Set Docker Repository Ports - nginx-reverse-proxy

Been working on setting up JFrog Container Repository and have been running into an issue with setting up the Docker Repository Ports.
I have gone through and set up Nginx as a reverse proxy and have generated a working sites-available conf file
## add ssl entries when https has been set in config
ssl_certificate /etc/nginx/ssl/secret.crt;
ssl_certificate_key /etc/nginx/ssl/secret.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
## server configuration
server {
listen 443 ssl;
listen 80 ;
server_name subdomain.domain.com;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
## Application specific logs
## access_log /var/log/nginx/artifactory.jfrog.com-access.log timing;
## error_log /var/log/nginx/artifactory.jfrog.com-error.log;
rewrite ^/$ /artifactory/webapp/ redirect;
rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect;
chunked_transfer_encoding on;
client_max_body_size 0;
location / {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
if ( $request_uri ~ ^/artifactory/(.*)$ ) {
proxy_pass http://localhost:8081/artifactory/$1;
}
proxy_pass http://localhost:8081/artifactory/;
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I am able to view the page, login, create repositories...etc...
But when I go to the Advanced tab of a docker repository to try and set the HTTP settings, I am still greeted by the "To use this feature first configure reverse proxy." even though I am viewing the page through the reverse proxy at the time.
I don't know if I am missing something super simple or if I am just running into a bug of sorts. I looked through the JFrog jira and couldn't seem to find anything that matched this description.
Any help would be greatly appriciated.
Thank you!
Edit:
Should probably leave some system info as well...
OS: Centos 7
Nginx: 1.16.1
JCR: 6.17.0-61700900

This is a bug. I have filed RTFACT-21197 for you. That said, it is simply a generator and you can simply edit your existing configuration. For ports, all you need to do is copy/paste and add a docker line with the repository name. For example, let's say you have a repository called docker-local and you want that to be accessible at port 5000, your final configuration would look like this:
## add ssl entries when https has been set in config
ssl_certificate /etc/nginx/ssl/secret.crt;
ssl_certificate_key /etc/nginx/ssl/secret.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
## server configuration
server {
listen 443 ssl;
listen 80 ;
server_name subdomain.domain.com;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
## Application specific logs
## access_log /var/log/nginx/artifactory.jfrog.com-access.log timing;
## error_log /var/log/nginx/artifactory.jfrog.com-error.log;
rewrite ^/$ /artifactory/webapp/ redirect;
rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect;
chunked_transfer_encoding on;
client_max_body_size 0;
location / {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
if ( $request_uri ~ ^/artifactory/(.*)$ ) {
proxy_pass http://localhost:8081/artifactory/$1;
}
proxy_pass http://localhost:8081/artifactory/;
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 5000 ssl;
server_name subdomain.domain.com;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
rewrite ^/$ /artifactory/webapp/ redirect;
rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect;
rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/docker-local/$1/$2;
chunked_transfer_encoding on;
client_max_body_size 0;
location / {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
if ( $request_uri ~ ^/artifactory/(.*)$ ) {
proxy_pass http://localhost:8081/artifactory/$1;
}
proxy_pass http://localhost:8081/artifactory/;
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Related

Nginx as Reverse Proxy for Apache

Ive been reading on using Nginx as a reverse proxy for Apache and how i can get benefits from using both. I dot have much experience with nginx, so im hoping someone here with more experience can take a look at my configuration and let me know if its a good starting point/where it can be improved.
server {
listen 80 default_server;
# Here, we have told that we are to listen to any request made to port 80 & then redirect it to https.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
# This is the document root
root /var/www/html/;
# This is the file which gets loaded by default. index.html gets loaded if there is no index.php
index index.html index.htm index.php;
# This has to be the domain you want to use
server_name mysite.xyz;
ssl_certificate /etc/letsencrypt/live/mysite.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.xyz/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
# Reverse Proxy
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
proxy_pass https://127.0.0.1:444;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# This configuration prevent the logger to log not found robots.txt
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# This tells the Nginx server to rewrite any requests which do not access a valid file to rewrite on to the index.php
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# This configuration prevent the logger to log not found favicon
location = /favicon.ico {
log_not_found off;
access_log off;
}
# This says that all files with the given endings should be cached by the client
location ~* .(jpg|jpeg|png|gif|ico|svg)$ {
expires 365d;
}
# .htaccess, .htpasswd, etc, will not be served.
location ~ /\.ht {
deny all;
}
# hotlink protect your images and other file types
location ~ .(gif|png|jpg|jpeg|svg|css|js|ico)$ {
valid_referers none blocked mysite.xyz www.mysite.xyz;
if ($invalid_referer) {
return 403;
}
}
}
Use the below nginx configuration to run nginx as reverse proxy for apache
server {
listen 443 ssl;
server_name www.example.com example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
location /.git {
deny all;
return 404;
}
}
restart nginx server after modification

How to handle multiple hostnames handles from nginx to apache in the same server?

I have the plan to manage multiple websites on the same server and I'm currently handling the http request from nginx then handling it to apache.
This is what the configuration I currently have for my first website:
# Force HTTP requests to HTTPS
server {
listen 80;
server_name myfirstwebsite.net;
return 301 https://myfirstwebsite.ne$request_uri;
}
server {
listen 443 ssl;
root /var/opt/httpd/ifdocs;
server_name myfirstwebsite.ne ;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always;
ssl on;
ssl_certificate /etc/pki/tls/certs/cert.pem;
ssl_certificate_key /etc/pki/tls/certs/cert.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/iflogs/http/access.log;
error_log /var/log/nginx/iflogs/http/error.log;
###include rewrites/default.conf;
index index.php index.html index.htm;
# Make nginx serve static files instead of Apache
# NOTE this will cause issues with bandwidth accounting as files wont be logged
location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
expires max;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:4433;
}
# proxy the PHP scripts to Apache listening on <serverIP>:8080
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:4433;
}
location ~ /\. {
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Now, My question is, for the second, third website and so on, I'm thinking in modifying the line:
proxy_pass https://127.0.0.1:4433;
for
proxy_pass https://secondwebsite.net:4433;
but what I don't want to do is that the goes out of the internet and looks up for that dns and then comes back to the same server, but serve in the same server (which is why I had localhost:4433 in the first website), so I don't get latency issues.
Is there any solution for this?
Also, I want to know if there will be issues if I serve multiple servers using the same port (in this case 4433) or do I have to use a different port for each website.
Thank you in advance.
Multiple server confs
One way to do this would be to have multiple server blocks, ideally over different conf files. Something like this would do for your second server in a new file (e.g. /etc/nginx/sites-available/mysecondwebsite):
# Force HTTP requests to HTTPS
server {
listen 80;
server_name mysecondwebsite.net;
access_log off; # No need for logging on this
error_log off;
return 301 https://mysecondwebsite.net$request_uri;
}
server {
listen 443 ssl;
root /var/opt/httpd/ifdocs;
server_name mysecondwebsite.net ;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always;
ssl on;
ssl_certificate /etc/pki/tls/certs/cert.pem;
ssl_certificate_key /etc/pki/tls/certs/cert.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/iflogs/http/access.log;
error_log /var/log/nginx/iflogs/http/error.log;
###include rewrites/default.conf;
index index.php index.html index.htm;
# Make nginx serve static files instead of Apache
# NOTE this will cause issues with bandwidth accounting as files wont be logged
location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
expires max;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:4434;
}
# proxy the PHP scripts to Apache listening on <serverIP>:8080
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:4434;
}
location ~ /\. {
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
You would then create a symlink using ln -s /etc/nginx/sites-available/mysecondwebsite /etc/nginx/sites-available/ and restart nginx. To answer your question about ports, you can only have one TCP application listening on any single port. This post provides a few more details about that.
You could also define an upstream in your server block like so:
upstream mysecondwebsite {
server 127.0.0.1:4434; # Or whatever port you use
}
And then reference this upstream using proxy pass like so:
proxy_pass http://mysecondwebsite;
This way if you change the port, you will only have to change it in one place in your server conf. Also, this is how you would scale your application with multiple Apache servers and implement load balancing.

Site redirected too many times after setting let's encrypt

I have set up www.myapp.io which connects to a MEAN-stack application hosted by nginx. It works, now, I want to add SSL to it. I have followed this link to secure with let's encrypt.
However, after the configuration, https://www.myapp.io isn’t working: www.myapp.io redirected you too many times. ERR_TOO_MANY_REDIRECTS.
The follows is /etc/nginx/sites-enabled/myapp.io, does anyone know where is wrong?
server {
listen 80;
server_name myapp.io www.myapp.io;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name myapp.io www.myapp.io;
ssl_certificate /etc/letsencrypt/live/myapp.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.io/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:EC$
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location ~ /.well-known {
allow all;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Accept-Encoding "";
proxy_set_header Proxy "";
proxy_pass https://127.0.0.1:3000;
}
}
(I did not put ssl_session_cache shared:SSL:50m;, because I already have ssl_session_cache shared:SSL:10m; in /etc/nginx/nginx.conf.)
The config file before adding ssl, which worked:
server {
listen 80;
server_name myopp.io *.myopp.io;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Accept-Encoding "";
proxy_set_header Proxy "";
proxy_pass http://127.0.0.1:3000;
}
}
PS: The site is managed via cloudflare, at the moment, the SSL setting on clouldflare is Flexible, I don't know if I need to change it.
As #dave_thompson_085 suggested in his comment, changing Flexible to Full in Cloudflare will make https://www.myapp.io reachable...

How to redirect on the same port from http to https with nginx reverse proxy

I use reverse proxy with Nginx and I want to force the request into HTTPS, so if a user wants to access the url with http, he will be automatically redirected to HTTPS.
I'm also using a non-standard port.
Here is my nginx reverse proxy config:
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
location / {
proxy_pass https://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto https;
}
}
I've tried many things and also read posts about it, including this serverfault question, but nothing has worked so far.
Found something that is working well :
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
error_page 497 301 =307 https://$host:$server_port$request_uri;
location /{
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
}
}
Are you sure your solution is working? It is listening for 8001 ssl. Will it accept http request?
I do it this way:
server {
listen 80;
server_name yourhostname.com;
location / {
rewrite ^(.*) https://yourhostname.com:8001$1 permanent;
}
}
Then goes your config:
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
location / {
proxy_pass https://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto https;
}
}
This worked for me:
server {
listen 80;
server_name localhost;
...
if ($http_x_forwarded_proto = "http") {
return 301 https://$server_name$request_uri;
}
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080;
}
...
}
You can
use $server_name to avoid hard coding your domain name again (DRY),
use return 301 for a bit easier reading (a web dev should know this http status code)
Note: I put 443 for https server. You may listen to 8001 if you really want that.
server {
listen 80;
server_name your_hostname.com;
return 301 https://$server_name$request_uri;
}
...
server {
listen 443 ssl;
server_name your_hostname.com
...
}
This is my approach, which I think is quite clean and allows you to add further locations if needed. I add a test on the $http_x_forwarded_proto property which if true forces all HTTP traffic to HTTPS on a NGINX Reverse Proxy setup
upstream flask_bootstrap {
server flask-bootstrap:8000;
}
server {
# SSL traffic terminates on the Load Balancer so we only need to listen on port 80
listen 80;
# Set reverse proxy
location / {
proxy_pass http://flask_bootstrap;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect http://localhost/;
# Permanently redirect any http calls to https
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
}
}

