Embrace Nginx for Application Delivery

First we install Nginx on our Ubuntu server:

$ apt-get install nginx

This will fire up Nginx right away as you can verify with

$ systemctl status nginx
...
   Active: active (running) since Wed 2016-11-16 11:34:29 GMT; 17min ago
...

What's next? Check the registration of Nginx with the Uncomplicated Firewall ufw:

$ ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
...

The automatic registration looks good. Let's allow Nginx access...

$ ufw allow 'Nginx Full'

and check the rules right away:

$ ufw status
Status: active

To                         Action      From
--                         ------      ----
...
Nginx Full                 ALLOW       Anywhere
...
Nginx Full (v6)            ALLOW       Anywhere (v6)

Accessing the HTTP version on our sever shows Nginx is up and running:

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

...but HTTPS needs some more actions.

As you might know from Apache HTTP Server Project sites are configured in /etc/nginx/sites-available and enabled via a soft link from /etc/nginx/sites-enabled.

The most interesting part is where Let’s Encrypt comes into play.

First we allow access to .well-known location in /etc/nginx/sites-available/default:

server {
    ...
    # SSL configuration
    #
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    location ~ /.well-known {
        allow all;
    }
    ...
}

To test the Nginx the configuration run: nginx -t. This should result in something like:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

And restart the service after successful verification with systemctl restart nginx.

Now we run letsencrypt to generate certificates for us:

$ letsencrypt certonly -a webroot --webroot-path=/var/www/html -d planets.datenkollektiv.de

and follow the instructions.

Once the process finished successfully you should be able to spot something like this in the Nginx access log: /var/log/nginx/access.log.

... "GET /.well-known/acme-challenge/<hash> HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

With the brand new certificate in /etc/letsencrypt/live/planets.datenkollektiv.de/ we continue the Nginx configuration.

The configuration snippet redirecting HTTP traffic to our HTTPS enabled site could looks something like this:

server {
  listen       *:80;
  listen       [::]:80;
  server_name planets.datenkollektiv.de;
  return 301 https://$server_name$request_uri;
}

and the planets.datenkollektiv.de_ssl configuration within sites-available:

server {
    listen       *:443 ssl;
    listen       [::]:443 ssl;
    server_name  planets.datenkollektiv.de;
    include /etc/nginx/sites-available/common_ssl.config;

    ssl_certificate      /etc/letsencrypt/live/planets.datenkollektiv.de/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/planets.datenkollektiv.de/privkey.pem;
}

As you can see the common ssl configuration may be shared among different server configuration files.

The shared configuration contains some ssl fine tuning:

ssl_protocols TLSv1.2 TLSv1.1 TLSv1;

ssl_ciphers EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:!MD5:!RC4:!LOW:!MEDIUM:!CAMELLIA:!ECDSA:!DES:!DSS:!3DES:!NULL;
ssl_prefer_server_ciphers on;

To redirect the content to your application you have to provide a location:

location / {
  proxy_cookie_domain ~ planets.datenkollektiv.de;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass_header ETag;
  proxy_pass https://localhost:18080;
}

Don't forget to enable the available (aka link) the new configuration with ln -s ../sites-available/planets.datenkollektiv.de_ssl .

Afterwards (re-)check the configuration and in case of no error restart Nginx with systemctl restart nginx.

For more detailed information refer to this very detailed How To Install Nginx on Ubuntu 16.04.

PS: The access logs of Nginx are available via tail -500f /var/log/nginx/access.log. The error logs are written into /var/log/nginx/error.log by default.