SSL mit LetsEncrypt ganz einfach - linuxmuster-dehydrated zum Test verfügbar

Hallo,

nachdem an anderer Stelle das Problem mit nicht (mehr) vertrauenswürdigen StartSSL Zertifikaten aufgetaucht ist, habe ich mal eben ein kleines Paket gestrickt, mit dem man seinen Server mit einem LetsEncrypt Zertifikat versorgen kann, ohne den mehrere Megabyte großen Binär/Python-Blob von LetsEncrypt installieren zu müssen.

Das Ganze ist ein Installationswrapper für https://github.com/lukas2511/dehydrated, das zu installierden Paket ist 17kB gross :wink:

Das Paket hänge ich mal hier an, ich schaff es nicht mehr, das noch ins Repo zu schieben heut abend, den Quellcode findet man hier:

und (wohl wichtiger) die Dokumentation dort:

VG, Frank

3 „Gefällt mir“

Das Paket ist jetzt gemäß Anleitung aus den Repos installierbar.

Hallo Frank,

könntest du deine Doku bitte noch in in die Hauptdoku einfügen (http://docs.linuxmuster.net/de/latest/howtos/contribute/new.html)? Aus meiner Sicht spricht nichts dagegen das unter “Weitere HowTos” einzufügen.

vG

Hallo Frank,

zunächst ganz herzlichen Dank für die Mühe, ich möchte das gerne ausprobieren.

Jetzt habe ich noch zwei Verständnisfragen (ich bin wirklich nicht der Zertifikatsexperte):

Ich habe Port 80 standardmäßig nach außen nicht offen, da ich ja eben nur verschlüsselt anbieten will. Muss ich jetzt Port 80 nur einmalig kurz öffnen, damit Letsencrypt das erste Zertifikat erstellen kann, oder warum ist das nötig?

Wir haben zwei verschiedene Apachen auf zwei unterschiedlichen virtuellen Maschinen laufen:

  • auf server.schule.xxxxx.de (der eigentliche lmn-Server)
  • auf server.schule.xxxxx.de:8443 (wird per Firewallregel im IPFire auf unseren Vertretungsplan-Server umgelenkt)
    Da beide Server nach außen unter demselben Namen auftauchen konnten wir dasselbe Zertifikat verwenden. Da wir bislang nur einmal pro Jahr das Zertifikat erneuert haben habe ich einfach das neue Zertifkat auf beide Server gespielt, und das hat gut funktioniert. Wie müsste ich da jetzt verfahren?

LG Alex

Hallo Alexander,

LetsEncrypt Zertifikate gelten immer nur für 3 Monate und erneuern sich dann selbst, wenn man einen korrekt konfigurierten ACME Client verwendet. Damit das klappt, muss Port 80 immer offen sein. Das ist für sich genommen aber keinerlei Risiko, du muss eben nur dafür sorgen dass die von dir auf dem Server angebotenen Dienste nicht über Port 80 erreichbar sind. Ich habe die Dokumentation um einen entsprechenden Abschnitt erweitert, wie man das erreichen kann, lass mich wissen, ob das verständlich ist. (howto_letsencrypt_dehydrated/source/index.rst at master · linuxmuster-docs/howto_letsencrypt_dehydrated · GitHub)

Einer der Server ist für die Erneuerung der Zertifikate zuständig, dort ist linuxmuster-dehydrated installiert. In der Datei
/etc/linuxmuster-dehydrated/hook.sh kannst du Aktionen definieren, die ausgeführt werden, wenn das Zertifikat tatsächlich erneuert wurde, normalerweise startet das nur den Apachen neu. Du kannst aber ebensogut dort Aktionen eintragen, die das neue Zertifikat auf den anderen Server kopieren und dort den apachen neu starten. (Passwortloses SSH mit Key?). Wenn du diesbezüglich Hilfe benötigst, melde dich nochmal.

VG

Frank

Hej,

Ad 1: Port 80 muss wohl nach außen offen sein, da der Letsencrypt-server über diesen Port deinen Server kontaktiert um zu verifizieren, dass Du ihn wirklich kontrollierst. Den Port 80 nur kurz aufzumachen, ist nicht sinnvoll: Die Letsencrypt-Zertifikate sind ja nur 90 Tage gültig. Das Schöne an dehydrated und Franks Paket ist ja, dass nach der Ersteinrichtung alles automatisch läuft…
Du kannst aber eine SSL-Weiterleitung in der Apache-config-Datei (in /etc/apache2/sites-available) einrichten:
Redirect permanent / https://server.schule.xxx.de/
Bei mir kommt dehydrated damit zurecht…

Ad 2: Das müsste auch weiterhin so funktionieren. Vielleicht kannst Du den Prozess ja auch wieder automatisieren: Auf einem Server läuft dehydrated und der andere Server holt sich regelmäßig von dort per scp das aktuelle Zertifikat.

Grüße Michael

P.S. Ob StartSSL wieder vertraut werden wird, hängt wohl damit zusammen ob WoSign (der böse Aufkäufer) eine organisatorische Trennung von StartCom umsetzt (https://www.computerbase.de/2016-11/sicherheit-mozilla-google-apple-wosign-startcom/)… Unterm Strich: StartSSL ist derzeit keine Option.
P.P.S Für die Hintergründe zu dehydrated und zum ACME-Protokoll fand ich dieses Video sehr hilfreich:

Wenn das mal ein paar Menschen (erfolgreich) getestet haben, mach ich das!

Hallo Michael,

So mach ich das auch, ich glaube, es gibt eine theoretische Möglichkeit, dass das nicht mehr klappt: Der ACME Challenge kommt immer über Port 80 rein und wird dann auf https 443 umgebogen und wird da ausgeliefert und damit bestätigt. Ich glaube, wenn das Zertifikat einmal ungültig wird (was ja nicht passieren sollte, aber…) klappt das nicht mehr, weil ich denke, dass LE keine Challenge von einem ungültigen Zertifikat akzeptieren wird. Muss man halt im Hinterkopf haben, dann müsste man tatsächlich kurz die permanente Weiterleitung deaktivieren.

Danke fürs Video, warum wird das nun wieder nicht eingebunden…?

VG

Frank

Ich weiss es: Die CCC Seite ist nicht sicher :frowning: (Mixed Content)

Überlistet :slight_smile:

Hej Frank,
Ja, jetzt klappts… Hatte mich schon gewundert und den Link nochmal hinter einen Text gepackt. Hast Du das nun serverseitig zugelassen, oder warum tut’s nun?

Zurück zum Thema und zu einer Frage, die auch die anderen interessieren könnte: Benutzt Du die hook.sh?
Ein Apache-Neutstart ist doch nur notwendig, wenn die Konfig geändert wurde und nicht, wenn einfach ein neues Zertifikat geholt wurde…?

Grüße
Michael

Das unsichere Element war der Film selbst, der wurde auf er CCC-Seite von einem weiteren Server als http eingebunden. Ich habe die Film URL genommen und aus http https gemacht, drum ist Discourse jetzt zufrieden.

Ich glaube der apache liest beim Start die Zertifikate, drum restarte ich den bei erneuertem Zertifikat. So schlägt es auch die Doku von dehydrated vor. Ich vermute, dass es nicht wirklich schlimm wäre, wenn mans nicht tut, aber apache Prozesse die mit dem alten Zertifikat laufen würden wohl mosern. Keine Ahnung…

Hi.
Ich würde das auch gerne einsetzen, um intern ein gültiges Zertifikat zu haben – allerdings will ich den Server nicht wirklich 24/7 nach außen hin erreichbar machen; und schon gar nicht über Port 80.
[etwas später… Ah, ok! Habe gerade die Anleitung bis ganz unten gelesen. Scheint ja kein Problem zu sein!)

Also ich habe das jetzt installiert, und es hat wirklich reibungslos geklappt. In der Doku ist an einer Stelle noch ein Tippfehler ( /cert/ statt /certs/), aber das war es auch schon.
Ich bin jetzt gespannt, ob in 3 Monaten mit der automatischen Erneuerung - und vor allem mit der von mir in der hook.sh erstellten automatischen Übertragung auf einen anderen Server - alles glatt geht…

Bis hierhin also tausend Dank, wie immer konnte ich mich auf linuxmuster.net 100% verlassen!

LG Alex

1 „Gefällt mir“

Du musst ja deine Dienste nicht über 80 erreichbar machen. Wenn der apache oder deine WebApp ein Loch hat bist du über 443 genauso angekäst wie über 80, nur dass der Angriff dann über den verschlüsselten Draht kommt :wink:

Wenn du ganz paranoid bist, kannst du natürlich den Cronjob anpassen, dafür ist das Skript /etc/cron.daily/linuxmuster-dehydrated zuständig. Du kannst dort die apache Konfiguration anpassen, so dass er auf 80 hört, dann den apachen restarten, das Zertifikat checken, den Port 80 wieder deaktivieren, apache neu starten. Ich halte das für sehr paranoid, aber wer weiß, die Russen :stuck_out_tongue: und wenn du deinen Server sonst nach draußen gar nicht offen hast und nur ein Zertifikat für die Schulkonsole haben willst, why not. Wahrscheinlich muss noch das eine oder andere sleep 5 dazwischen, aber sonst sollte das gehen.

Die Ports des Apachen konfiguriert man in /etc/apache2/ports.conf , da kannst du den 80er rein und rausnehmen, dann ist die Portweiterleitung auf dem IPfire auch wurscht, weil auf deinem Server nichts mehr auf 80 hört.

VG

Frank

Gefixt, danke.

4 Beiträge wurden in ein neues Thema verschoben: Externe Mailadressen nutzen - wie?

Hey,

ich habe es jetzt auch mal erfolgreich getestet und ein paar kleinigkeiten in github hochgeladen.
zum Testen kann man:

#CA="https://acme-staging.api.letsencrypt.org/directory"
#CA_TERMS="https://acme-staging.api.letsencrypt.org/terms"

in die config einfügen, auskommentiert, allerdings muss man dafür extra --register aufrufen…

Noch den Vorschlag, von Dominik entnommen, der das mit Hilfe von cert-bot-auto: anwenderwiki:server:ssl-tls-letsencrypt [CommunityWiki] gemacht hat, „server.pem“ direkt zu schreiben, weil es dann gleich verwendet wird von slapd,cyrus und apache2

#!/bin/bash

if [ ${1} == "deploy_cert" ]; then

    echo " + Hook: Deploying to Apache/slapd/cyrus... $1"
    
    TARGETDIR=/etc/ssl/private

    echo "   + Sichere altes Zertifikat"
    cp -a $TARGETDIR/server.pem $TARGETDIR/server.pem_$(date +%Y%m%d.%H:%M)

    echo "   + Kopiere neues Zertifikat nach $TARGETDIR"
    cat "$3" > $TARGETDIR/server.pem 
    cat "$5" >> $TARGETDIR/server.pem
    
    chmod 0640 $TARGETDIR/server.pem
    chown root:ssl-cert $TARGETDIR/server.pem

    echo "   + Restart services"
    service apache2 reload
    service slapd restart
    service cyrus-imapd reload

    # Beispiel, um es  auf einen anderen Webserver zu kopieren:
    #echo "   + Copy to cloudserver"
    #rsync -avP $TARGETDIR/server.pem cloud:/etc/ssl/private/server.pem
    #ssh cloud service apache2 reload

else
    echo " + Hook: Nothing to do... $1"
fi

vG, Tobias

Hai,

Sieht nicht übel aus :wink:

ich hab dich als Mitarbeiter für das Repo eingeladen, kannst du das bei Gelegenheit reinpushen, testen und mir Bescheid geben wenn es tut :wink: Dann bau ich ein aktualisierten Paket und leg das aus.

VG

Frank

Hi,

ich hab jetzt das mal umgesetzt, da ich den server selbst nicht als webserver nach draußen verwenden will. 443 geht auf einen anderen server, daher: port 80 auf, challenge → validation, port zu:

Ich hab jetzt die hook.sh der Vorlage vom entwickler genommen.

deploy_challenge() {
 local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"                                                                                                                                                

 source $CONFIG

 if [ "x$DEACTIVATE_PORT80" = "xyes" ]; then
     if ! grep "^Listen 80" /etc/apache2/ports.conf >/dev/null 2>&1; then
         echo " + Activating Apache on port 80"
         echo "Listen 80" >> /etc/apache2/ports.conf
         service apache2 reload
     fi
 fi
}
deploy_cert() {
 local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
    echo " + Deploying to Apache/slapd/cyrus..."

    # TARGET in the standard linuxmuster.net-installation                                                                                                                               
    TARGETDIR=/etc/ssl/private

    echo "   + Sichere altes Zertifikat"
    cp -a $TARGETDIR/server.pem $TARGETDIR/server.pem_$TIMESTAMP

    echo "   + Kopiere neues Zertifikat nach $TARGETDIR"
    ## put all in one:                                                                                                                                                                  
    cat "$KEYFILE" > $TARGETDIR/server.pem
    cat "$FULLCHAINFILE" >> $TARGETDIR/server.pem

    chmod 0640 $TARGETDIR/server.pem
    chown root:ssl-cert $TARGETDIR/server.pem

    echo "   + Restart services"
    service apache2 reload
    service slapd restart
    service cyrus-imapd reload
}
exit_hook() {
 source $CONFIG

 if [ "x$DEACTIVATE_PORT80" = "xyes" ]; then
     if grep "^Listen 80" /etc/apache2/ports.conf >/dev/null 2>&1; then
         echo " + Deactivating Apache on port 80"
         sed "/^Listen 80/d" -i /etc/apache2/ports.conf
         service apache2 reload
     fi
 fi

}
HANDLER="$1"; shift
if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|deploy_cert|unchanged_cert|invalid_challenge|request_failure|exit_hook)$ ]]; then
    echo " + Hook $HANDLER..."
    "$HANDLER" "$@"
fi

Dabei hab ich noch die /etc/linuxmuster-dehydrated/config aufgebohrt mit folgendem Switch:

 DEACTIVATE_PORT80="yes"

Schien in meinen Tests erfolgreich zu laufen. Ich warte jetzt mal 60 Tage ab, bis cron die automatische Aktualisierung versucht…

VG, Tobias