Configuring NGINX with HTTPS redirect and reverse proxying to multiple services
So I had an issue where I wanted to host multiple websites behind a single web address/IP address. I knew this was possible to do, but I didn’t know how. I also wanted it to be secured by HTTPS, which would require a redirect of all HTTP traffic. I stitched together the following.
server {
listen 80 default_server; # Listens to HTTP
server_name example.com; # Replace example.com with your web address
return 301 https://$host$request_uri; # Redirect all HTTP traffic to HTTPS
}
server {
listen 443 ssl; # Listen to HTTPS port and use SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # Path to your SSL Certificate, mine was created by let's encrypt
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # Path to your SSL key file, again mine is managed by let's encrypt
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by let's encrypt Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by let's encrypt Certbot
location /app1 { # Application 1 can be found by going to example.com/app1
proxy_pass https://10.0.0.60/; # Location of redirect this can be HTTP or HTTPS, if HTTP data will only be encrypted until it hits the reverse NGINX proxy, then it will be clear text
proxy_redirect off; # This hides the interal address of the web app rather than redirecting you to https://10.0.0.60/
proxy_set_header Host $host; # This sets the header to the host name listed above which is example.com
}
location /app2 { # Application 2 can be found by going to example.com/app2
proxy_pass https://10.0.0.61/;
proxy_redirect off;
proxy_set_header Host $host;
}
location / { # This catches all other web requests that aren't /app1 or /app2
proxy_pass http://127.0.0.1:30000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header Connection "upgrade"; # Needed for web sockets
proxy_set_header Upgrade $http_upgrade; # Needed for web sockets
proxy_set_header X-Real-IP $remote_addr; # Allows the server to see the IP of the client rather than that of the reverse proxy's address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Needed for web sockets
proxy_set_header X-Client-Verify SUCCESS; # Needed for web sockets
proxy_set_header X-Client-DN $ssl_client_s_dn; # returns the “subject DN” string of the client certificate for an established SSL connection according to RFC 2253 (1.11.6);
proxy_set_header X-SSL-Subject $ssl_client_s_dn;
proxy_set_header X-SSL-Issuer $ssl_client_i_dn; # returns the “issuer DN” string of the client certificate for an established SSL connection according to RFC 2253 (1.11.6)
proxy_read_timeout 60s; # How long to read the response from the proxied server
proxy_connect_timeout 60s; # Defines how long to wait for the proxied server before sending a timeout to the client.
}
}
I commented as much as I could in-line with each setting but in a nutshell what this config does is redirect all traffic from port 80 to port 443, then if the user is going to example.com/app1 it redirects to one server, if they go to example.com/app2 it goes to a different servers and all other requests are handled by a local server running on port 30000 with no security on it, this is why I was using NGINX to reverse proxy in the first place is I wanted this app to be secure.