Apache and ultimate config for nginx to serve all virtual hosts in the right way

I've just set up nginx to serve static request on one site, but I have lots of sites on my server and I wonder, should I right new nginx server configuration for all of them?
What I'm doing now. I have file with all virtual hosts entries for Apache with some-thing like this:
NameVirtualHost *:8080
<VirtualHost *:8080>
ServerName sky2high.net
DocumentRoot /home/mainsiter/data/www/sky2high.net
</VirtualHost>
<VirtualHost *:8080>
ServerName surdo.asmon.ru
DocumentRoot /home/surdo/data/www/surdo.asmon.ru
</VirtualHost>
<VirtualHost *:8080>
ServerName surdoserver.ru
DocumentRoot /home/surdo/data/www/surdoserver.ru
</VirtualHost>
I have this in apache's ports.conf:
Listen 8080
And so I've set up nginx to work with one site (sky2high.net), created next configure file (/etc/nginx/sites-enabled/sky2high.net):
server {
listen 80;
server_name sky2high.net www.sky2high.net;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
access_log /var/log/nginx.access_log;
location ~* \.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|tar|wav|bmp|rtf|swf|ico|flv|txt|xml|docx|xlsx)$ {
root /home/mainsiter/data/www/sky2high.net/;
index index.php;
access_log off;
expires 30d;
}
location ~ /\.ht {
deny all;
}
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_set_header Host $host;
proxy_connect_timeout 60;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_redirect off;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
}
}
And it works fine for this domain, but of course another virtual hosts are broken.
So, the question is: is there ultimate config option for nginx, witch can help to handle all request, from all virtual hosts (domains) and serve them in the right way? I mean, option that allows not to write separete configure files for each virtual hosts (with all this doubled stuff like root and index options), but only one for all virtual hosts?
PS: should I move question to serverfault?
UPDATE:
Emm.. I wonder how is it works, but it is. I've made next config files:
/etc/nginx/nginx.conf
user www-data;
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
and
/etc/nginx/sites-enabled/default
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
}
}
I do not understand how is it works, but it is...
UPDATE 2: or it doesn't work! I've looked to "top" in console and metioned that apache serves not only php request, but for static content either =(
What you do now is sending all the network traffic to 127.0.0.1:8080 without allowing Nginx to serve the static files.
What you should try is the following:
server {
listen 80;
server_name sky2high.net www.sky2high.net;
location / {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/conf.d/proxy.conf;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|tgz|gz|pdf|rar|bz2|exe|ppt|txt|tar|mid|midi|wav|bmp|rtf) {
root /folder/to/static/files;
expires 90d;
}
location ~* ^.+\.(css|js)$ {
root /folder/to/static/files;
expires 30d;
}
And in proxy.conf you put the following:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 8m;
client_body_buffer_size 256k;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffer_size 4k;
proxy_buffers 32 256k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 256k;
This should work for you
Just my two cents, in most cases it's not necessary to specify the listen 80.
Source: Nginx common Pitfalls