Bild: Pixabay

HowTo: Nginx mit Let’s Encrypt Zertifikat

Als Basis dient ein Debian Jessie Server mit bereits installierten Nginx Webserver. Für das Let’s Encrypt Zertifikat wird Dehydrated-Skript von Lukas Schauer, alias lukas2511, verwendet.

Ich gehe im Beispiel von einer Domain www.example.com aus.

Vorbereitung

Anlegen des Austauschverzeichnisses für die “Challenge”

mkdir -p /var/www/dehydrated
chown -R root:www-data /var/www/dehydrated

Webserver Pfad für “Challange” anlegen

nano /etc/nginx/sites-available/www.example.com.conf
Innerhalb der Server {…} folgendes hinzufügen:
location /.well-known/acme-challenge {
      alias /var/www/dehydrated;
}
Die geänderte Konfiguration laden
service nginx reload

Dehydrated installieren

Leider wird das Skript derzeit in Debian nicht mitgeliefert, deshalb müssen wir es ersteinmal herunterladen und Konfigurieren. Ich Verwende das Verzeichnis /opt, richtiger wäre eigentlich /usr/local/bin/…

cd /opt
git clone https://github.com/lukas2511/dehydrated
mkdir /etc/dehydrated
chown -R root:www-data /etc/dehydrated
cp /opt/dehydrated/docs/examples/config /etc/dehydrated/
cp /opt/dehydrated/docs/examples/domains.txt /etc/dehydrated/
Nun muss man /etc/dehydrated/domains.txt editieren und die eigenen Domains eintragen.

/etc/dehydrated/config kann eigentlich unverändert bleiben, mann kann aber für CONTACT_EMAIL die Mailadresse des Hostmasters eintragen z.B. hostmaster@example.com

Um das ganze einmal zu Testen und das Anfragelimit nicht zu überschreiten kann man vorübergehend in /etc/dehydrated/config am Ende noch folgendes Eintragen:

CA="https://acme-staging.api.letsencrypt.org/directory"
Nun kann man Testweise das Zertifikat anfordern lassen
/opt/dehydrated/dehydrated -c

Gegebenenfalls den Hinweisen folgen und fehlende Pakete nachinstallieren, bei mir war es curl

apt install curl
/opt/dehydrated/dehydrated --register --accept-terms
Erst wenn dies Fehlerfrei durchläuft sollte man den vorhin hinzugefügten CA-Eintrag in /etc/dehydrated/config wieder löschen.

Zertifikat anfordern

Wenn man den Staging-CA Eintrag in /etc/dehydrated/config entfernt hat, sollte man nun auch noch die Test-Zertifikate löschen und dann die entgültigen Zertifikate anfordern:

rm -r /etc/dehydrated/certs /etc/dehydrated/accounts
/opt/dehydrated/dehydrated -c

Webserver Konfigurieren

Alle http Anfragen nach https Umleiten

# nano /etc/nginx/sites-available/www.example.com.conf
server {
  listen 80;
  server_name www.example.com;
  return 301 https://www.example.com;
}

SSL-Konfiguration für ein A+ bei SSLLabs

Den bisherigen Server-Eintrag entsprechend abändern:

server {

  # Server name 
  server_name www.example.com;

  # Server Port
  listen 443 ssl spdy; # http2; ... die aktuelle debian-Version kann derzeit noch kein http2

  ssl_certificate     /etc/dehydrated/certs/www.example.com/fullchain.pem;
  ssl_certificate_key /etc/dehydrated/certs/www.example.com/privkey.pem;
  ssl_trusted_certificate     /etc/dehydrated/certs/www.example.com/fullchain.pem;
  
   ssl_protocols   TLSv1.2;
   ssl_ciphers     'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384: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_ecdh_curve  secp521r1;  # funktioniert nicht mir Chrome(ium) 53 -  ERR_SSL_OBSOLETE_CIPHER
        ssl_ecdh_curve secp384r1;   # niedrigere Security, läuft aber mit Chrome 53 :-(

## Send header to tell the browser to prefer https to http traffic
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

## Specifies that server ciphers should be preferred over client ciphers
        ssl_prefer_server_ciphers on;

## Enables all nginx worker processes share SSL session information
        ssl_session_cache shared:SSL:30m;

## Increases the amount of time SSL session information in the cache is valid
        ssl_session_timeout 30m;

## Specifies a file with DH parameters for EDH ciphers
## Run "openssl dhparam -out /path/to/ssl/dhparam.pem 2048" in
## terminal to generate it
        ssl_dhparam /etc/ssl/dhparam.pem;

## Enables OCSP stapling
        ssl_stapling on;
        resolver XX.XX.XX.XX;
        ssl_stapling_verify on;
resolver XX.XX.XX.XX; muss natürlich gegen den passenden eigenen DNS-Resolver geändert werden.

dhparam erzeugen (das dauert je nach Länge eine Weile):

dhparam -out /etc/ssl/dhparam.pem 2048

Geänderte Konfiguration laden

service nginx reload

Testen

Wenn alles gepasst hat, dann sollte jetzt bei Aufruf der URL http://www.example.com nach https://www.example.com weitergeleitet werden und (je nach Browser) ein grünes Schloss bei https angezeigt werden.

Wer will kann das ganze noch mit der Webseite des SSL-Labs prüfen, aktuell (Stand Dezember 2016) sollte dies ein “A+” ergeben.

Automatische Zertifikatserneuerung

Die Gültigkeit der Let’s Encrypt Zertifikate ist auf 3 Monate beschränkt. Deshalb sollte ein wöchentlicher Check durchgeführt werden. Mit folgenden Cron-Job wird das Zertifikat geprüft, und 30 Tage vor Ablauf erneuert.

nano /etc/cron.weekly/dehydrate-renew 
#!/bin/bash
/opt/dehydrated/dehydrated -c
Damit nach Erhalt eines neuen Zertifikats der Webserver dieses auch verwendet, muss dieser neu geladen werden. Dazu nun in der Datei /etc/dehydrated/config die Zeile hinzufügen
HOOK=/opt/dehydrated/nginx_hook.sh
Das Beispiel-Skript kopieren
cp /opt/dehydrated/docs/examples/hook.sh /opt/dehydrated/nginx_hook.sh
und in nginx_hook.sh die Funktion deploy_cert um diesen Aufruf erweitern

systemctl reload nginx

Hint

Wer auf Nummer sicher gehen will, kann das Dehydrated Skript auch mit einem anderen User als root ausführen lassen, dazu ist ein eigener Benutzer anzulegen und die Berechtigungen entsprechend zu setzten.