nginx reverse proxy multiple domains docker - nginx-reverse-proxy

I have a container with nginx (reverse proxy) and currently I have this configuration for when the user enters the following url (http://panels-cliente1.company.com) the page loads:
upstream panels-cliente1.company.com {
server 172.20.1.100:3000;
}
server {
server_name panels-cliente1.company.com;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
#Limite de subida de ficheros en Nginx
client_max_body_size 50M;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/cert.key;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://panels-cliente1.company.com;
}
}
but I would like to see how to add another url to enter the same container, I mean having:
http://panels-cliente1.company.com
http://panels-cliente1.company.com
and with both links enter the server and when client1 is browsing it always sees "client1" and the same for client2, always in the url "client2" appears
I try adding in the server_name and in the upstream the 2 urls , but I'm not sure what to add in the location
Can I do something like what i describe?

Related

Nginx reverse proxy for requesting HTTP backend on HTTPS frontend

I've been seeing a ton of info about reverse proxies and nginx but I'm a little lost on how to implement. I am running two separate EC2 instances (front and back end, with back end running pm2). I have SSL established on the front using LetsEncrypt, and it won't allow me to hit my backend because of Mixed Content. What should I do?
nginx.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name domain;
location / {}
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
root /insert/root/here;
ssl_certificate "/path/to/cert";
ssl_certificate_key "/path/to/key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
ssl_prefer_server_ciphers on;
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
It looks like browser complains at your html content because it has hard-coded "http://" references to external resources, like javascript, fonts etc.
It does not mean that it can't reach backend due to this "mixed-content" issue.
I see no proxy_pass (or fastcgi_pass) directives in your config (which should pass requests to your upstream backend server) so probably that is an real reason why you can't reach your backend.
Your configuration should look like this:
server {
listen 443 ssl;
root /here/are/your/static/files/; # here you can place static html, css, js etc files from your backend to offload backend from serving static files - nginx will take care of them.
...
location / {
#this means that nginx will forward requests to backend server in case request does not match local static file.
try_files $uri $uri/ #backend;
}
location #backend {
#....
proxy_pass http://backend-server-ip-address:backend-port
}
}

nginx is giving 404 error on page reload of my production vue-cli app

I know this is a known problem even explained in vue-cli docs when you use history mode in Vue Router.
If you are using Vue Router in history mode, a simple static file server will fail. For example, if you used Vue Router with a route for /todos/42, the dev server has been configured to respond to localhost:3000/todos/42 properly, but a simple static server serving a production build will respond with a 404 instead.
To fix that, you will need to configure your production server to
fallback to index.html for any requests that do not match a static
file.
But I'm already doing this in my config file and the problem persists when I reload the page manually.
server {
listen 80;
server_name my.domain.name.com;
rewrite ^ https://$server_name$request_uri permanent;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name my.domain.name.com;
root /var/www/my-frontend-dist-root;
location / {
try_files $uri $uri/ /index.html;
}
location ~*.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|ta$
expires 365d;
log_not_found off;
access_log off;
}
access_log /var/log/nginx/my.access.log;
error_log /var/log/nginx/my.error.log debug;
ssl on;
ssl_certificate /etc/letsencrypt/live/my.domain.name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.domain.name/privkey.pem;
keepalive_timeout 60;
ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aN$
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhp-2048.pem;
proxy_buffers 16 64k;
proxy_buffer_size 128k;
}
What am I missing?

no "ssl_certificate" is defined for the "listen ... ssl" directive

