Tim's blah blah blah

Setting up an A+-grade nginx SSL server

(Updated: )

Because I don’t want to expose smarthome dashboards (like domoticz or grafana) directly to the internet, I’ve set up a separate server to publish data beyond my local network. For this I’ve chosen nginx (nginx.org) using let’s encrypt certificates (letsencrypt.org) renewed by certbot (eff.org), enabling hsts (nginx.com) and fixing the logjam vulnerability (weakdh.org).


Integrating a web server in a smarthome dashboard violates the Unix philosophy (wikipedia.org) of doing one thing only and doing it well. It’s unclear which web server domoticz/grafana uses, and why it’s integrated in their codebase. If it’s a custom web server, the chances that security is properly implemented is small. Additionally, setting up a separate web server allows me to choose what content I do and don’t want to serve.

The reason I’ve chosen for nginx is that it’s widely used (netcraft.com) (and thus hopefully well-tested) and faster (wikipedia.org) than apache.

Setting up nginx


Install the server as usual

sudo apt install nginx

Enable HTTPS in sites-enabled/default and nginx.conf - no need to make certificates yet.

Get SSL certificate

Get certbot-auto (eff.org) to automatically deploy certificates:

sudo /path/to/certbot-auto —nginx    

First dry-run a renew

sudo /path/to/certbot-auto renew --dry-run    

then add to crontab, using random delay to load balance for let’s encrypt (eff.org)

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /path/to/certbot/certbot-auto renew

Harden security

Now enable HSTS (wikipedia.org) to prevent MITM sslstrip attacks (stackexchange.com). Add the following to your sites-enabled/default config (source (nginx.com)):

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;    

By default, nginx https is pretty secure, fixing many known vulnerabilities. The logjam attack (weakdh.org) however, is not mitigated. To fix, follow these instructions (weakdh.org):

sudo su
cd /etc/ssl/private
openssl dhparam -out dhparams.pem 2048

in sites-enabled/default, add:

ssl_dhparam "/etc/ssl/private/dhparams.pem"    

Redirect HTTP to HTTPS

To limit HTTP exposure to the web, one can redirect all HTTP traffic to HTTPS. However, since certbot only works over HTTP, an exception has to be made to have certificate renewal working.

I’ve followed these instructions here (letsencrypt.org) and here (letsencrypt.org) to implement this.

There are three ways certbot can renew certificates, unfortunately none allowing a HTTPS-only server (letsencrypt.org).

  1. HTTP-01: Store a token on your webserver that is retrieved over HTTP
  2. DNS-01: Store a token in your DNS records
  3. TLS-SNI-01: Change the SSL certificate on the server - this method is deprecated

Verify setup

Finally, test your configuration (ssllabs.com) which should give you an A+ grade:

#Linux #RaspberryPi #Security