Nginx: Using Nginx for SSL termination on Ubuntu

Nginx is a popular reverse proxy and load balancer that focuses on level 7 (application) traffic.  A common pattern is allowing Nginx to be the fronting SSL-termination point, and then Nginx determines which pooled backend server is best available to serve the request.

Installation from Ubuntu Repository

The easiest way to install Nginx is from the main Ubuntu repository, but the version will be older (1.4.6) and will not have the latest advanced features.

$ sudo apt-get install nginx -y
$ nginx -v

Installation from Nginx Repository

If you want the latest version of Nginx, the Nginx repository needs to be added and then you can install using apt-get like below.

$ sudo apt-cache policy nginx
$ echo "deb $(lsb_release -s -c) nginx" | sudo tee -a /etc/apt/sources.list.d/nginx.list
$ sudo apt-key adv --keyserver\
 --recv-keys ABF5BD827BD9BF62 
$ sudo apt-get update
$ sudo apt-cache policy nginx
$ sudo apt-get install nginx -y
$ nginx -v

nginx version: nginx/1.12.0

Secure Certificate

If you are going to use Nginx as an SSL termination point, then it needs a private/public key pair.  The easiest way to satisfy this requirement is to create a self-signed certificate as described in the article I wrote here.

Open Firewall Ports

We need to make sure port 80 and 443 are open.

$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp

SSL Termination for pool

The file ‘/etc/nginx/nginx.conf’ defines which folders are searched for configuration files.  You will want to create ‘/etc/nginx/conf.d/ssl.conf’ with the contents below.

# single or multiple servers in pool
upstream mypool {
server {
        listen 443;
        server_name FQDN;
        location / {
                proxy_pass http://mypool;
                proxy_set_header Host      $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_ssl_session_reuse on;
                proxy_send_timeout 300s;
        ssl on;
        ssl_certificate /etc/pki/tls/certs/FQDN.crt;
        ssl_certificate_key /etc/pki/tls/certs/FQDN.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

You need to replace ‘FQDN’ with the actual fully qualified domain name of your Nginx host.  And of course, point the upstream servers to your actual pool of host:port.

Redirect HTTP to HTTPS

To ensure that all non-secure requests go through HTTPS, you can add the following line to ‘/etc/nginx/conf.d/default’, right underneath the server_name definition.  For older Nginx versions, the file is located at ‘/etc/nginx/sites-enabled/default’.

return 301 https://$host$request_uri;

Start Service

To start Nginx, use the command below.  Logs can be found at ‘/var/log/nginx/’.

$ sudo service nginx start

Be sure that when you pull up the Nginx server in the browser, you use the fully qualified host name (and not the IP).  If you have to make changes to your local hosts file, then do so, because the browser address needs to match the CN in the certificate.

Start your research here and here on how to harden Nginx security.


# echo if older nginx installed, may require purge to install newer
# apt-get remove nginx --purge 
# apt-get autoremove -f 
# apt-get install nginx -y