Nginx mit SSL und Let's Encrypt absichern

Hinweis: Wenn man den Client und Pakete die für ihn benötigt werden nicht zusätzlich auf seinem Server installieren will kann man auch mit der Hilfe einer Webseite die einzelnen Schritte zur Ausstellung des Zertifikats manuell durchführen.

Seit dem 3. Dezember 2015 befindet sich Let’s Encrypt in der Public Beta. Das bedeutet man kann sich ohne vorherige Registrierung und Wartezeit ein kostenloses SSL Zertifikat für seine Domain erstellen. Für mein “Heimcloud” nutze ich einen Cubietruck (ähnlich zum weitaus bekannteren Raspberry Pi) mit Nginx. Dieser Artikel zeigt wie ich Nginx mit einem SSL-Zertifikat von Let’s Encrypt eingerichtet habe.

Als erstes musss der Let’s Encrypt Client installiert werden. Dabei werden alle benötigten Debian-Pakete installiert:

hostname:~# git clone https://github.com/letsencrypt/letsencrypt
hostname:~# cd letsencrypt
hostname:~/letsencrypt# ./letsencrypt-auto

Für Nginx gibt es noch kein Plugin das die Installation des Zertifikats automatisch vornimmt. Deshalb wird als Plugin standalone verwendet und die Nginx Konfiguration danach manuell angepasst. Zur Validierung der Domain (nicht das man sich ein Zertifikat für eine Domain ausstellt die man gar nicht administriert) werden Port 80 oder 443 genutzt. Da Nginx auf diesen Ports lauscht muss er während der Ausstellung des Zertifikats gestoppt werden. In meinem Fall habe ich kein Problem damit wenn der Webserver kurz nicht verfügbar. Alternativ kann die Domain auch über ein Verzeichnis im Webroot validiert werden:

hostname:~# sudo /etc/init.d/nginx stop
hostname:~# ./letsencrypt-auto certonly -d example.krausmueller.de
hostname:~# sudo /etc/init.d/nginx start

Wenn alles geklappt hat liegen die Dateien des Zertifiktas unter /etc/letsencrypt/live/example.krausmueller.de/:

hostname:~# sudo ls /etc/letsencrypt/live/example.krausmueller.de/
cert.pem  chain.pem  fullchain.pem  privkey.pem

Neben dem Zertifikat sollte man noch seien eigenen Diffie-Hellman-Parameter erstellen:

hostname:~# sudo openssl dhparam -out /etc/nginx/dhparams.pem 2048

Eine möglichst sichere Konfiguration für Nginx lässt sich mit dem Mozilla SSL Configuration Generator erstellen. Wichtig ist es dabei die richtige Version des Servers und von OpenSSL einzutragen. Die für meine Zertifikate angepasste Konfiguration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
    listen 443 ssl;
    server_name example.krausmueller.de;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/letsencrypt/live/example.krausmueller.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.krausmueller.de/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/dhparams.pem;

    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

}

Nach einem Neustart des Nginx sollte ein Test bei SSL Labs jetzt ein “A Rating” ergeben.

SSL Labs Rating

Zertifikate von Let’s Encrypt sind lediglich 90 Tage gültig und müssen deshalb regelmäßig erneuert werden. Am einfachsten lässt sich das über einen Cronjob erledigen. Bei diesem Beispiel wird das Zertifikat jeden 2. Monat am 28. (wichtig durch möglichen Schalttag im Februar) erneuert:

hostname:~# crontab -l
# m   h    dom mon           dow   command
  0   1    28  2,4,6,8,10,12 *     sudo /etc/init.d/nginx stop; /home/user/letsencrypt/letsencrypt-auto certonly --renew -d example.krausmueller.de; sudo /etc/init.d/nginx start