Kategorien
devnotes Linux Software

Let’s Encrypt für nginx unter Debian 8 einrichten

Vorwort

Wie man unschwer erkennen kann, ist wandpapier.de nun nicht mehr über http, sondern über https erreichbar. Hintergrund ist die Umstellung des nginx-Servers auf https mit Hilfe von certbot-auto der EFF. Ich werde euch dabei meine Vorgehensweise unter Debian 8 beschreiben. Vergesst aber bitte nicht, dass ihr diese Anleitung auf eigenes Risiko nutzt und ich keine Garantie für irgendetwas übernehme was bei euch nicht funktioniert und schief läuft!

Voraussetzungen

  • Zugriff auf den Server
  • Zugriff auf die Konfigurationsdateien von nginx

Nun die Schritte

certbot-auto einrichten

cd /usr/local/sbin
sudo wget https://dl.eff.org/certbot-auto
sudo chmod a+x /usr/local/sbin/certbot-auto

Damit habt ihr ein überall ausführbares certbot-auto. Man kann certbot auch über die jessie-Backports bekommen. Das sieht dann so aus.

sudo echo "deb http://ftp.de.debian.org/debian jessie-backports main" >> /etc/apt/sources.list
sudo apt-get update
sudo apt-get install certbot -t jessie-backports

.well-known-Ordner einrichten

Extra einrichten brauch man da eigentlich nichts. Man sollte aber nginx sagen, wie darauf von außen zugegriffen werden kann. Das geschieht im server-Block der nginx-Konfiguration. Darin sollte folgendes eingetragen werden.

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

Solltet ihr wie ich andere location-Einträge haben, so kann es dabei zu Problemen kommen, vor allem wenn diese Einträge per Regex gesteuert werden. So habe ich zum Beispiel für statische Dateien einen Eintrag

location ~ ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|woff)$ {
    access_log off;
    expires max;
    add_header Pragma public;
    add_header Cache-Control "public";
}

Dann solltet ihr nach dem letzten location-Eintrag im server-Block folgendes in eurer Konfiguration stehen haben.

location ~ /\. {
    deny all;
}

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

Nun prüft ihr eure nginx-Konfiguration mit nginx -t auf Fehler. Diese sollte im Bestfall keine Fehler werfen. Falls doch, schaut wo der Fehler genau liegt und korrigiert diesen. Danach startet ihr per service nginx restart nginx neu, damit die Einstellungen übernommen werden.

Zertifikat anlegen

Kommen wir zum eigentlichen Anlegen eines Zertifikates. Wer eine Begleitung mit Oberfläche durch alle Schritte benötigt, kann sich das Zertifikat per certbot-auto certonly erstellen lassen. Wer es alles über die Shell machen möchtekann dies wie folgt tun.

certbot-auto certonly -a webroot --webroot-path=/pfad/zum/public/verzeichnis --renew-by-default --email deineEmail@anbieter.de --text --agree-tos -d deineDomain.de -d www.deineDomain.de

Damit nur das neue Zertifikat herunter geladen werden kann und icht noch irgendwas an irgendwelchen Einstellungen geändert wird ist certonly zuständig. Das verwendete Authentikatorplugin webroot wird mit -a webroot festgelegt. Das legt in den .well-known Ordner im Root-Verzeichnis eurer unter eurer Domain für letsencrypt prüfbare Dateien an. Daher auch die Freigabe dieses Ordners in nginx. Mit –webroot-path gebt ihr den Pfad auf eurem System an, welcher dem Root unter eurer Domain entspricht. Das sind meist Ordner mit dem Namen public, httpdocs oder ähnliches, je nachdem was ihr bei euch eingerichtet habt. Der Parameter –renew-by-default  wird dazu genutzt, dass ein bereits vorhandenes Zertifikat erneuert wird. Und das unabhängig davon, ob es abgelaufen ist oder nicht. –text gibt alles von certbot-auto auf der Kommandozeile aus statt in der standardmäßig genutzten Oberfläche. Die Nutzungsbedingungen akzeptiert ihr mit dem Parameter –agree-tos. Die zu zertifizierenden Domains werden mit -d angegeben. Dabei können wie auch im Beispiel mehrere angegeben werden.

