This is part one of a two-part series for using NGINX as a reverse proxy for microservices on the same server or hosted on other servers/ports
In this article, we will:
- Install NGINX
- Install LetsEncrypt CertBot
- Obtain free SSL certificate
- Configure NGINX for SSL
In part two, we will go over how to turn the basic HTTPS encrypted NGINX site into a reverse proxy for your other services.
Installing NGINX and CertBot Auto
We are using Ubuntu 14.04.5
Download certbot-auto
to the /usr/local/sbin
directory
cd /usr/local/sbin sudo wget https://dl.eff.org/certbot-auto
Make sure it is executable:
sudo chmod a+x /usr/local/sbin/certbot-auto
Install NGINX
sudo apt-get update sudo apt-get install nginx
Modify default config
Certbot looks for a file .well-known to validate your domain before issuing a certificate. This is how we will obtain our SSL certificate, so this means you must already have your HTTP/HTTPS ports open on your firewall and your DNS pointed to your server’s IP for when we run the script.
We need to add a snippet to our default site config for this validation.
Open the config in nano
sudo nano /etc/nginx/sites-available/default
server {
” opening tag and the ” }
” corresponding closing tag, add the following snippet: location ~ /.well-known {
allow all;
}
It might look something like this:
server { listen 80; server_name example.com www.example.com; location ~ /.well-known { allow all; } }
Save and quit the editor.
Check the configuration file for syntax errors:
sudo nginx -t
As long as there are no errors, restart NGINX
sudo service nginx restart
Let’s Encrypt!
Here is where we request a free SSL cert, also specifying our domain names with the -d
option. If you want a single cert to work with multiple domain names (e.g. example.com
and www.example.com
), be sure to include all of them, starting with the most high level domain (e.g. example.com
).
Replace example.com entries with your own domain.
certbot-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d example.com -d www.example.com
If this is a success, you should be told so by the script and be presented the directory locations for your certificates.
Next, it’s recommended to generate a strong Diffie-Hellman group.
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Finishing up
We’re almost done. We just need to enable new SSL security and define the SSL cert location in your site config.
Edit the Nginx configuration that contains your server block. Again, it’s at /etc/nginx/sites-available/default
by default:
sudo nano /etc/nginx/sites-available/default
Basically, you can clear or comment out most of this file. You want yours to look like this: (make sure to replace example.com with your domain name)
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name example.com www.example.com; # LetsEncrypt certificates. Replace example.com with your domain ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; root /usr/share/nginx/html; index index.php index.html index.htm; # SSL settings ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; # Strong DH key we generated ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000; # Make site accessible from http://localhost/ server_name localhost; location / { try_files $uri $uri/ =404; } # LetsEncrypt renewal, leaving this here location ~ /.well-known { allow all; } }
With the configuration above, you are automatically redirected to HTTPS any time you try to use HTTP. It utilizes the DH group we generated earlier and also defines the location of our SSL certs.
Save your configuration.
Check it for errors:
sudo nginx -t
If there are no errors in your config, go ahead and restart the NGINX service to make the changes go live.
sudo service nginx restart
Testing
If your NGINX config test didn’t fail and you were able to restart the nginx service without an error, go ahead and browse to your domain. The SSL cert will be valid if everything went well.
You should see the default nginx page when browsing to your domain, as right now, you’re only hosting out of your document root:
/usr/share/nginx/html
You can analyze your SSL certificate and perform tests on it with:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
This concludes part 1 of how to install and configure NGINX to act as a reverse proxy.
In summary, right now, our Ubuntu 14.04.5 server is runing NGINX on port 80 and 443, and when browsing to the domain name, we are automatically redirected to the HTTPS site. The site is encrypted with a valid SSL certificate for free from Lets Encrypt, but we still need to configure the site blocks for our reverse-proxy.
Please feel free to comment with your experiences or if you have any problems/comments.
Look out for part two coming soon.
3 Comments
scottocsscott · September 26, 2017 at 8:25 pm
I doubt this has to do with me installing it on Ubuntu 16.04, but in the final /etc/nginx/sites-available/default file on line 21, I had to add the ending ‘; to the line.
Tyler Woods · September 26, 2017 at 8:28 pm
You’re right, that did get a little funky. I’ll try to update that soon.
Meanwhile I have a newer article that you can couple with an article for security hardening NGINX if this didn’t end up working out.
http://149.28.126.230/2017/09/14/the-perfect-reverse-proxy-nginx-ssl-webui-management/
http://149.28.126.230/2017/05/01/nginx-security-hardening/
Thank you for your comment!
How to install NGINX, get a free SSL certificate, and configure a reverse proxy (part two) – Tyler N. Woods · April 28, 2017 at 10:54 am
[…] that you have successfully installed NGINX and obtained a free SSL cert, you can proceed turning your server into a reverse […]