Setting up a reverse proxy using nginx is easy:
for this how-to i will use debian
1) install nginx:
sudo apt-get install nginx
2) remove the default config (or move somewhere else for reference):
sudo rm /etc/nginx/sites-enabled/default
sudo rm /etc/nginx/sites-available/default
3) copy your certificates to the machine or generate some if using self-signed certificates, for a great lets encrypt certificate how-to click here
4) create a default conf, which probably leads to your webserver:
sudo nano /etc/nginx/sites-available/default-webserver
server { listen 443 ssl default_server; server_name _; ssl on; ssl_certificate /etc/nginx/ssl/certs/your-certificate.crt; ssl_certificate_key /etc/nginx/ssl/private/your-key.key; error_log /var/log/nginx/default-webserver/error.log; access_log /var/log/nginx/default-webserver/access.log; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass https://<IP-OF-YOUR-WEBSERVER>; } }
were the cert paths have to be adjusted to match yours and the ip/hostname of the webserver has to be inserted
explanation:
listen 443 ssl default_server; |
creates a virtual host on port 443 which listens for ssl connections and is the default server, so it takes all requests not handled by any other config |
server_name _; |
can also be omitted, only symbolizes the unused server_name directive |
location / {} |
defines an action for the root ( / ) of the current config |
proxy_set_header Host $host; |
sets the host header if your next hop (the webserver) wants to do sni again or is configured to only accept requests for a specific domain |
proxy_set_header X-Real-IP $remote_addr; |
sets the X-Real-IP header to the remote_addr, which is the connecting ip to the reverse proxy |
proxy_pass https://<IP-OF-YOUR-WEBSERVER>; |
instructs nginx to connect to https://<IP-OF-YOUR-WEBSERVER> if a request arrives for this config |
note that the backend (your weserver, webapp, whatever) and frontend (the reverse proxy) do not need to be https
5) i prefer to use seperate directorys for each config, in such a case you have to create the directory for the logs:
sudo mkdir -p /var/log/nginx/default-webserver
6) link the config to the sites-enabled directory for nginx to actually use it:
sudo ln -s /etc/nginx/site-available/default-webserver /etc/nginx/sites-enabled/default-webserver
7) test if nginx accepts the config by issuing:
sudo nginx -t
8) if everything is ok, reload nginx:
sudo service nginx reload
you can test the proxy by connection to the ip/hostname of the reverse proxy machine
to use different hosts for different domain names just repeat the steps 3 to 8, but this time set a servername like so:
server { listen 443 ssl; server_name mysubdomain.domain.tld; ssl on; ssl_certificate /etc/nginx/ssl/certs/your-certificate.crt; ssl_certificate_key /etc/nginx/ssl/private/your-key.key; error_log /var/log/nginx/mysubdomain.domain.tld/error.log; access_log /var/log/nginx/mysubdomain.domain.tld/access.log; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass https://<IP-OF-YOUR-OTHER-WEBSERVER>; } }
if you want to use cloudflare as another reverse proxy on top of yours, check out this post to get the real visitor ip for the nginx logs