Nun solltet ihr bei einer fehlerfreien Konfiguration von nginx und certbot-auto etwa folgende Ausgabe erhalten.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for deineDomain.de
Using the webroot path /pfad/zum/public/verzeichnis for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/deineDomain.de/fullchain.pem. Your cert will
   expire on 2017-02-15. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to deineEmail@anbieter.de
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Damit liegen nun alle notwendigen Zertifikatsdateien im Ordner /etc/letsencrypt/live/deineDomain.de/. Das ist ein Ordner mit Symlinks zu den aktuellen Dateien, welche im Original unter /etc/letsencrypt/archive/deineDomain.de/.

Es werden insgesamt vier Dateien erstellt. cert.pem  ist das Domain-Zertifikat, chain.pem  ist das Let’s encrypt chain Zertifikat, fullchain.pem  sind beide nochmal zusammen in einer Datei und privkey.pem  ist der Private Key zum Zertifikat.

Um das ganze noch weiter abzusichern erstellt man sich eine Diffie-Hellmann-Gruppe per sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048. Je nach Rechenleistung des Servers kann das bis zu einer Minute dauern bis die Datei /etc/ssl/certs/dhparam.pem erstellt wurde. Diese benötigen wir später noch für nginx.

nginx auf https umstellen

Nachdem wir die notwendigen Dateien erhalten haben machen wir uns daran nginx auf https umzustellen. Dazu sucht ihr euch wieder den entsprechenden server-Block in eurer nginx-Konfiguration. Ihr sucht euch am besten die Stelle heraus, an der der Port geschrieben steht. Das sollte listen 80; sein. Diese Zeile könnt ihr löschen und fügt folgende Zeilen ein.

listen 443 ssl;

ssl_certificate      /etc/letsencrypt/live/deineDomain.de/fullchain.pem;
ssl_certificate_key  /etc/letsencrypt/live/deineDomain.de/privkey.pem;

Damit funktioniert das Ganze bereits. Um https noch weiter abzusichern kann man verschiedene Protokolle, Ciphers und natürlich auch die oben erstellte Diffie-Hellmann-Gruppe einbinden.

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
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:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=2628000;

Der Ablauf der SSL-Sitzung erfolgt nach einem Tag mit dem Eintrag ssl_session_timeout 1d;. Es wird per ssl_session_cache shared:SSL:50m; über alle nginx-Worker ein gemeinsamer SSL-Cache genutzt, der 50 MB groß ist. Das reicht laut nginx-Dokumentation für etwa 20.000 SSL-Sitzungen. Um nicht mit jedem Request den Status des Zertifikats abzufragen zu müssen wird ssl_stapling on; genutzt. Die Verifikation dessen wird mit ssl_stapling_verify on; eingeschalten. Damit der Browser sich merkt, dass die von nginx ausgelieferte Seite per https erreichbar ist und die Zertifikate nutzt gibt man add_header Strict-Transport-Security max-age=2628000; mit. Dabei legt man mit max-age die Dauer in Sekunden fest, für die sich der Browser das merkt. Im Fall oben wäre das die Dauer von einem Monat.

Damit wären wir mit nginx fertig und nach dem Neustart von nginx per service nginx restart ist eure Seite per https erreichbar.

Wollt ihr eine Umleitung von http auf https einrichten wollen, solltet ihr euch einen zweiten server-Block anlegen mit folgendem Inhalt.

server {
    listen 80;
    server_name deineDomain.de www.deineDomain.de;
    return 301 https://$host$request_uri;
}

Erneuerung einrichten

Leider sind die Zertifikate von Let’s encrypt nur drei Monate gültig. Da man aber das obige Prozedere nicht jedes Mal aufs Neue durcharbeiten möchte, gibt es mit certbot-auto renew eine Möglichkeit das kürzer zur gestalten. Damit werden vorhandene Zertifikate erneuert, sofern deren Ablaufdatum unter 30 Tage in der Zukunft liegen. Und damit man auch das nicht händig machen muss, legt man sich einen Cronjob per crontab -e  an.

15 1 * * 1 /usr/local/sbin/certbot-auto renew >> /var/log/letsencrypt-renew.log
20 1 * * 1 service nginx reload

Damit wird das Zertifikat jeden Montag um 01:15 erneuert und nginx um 01:20 neu gestartet. Somit hat man jederzeit ein aktuelles Zertifikat.

Nun viel Vergnügen und Erfolg mit eurer ssl-gesicherten und per https erreichbaren Seite.

Quellen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.