I am trying to configure nginx server for my website. I am using the following code to configure my server. It works if I add default_server for my www.fastenglishacademy.fr (443) server block.
But in that case, All my subdomains also brings the content of www.fastenglishacademy.fr
And if I remove the default_server, I get the following error:
nginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /etc/nginx/sites-enabled/fastenglishacademy.fr.conf:14
nginx: configuration file /etc/nginx/nginx.conf test failed
My nginx configuration codes:
server {
listen 80;
listen [::]:80;
server_name fastenglishacademy.fr;
return 301 https://www.fastenglishacademy.fr$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name www.fastenglishacademy.fr;
return 301 https://www.fastenglishacademy.fr$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name fastenglishacademy.fr;
return 301 https://www.fastenglishacademy.fr$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /media/fea/www/fastenglishacademy.com;
index index.html index.htm index.nginx-debian.html;
server_name www.fastenglishacademy.fr;
location / {
etag on;
try_files $uri$args $uri$args/ /index.html;
}
location ~* \.(jpg|jpeg|png|gif|ico|ttf|woff2|woff|svg)$ {
expires 365d;
}
location ~* \.(css|js)$ {
expires 30d;
}
location ~* \.(pdf)$ {
expires 15d;
}
#WARNING: Please read before adding the lines below!
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# SSL Certificates
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_trusted_certificate /path/to/chain.pem;
}
My links:
https://www.fastenglishacademy.fr/
https://api.fastenglishacademy.fr/
Your server section is missing ssl_certificate and ssl_certificate_key declarations.
You need to have a .crt and a .key file to run with ssl.
It should looks like
server {
listen 80;
listen 443 default_server ssl;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
... other declarations
}
Had the same problem.
Adding directive
ssl on;
solved my problem.

Apply SSL and www in main domain and not in subdomain in nginx

I am working on to apply SSL (https) and www to domain ("https:// www.xyz.com") in the browser whenever I type anything for the domain ("xyz.com").
I have subdomains as well and I don't want to apply "www" in subdomains (this is working fine).
Everything is working great except if I type "https:// xyz.com" in the browser, ngingx doesn't apply www (it should be "https:// www.xyz.com") but it gives "https:// xyz.com" only.
Following is the config file of sites-available:
server {
listen 443;
server_name xyz.com *.xyz.com;
ssl on;
ssl_certificate /etc/nginx/ssl/xyz.crt;
ssl_certificate_key /etc/nginx/ssl/*.xyz.com.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8069;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffer_size 128k;
proxy_buffers 16 64k;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
location ~* /web/static/ {
proxy_buffering off;
proxy_pass http://127.0.0.1:8069;
}
}
}
server {
listen 80;
server_name xyz.com;
add_header Strict-Transport-Security max-age=2592000;
rewrite ^/.*$ https://www.$host$request_uri? permanent;
}
server {
listen 80;
server_name *.xyz.com;
add_header Strict-Transport-Security max-age=2592000;
rewrite ^/.*$ https://$host$request_uri? permanent;
}
Kindly guide me where I am doing wrong.
Thanks in advance.
move add_header Strict-Transport-Security max-age=2592000; option to ssl server block with 443 port.
server {
listen 443;
add_header Strict-Transport-Security max-age=2592000;
# rest configs
}
Change http 80 block to
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://www.example.com$request_uri; # permenent redirect
}
NOTE: any changes made to nginx config needs a reload signal to nginx process to apply the changes in ubuntu it requires sudo service nginx reload

HTTP Upgrade to TLS in Nginx Per RFC 2817

I have been looking into how I can upgrade an HTTP connection to TLS and achieve and end to end tunnel across proxy hops. I would like to use the client certificate in this tunnel to act upon it on the receiving end after a few hops.
I read RFC 2817 (HTTP Upgrade to TLS) and it seems this is possible. I just cannot figure out how to do that using Nginx being new to Nginx.
I was wondering if I am making a complete noob mistake or if this is at all possible in Nginx.
I have Nginx instance 1 with the following config for the http block:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass https://10.0.3.4/;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
The second Nginx instance has the following config has pretty much the same config except for one difference proxy_pass https://10.0.3.5/index.html
The last Nginx instance has the following config:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location / {
root html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
When I hit the URL using HTTPS, I do get the response but nothing about the client cert is printed in the logs. When I use only HTTP, I get the 301 response. These are the two calls I am making:
$ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" https://10.0.3.3/
and
$ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" http://10.0.3.3/
RFC 2817 defines two methods for TLS upgrade: CONNECT request and Connection: Upgrade.
CONNECT is a HTTP request done by the browser when using an explicitly configured HTTP proxy. It gets not used with transparent proxies or reverse proxies. Contrary to for instance squid nginx is a web server and not a HTTP proxy (from the perspective of the browser) and thus does not implement the CONNECT request.
As for the Connection Upgrade to TLS specified in RFC 2817: this was just an idea and no browser supports this. This kind of Upgrade mechanisms is actually used in browsers today but not for upgrading to TLS but only for WebSockets.