Aktionen

ISPConfig 3.0.5.4p8 Webseiten https mit letsencrypt absichern und Zertifikate automatisch erneuern

Aus znilwiki

Warning.png
Warnung: Der Artikel gilt nur für alte ISPConfig Versionen. Die neueren (z.B. 3.1.6) haben das als Feature bei den Webseiten eingebaut - man muss nur den Haken setzten


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:

ISPConfig-LetsEncrypt-001.png



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

ISPConfig-LetsEncrypt-002.png



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:

ISPConfig-LetsEncrypt-004.png
ISPConfig-LetsEncrypt-003.png




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:

ISPConfig-LetsEncrypt-005.png50x50.pngISPConfig-LetsEncrypt-006.png




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

Warning.png
Warnung: Ihr dürft bei Angabe von --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.

Warning.png
Warnung: Falls Ihr den Aufruf von Hand testen wollt - Überteibt es nicht! Wenn Ihr das 5 mal in 7 Tagen macht obwohl die Zertifikate noch gültig sind seit Ihr erst einmal gesperrt bis die 7 Tage um sind! Das machen die so um Ihre Server zu entlasten!
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:

ISPConfig-LetsEncrypt-007.png ISPConfig-LetsEncrypt-008.png


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:

ISPConfig-LetsEncrypt-009.png ISPConfig-LetsEncrypt-010.png



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.



Kommentare

Loading comments...