ISPConfig 3.0.5.4p8 Webseiten https mit letsencrypt absichern und Zertifikate automatisch erneuern
Aus znilwiki
Changelog:
- 17.12.2016 erste Version des Artikels
- 10.02.2015 SAN Zertifikate ergänzt (Zertifikate mit mehreren Domänennamen)
- 04.03.2016 fullchain.pem ergänzt
- 23.09.2016 Alles an certbot angepasst
Die kostenlosen Zertifikate von https://letsencrypt.org/ sind für mich als private Person eine feine Sache.
Im Gegensatz zu den Zertifakten von https://startssl.com/ werden die Zertifikate tatsächlich von allen Browsern als gültig aktzeptiert.
Der Firefox mag die StartSSL Zertifikate nicht und auch in vielen Kundenumgebungen gelten diese als "unsicher".
Der Vorteil bei StartSSL ist aber das die Zertifikate 1 Jahr gültig sind.
Bei Let's Encrypt sind es nur 3 Monate ... da sollte man unbedingt die automatische Erneuerung nutzen damit man es nicht vergisst.
Nun, ich musste ein wenig probieren aber nun habe ich eine lauffähige, dauerhafte Lösung für mich gefunden.
Ausgangslage
- Ubuntu 14.04.x LTS
- Apache 2.4.7 (Ubuntu)
- ISPConfig 3.0.5.4p8
Webseite/Domäne die ich Absichern will:
remote.znil.net
Apache vorbereiten
Für die nachfolgenden Punkte sollte die folgenden beiden Erweiterungen von Apache aktiv sein:
sudo -i a2enmod rewrite a2enmod ssl
Wahrscheinlich sind die beiden schon aktiv, den Befehl noch einmal auszuführen schadet aber auch nicht.
Danach den Apache neu starten:
service apache2 restart
Vorbereitung der Webseite
Wir rufen die Webseite im ISPCpnfig Konfigurator auf:
Auf dem Reiter Domain setzen wir den Haken bei SSL:
Auf dem Reiter SSL füllt Ihr die oberen Felder nach belieben aus (Muss etwas drin stehen, wird aber später nicht mehr genutzt)
und setzen unten die SSl Action auf Create certificate
Auf dem Reiter Options kopiert Ihr folgendes in das Feld Apache Directives:
# Verzeichnis für Let's Encrypt Webroot Methode <IfModule mod_headers.c> <LocationMatch "/.well-known/acme-challenge/*"> Header set Content-Type "text/plain" </LocationMatch> </IfModule> # Immer Umleiten auf https <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} </IfModule>
Den 2. Teil mit der Umleitung auf https könnt Ihr auch weglassen.
Ich habe es immer drin - denn wenn ich schon eine Seite per SSL absichere will acuh nur noch über das sichere Protokoll darauf zugreifen.
Dann speichern wir!
Jetzt dauert es einen Moment bis ISPConfig im Hintergrund die Änderungen verarbeitet hat (ein bis 5 Minuten),
wenn wir dann unsere Webseite aufrufen bekommen wir eine Zertifikatswarnung und das Zertifikat ist halt ein selbstsigniertes:
Let's Encrypt installieren
Wir öffnen eine SSH Sitzung auf unseren Webserver und wechseln zum root:
sudo -i
Falls nicht vorhanden installieren wir zunächst git nach:
apt-get install git
Dann können wir letsencrypt installieren:
cd /opt git clone https://github.com/certbot/certbot cd /opt/certbot/ ./letsencrypt-auto --help
Der letzte Aufruf sorgt dafür das sich letsencrypt richtig einrichtet und ggf. benötigte Pakete nachinstalliert.
Diesen Check macht das Programm bei jedem Aufruf - aber nur beim ersten mal dauert es so lange.
Danach wird er nur prüfen und entsprechend schneller starten.
Erstes Zertifikat anfordern
Nun sind wir bereit unser erstes Zertifikat anzufordern.
Meine Domäne in diesem Beispiel heißt - wie am Anfang erwähnt:
remote.znil.net
Die zugehörigen Ordner zu der Domäne liegen dann also unter
Webseite : /var/www/remote.znil.net/web/ Zertifikate : /var/www/remote.znil.net/ssl/
Mit dem folgenden Aufruf fordern wir ein Zertifikat für unsere Domäne mit dem obigen Pfad an:
/opt/certbot/letsencrypt-auto certonly --webroot --rsa-key-size 4096 -w /var/www/remote.znil.net/web/ -d remote.znil.net
Erklärung:
certonly = nur Zertifikat Anfordern, es aber nicht in Apache installieren --webroot = vorhandenen Webserver nutzen (keinen eigenen starten) --rsa-key-size 4096 = SSL Schlüssel mit 4096 statt 2048 Bits erzeugen (= länger = sicherer) -w /var/www/remote.znil.net/web/ = Pfad zum Webstammverzeichnis der Domäne inklusive abschließenden / -d remote.znil.net = Name der dazu gehörigen externen Domäne
Beim nun allerersten Aufruf fragt er euch nach eurer Email-Addresse. Gebt da eine echte Adresse an damit mit Ihr bei Problemen acuh informiert werden könnt!
Danach müsst Ihr die Nutzungsbedingungen einmalig akzeptieren.
Beides geschieht nur bei der ersten Anforderung auf eurem Server!
Das angeforderte Zertifikat liegt nun unter
/etc/letsencrypt/live/name.euerer.domain
bei diesem Beispiel also unter
ls -l /etc/letsencrypt/live/remote.znil.net/
Ausgabe:
root@web01:# ls -l /etc/letsencrypt/live/remote.znil.net/ insgesamt 0 lrwxrwxrwx 1 root root 39 Dez 17 21:15 cert.pem -> ../../archive/remote.znil.net/cert1.pem lrwxrwxrwx 1 root root 40 Dez 17 21:15 chain.pem -> ../../archive/remote.znil.net/chain1.pem lrwxrwxrwx 1 root root 44 Dez 17 21:15 fullchain.pem -> ../../archive/remote.znil.net/fullchain1.pem lrwxrwxrwx 1 root root 42 Dez 17 21:15 privkey.pem -> ../../archive/remote.znil.net/privkey1.pem
Nun müssen wir dieses Zertifikat nur noch nutzen!
Zertifikat in Webseite einbauen
Für jede Webseite legt ISPConfig eine Datei unter
/etc/apache2/sites-available/
an. Meine Webseite heißt
remote.znil.net
dann müssen wir folgende Datei bearbeiten:
nano /etc/apache2/sites-available/remote.znil.net.vhost
In der Datei sucht nach den folgenden Zeilen:
<IfModule mod_ssl.c> SSLEngine on SSLProtocol All -SSLv2 -SSLv3 SSLCertificateFile /var/www/clients/client0/web4/ssl/remote.znil.net.crt SSLCertificateKeyFile /var/www/clients/client0/web4/ssl/remote.znil.net.key </IfModule>
und ändert diese wie folgt ab:
<IfModule mod_ssl.c> SSLEngine on SSLProtocol All -SSLv2 -SSLv3 # SSLCertificateFile /var/www/clients/client0/web4/ssl/remote.znil.net.crt # SSLCertificateKeyFile /var/www/clients/client0/web4/ssl/remote.znil.net.key SSLCertificateFile /etc/letsencrypt/live/remote.znil.net/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/remote.znil.net/privkey.pem SSLCACertificateFile /etc/letsencrypt/live/remote.znil.net/fullchain.pem </IfModule>
remote.znil.net müsst Ihr dabei natürlich durch euren eigenen Webseitennamen ersetzen!
Und ja, wir ersetzen die 2 Einträge damit durch 3 neue Einträge! Ohne den 3. Eintrag SSLCACertificateFile kann es Probleme geben!
Im Anschluß müsst Ihr den Apache seine Konfiguration neu einlesen lassen:
service apache2 reload
Wenn Ihr nun eure Webseite aufruft so sollte diese sich mit dem letsencrypt Zertifikat melden:
Automatische Erneuerung in 3 Varianten
Variante 1: Die einfachste!
Habe ich erst kürzlich beim Umzug meines Servers entdeckt als ich die mal die ganze Anleitung auf der Let's Encrypt Webseite gelesen habe. Ich behaupte einfach mal das diese bei der ursprünglichen Erstellung dieses Artikel noch nicht funktionierte:
Die dort beschriebene Methode deckt alle Szenarien ab - man muss nur damit leben das alle paar Monate(!) der Webserver mal kurz für eine Minute angehalten wird.
Variante 2: Automatische Erneuerung des Zertifikates
--renew-by-default
keinen neuen Domänennamen hinzufügen oder einen weglassen! Kommt eine weitere Domäne hinzu müsst Ihr erst wieder eine Anforderung wie in den Abschnitten zuvor machen. Im Dialog könnt Ihr dann Expand wählen und der neue Name wird mit eingebaut
Nun läuft das Zertifikat nach genau 90 Tagen wieder ab.
Um es zu erneuern reicht - im Prinzip - der erneute Aufruf des Befehls mit dem wir das Zertifikat auch schon angefordert haben.
Jedoch wird dabei ein Menü erscheinen welches auch fragt ob Ihr das alte überschreiben wollt (falls es denn noch gültig ist).
Um das zu verhindern kann man noch den Parameter
--renew-by-default
setzen. Der ist extra für Cron-Jobs gedacht und setzt vorraus das es zu keinen Nachfragen kommt.
Beim ersten Aufruf auf dem Server MUSS es also ohne diesen Parameter sein.
Neuerdings könnte Ihr ein
--dry-run
anhängen - dann simuliert er nur!
Der Aufruf für den Cron-Job wäre also
/opt/certbot/letsencrypt-auto certonly --webroot --rsa-key-size 4096 --renew-by-default -w /var/www/remote.znil.net/web/ -d remote.znil.net
Nun müssen wir uns noch für einen vernünftigen Zeitrahmen entscheiden.
Die meisten anderen im Internet stellen den Job auf 30 Tage ... nun das Ding ist 90 Tage gültig ...
Ich habe mich für folgendes enstchieden:
- Das Zertifikat habe ich am 17. des Monats angefordert
- Erneuerung also alle 2 Monate am 16.
- Um 5:30 Uhr wenn es keinen stört!
Daraus ergibt sich folgender Eintrag in der crontab:
crontab -e
und dann
30 5 16 */2 * /opt/certbot/letsencrypt-auto certonly --webroot --rsa-key-size 4096 --renew-by-default -w /var/www/remote.znil.net/web/ -d remote.znil.net > /dev/null
Variante 3: Automatische Erneuerung bei Reverse Proxy Webseiten
Mit Certobot (bis ISPConfig 2.1)
Viele meiner Subdomains hosten gar keine Webseiten sondern leiten den Datenverkehr nur um auf einen anderen Dienst.
Hier kommen wir mit der Methode nicht weiter da letsencrypt es nie schaffen wird seine Daten zu lesen.
In diesem Fall ist es am einfachsten beim Aufruf statt des Apache den in letsencrypt Webserver zu nehmen.
Nachteil ist das dazu der eigentliche Apache kurz angehalten werden muss - was ich aber alle 2 Monate mal kurz verschmerzen kann
Die erste Anforderung sähe dann wie folgt aus:
service apache2 stop && /opt/certbot/letsencrypt-auto certonly --standalone --rsa-key-size 4096 -d remote.znil.net && service apache2 start
Und die automatische Erneuerung in der crontab entsprechend so:
30 5 16 */2 * service apache2 stop && /opt/certbot/letsencrypt-auto certonly --standalone --rsa-key-size 4096 --renew-by-default -d remote.znil.net && service apache2 start > /dev/null
Mit acme.sh (ab ISPConfig 3.2)
"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --standalone --pre-hook "systemctl stop apache2.service" --post-hook "systemctl start apache2.service" > /dev/null
Den Benutzer müsst Ihr ggf. gegen euren Benutzer anpassen, es sollte der Login-Benutzer sein.
Ggf. braucht dieser die sudo Rechte um die dienste neu zu starten (ohne Passwort)
SAN-Zertifikate bzw. ein Zertifikat für mehrere Webseiten gleichzeitig
SAN-Zertifikate sind Zertifikate die gleichzeitig für mehrere Domänennamen gültig sind.
Zum Beispiel das für meinen Test-Exchange-Server:
Jede Menge Domänennamen und für jedes dieser Domänen ist das zertifikat gültig.
Nun gibt es bei letsencrypt die Einschränkung das diese Domänennamen auch überpüft werden müssen/können.
Das bedeutet das man halt keine internen Domänenenamen in das Zertifikat aufnehmen kann.
Auch Wildcard-Zertifikate werden - im Moment - nicht ünterstützt.
Im nachfolgenden will ich nun ein Zertifikat für die folgenden Subdomänen anfordern:
grafana.znil.net ispconfig.znil.net livecam01.znil.net login.znil.net nzb.znil.net pfsense.znil.net support.znil.net zabbix.znil.net
Diese sollen alle in ein einziges Zertifikat.
Für die Anforderung habe ich mich für diue Version über den interen Webserver des letsencrypt-Skripts entschieden das sehr viele Reverse-Porxy-Domänen dabei sind.
Die erste Anforderung würde wie folgt laufen:
service apache2 stop /opt/certbot/letsencrypt-auto certonly --standalone --rsa-key-size 4096 -d grafana.znil.net -d ispconfig.znil.net -d livecam01.znil.net -d login.znil.net -d nzb.znil.net -d pfsense.znil.net -d support.znil.net -d zabbix.znil.net service apache2 start
Wie Ihr seht wird einfach für jede Subdomäne / jeden Namen einfach ein -d Domänenname
angehängt.
Die Ausgabe ist wie folgt:
Updating letsencrypt and virtual environment dependencies....... Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --standalone --rsa-key-size 4096 -d grafana.znil.net -d ispconfig.znil.net -d livecam01.znil.net -d login.znil.net -d nzb.znil.net -d pfsense.znil.net -d support.znil.net -d zabbix.znil.net IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/grafana.znil.net/fullchain.pem. Your cert will expire on 2016-03-24. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Er speichert das Zertifikat also unter dme Namen des ersten -d
Eintrages in der Liste.
Das Zertifikat können wir nun wie gewohnt allen Webseiten die darin aufgeführt werden zuweisen.
Wenn wir es uns dann im Browser ansehen sieht es wie folgt aus:
Das Erneuern per crontab dazu sieht zum Beispiel so aus:
30 5 25 */2 * service apache2 stop && /opt/certbot/letsencrypt-auto certonly --standalone --rsa-key-size 4096 --renew-by-default -d grafana.znil.net -d ispconfig.znil.net -d livecam01.znil.net -d login.znil.net -d nzb.znil.net -d pfsense.znil.net -d support.znil.net -d zabbix.znil.net && service apache2 start > /dev/null
Für und Wieder der Methode
Wer das so macht wie ich dem muss bewusst sein das bei jeder Änderung in ISPConfig an der Webseite die gemachten Änderungen überschrieben werden!
Ich hatte es auch zunächst hiermit versucht: https://github.com/alexalouit/ISPConfig-letsencrypt
Es aber nicht zum laufen bekommen.
Naja .. und ich lege jede seite in ISPConfig an ... und danach nutze ich die Oberfläche eigentlich nicht mehr dafür.
Und mit dem Cronjob pro Webeite kann ich leben.
Was mich nicht daran hindern soll das ich es in ein paar Wochen eventuell eleganter hinbekommen und den Artikel hier dann ändere.