Cryptdomainmgr

4 Minuten zum lesen

Unterbrechungsfreie Erneuerung von X.509-Zertifikaten, TLSA-Einträgen und DKIM-Schlüsseln

Projektdaten  
Logo Logo für das Projekt Cryptdomainmgr
Quellcode Cryptdomainmgr auf Github
Paket Cryptdomainmgr auf Pypi
Lizenz AGPLv3
Vortrag Domain-Automatisierung mit Cryptdomaimgr

Cryptdomainmgr ist ein Python-Programm, welches TLS-Zertifikate, TLSA-Domaineinträge und DKIM-Schlüssel automatisch erneuert.

Das Verfahren “DNS-Based Authentication of Named Entities” (DANE) koppelt TLS-Zertifikate über Hashwerte (TLSA-Einträge) an die DNS-Zone. Im Falle einer kompromittierten Zertifizierungsstelle (CA) kann über den DNS-Eintrag die Richtigkeit des Zertifikates nachgewiesen werden. An unberechtigte Dritte ausgestellte Zertifikate werden entlarvt. Die DNS-Zone darf jedoch nicht kompromittiert sein und sollte per DNSSEC abgesichert werden.

Um den Versand betrügerischer E-Mails zu erschweren, signieren Mailserver E-Mails mit mit einem DKIM-Schlüssel. Die Signatur kann über den DKIM-Eintrag in der Absenderdomain validiert werden. Das Fälschen der Absenderdomain wird dadurch entdeckt.

Die asymmetrischen Schlüsselpaare für die DKIM-Signatur und TLS-Zertifikate müssen regelmäßig erneuert werden, um den Angriffszeitraum bei gebrochenen Schlüsseln gering zu halten.

Cryptdomainmgr erneuert die Schlüssel sowie DH-Parameter automatsich lückenlos ohne Downtime in drei Phasen: Prepare, Rollover, Cleanup. Auch negative Caching stellt dadurch kein Problem dar.

Aufbau

Der Cryptdomainmgr wird auf das System installiert, auf welchem der Web- oder Mailserver-Dienst läuft. Softwaremodule kommunizieren mit den externen Komponenten. Momentan können TLS-Zertifikate nur von Let’s Encrypt bezogen werden. Der DNS-Anbieter Internetworx stellt eine API bereit, über welche die DNS-Einträge aktualisiert werden können. Zum Erzeugen der DKIM-Schüssel und zum Signieren wird rspamd verwendet. Die Zertifikate werden den Mailserver-Diensten postfix und dovecot sowie dem Webserver apache2 zur Verfügung gestellt.

Um weitere DNS-Server, Zertifikatsanbieter und Dienste zu unterstützen kann Crypdomainmgr, ohne Änderungen am Hauptprogramm vornehmen zu müssen, mit entsprechenden Softwaremodulen erweitert werden.

Diagramm welches den Datenfluss zwischen Cryptdomainmgr und externen Diensten zeigt

Installation

Auf Debian 9 oder Ubuntu 18.04 sind mehrere Installationsschritte erforderlich. Die Software wird über pypi bereitgestellt. Da der zugehörige Paketmanager pip keine Abhängigkeiten über apt nachinstalliert, müssen diese zuerst manuell installiert werden:

apt install -y libcurl4-openssl-dev libssl-dev

Um Zertifikate bei Let’s Encrypt abzuholen wird curl benötigt:

apt install -y curl

Für die Erzeugung der DKIM-Schlüssel und zur DKIM-Signierung muss noch rspamd installiert werden:

apt install -y lsb-release wget # optional
CODENAME=`lsb_release -c -s`
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -
echo "deb [arch=amd64] http://rspamd.com/apt-stable/ $CODENAME main" > /etc/apt/sources.list.d/rspamd.list
echo "deb-src [arch=amd64] http://rspamd.com/apt-stable/ $CODENAME main" >> /etc/apt/sources.list.d/rspamd.list
apt update
apt install -y rspamd

Nun fehlt nur noch das eigentliche Programm:

python2 -m pip install cryptdomainmgr

Nutzung

Die gesamte Konfiguration erfolgt über Dateien im ini-Format. Die Einträge können über mehrere Dateien verteilt werden. Bei Konflikten gilt immer der Eintrag der letzten Datei.

Verwalten von IP-Adressen im DNS

Für den Zugriff auf die API des Domainhosters müssen Zugangsdaten angegeben werden. Zumindest das Passwort sollte in einer extra Datei liegen. Bspw. die Datei /etc/cryptdomainmgr/credentials.conf:

[domain]
handler = dnsuptools/inwx
user = myUsename
passwd = myPassword1234

Diese Angaben gelten grundsätzlich für alle verwalteten Domains. Abweichende Daten können auch für jede Domain einzeln hinterlegt werden.

Jetzt kann die Konfiguration für die erste Domain angelegt werden, bspw. die Datei /etc/cryptdomainmgr/mydomains.conf:

[domain:test1234.entroserv.de]
ip4 = auto
ip6 = auto

Die Minimalkonfiguration ist fertig. Sie hinterlegt die IPv4- und die IPv6-Adresse, über welche der Server extern erreichbar ist, automatisch im DNS. Die IP-Adressen werden durch Aufruf von ip4.icanhazip.com bzw. ip6.icanhazip.com ermittelt. Die Ermittlung der IP-Adressen und das Eintragen im DNS wird durch Aufruf von:

python2 -m cryptdomainmgr --update /etc/cryptdomainmgr/*.conf 

einmal ausgeführt.

Alternativ kann der Inhalt der Konfiguration auch direkt als Argument übergeben werden:

python2 -m cryptdomainmgr --update /etc/cryptdomainmgr/inwxcred.conf --config-content $'[domain:test1234.entroserv.de] \n handler=dnsuptools/inwx \n ip4=auto'

Wichtig ist das $-Zeichen, damit die \n als Zeilenumbruch interpretiert werden. In diesem Beispiel liegen die Zugangsdaten für inwx in /etc/cryptdomainmgr/inwxcred.conf.

Die Log-Ausgabe des Programms, sollte, wenn alles richtig funktioniert, ungefähr so aussehen:

[2019-02-03 16:07:22,496]    INFO      Interpreting config sections
[2019-02-03 16:07:22,496]    INFO        - cdm
[2019-02-03 16:07:22,497]    INFO        - domain
[2019-02-03 16:07:22,634]    INFO      Running phase: update
[2019-02-03 16:07:22,634]    INFO      Create resource records for section "test1234.entroserv.de"
[2019-02-03 16:07:24,144]    INFO      add (exists) A for test1234.entroserv.de : 92.60.36.246

Es wird sogar angezeigt, dass der Eintrag in identischer From schon vorhanden ist. Beim erstmaligen Ausführen steht dort: add (new) ....

Sollte bereits ein alter, nicht mehr gültiger, Eintrag vorhanden sein, wird auch der Löschvorgang protokolliert:

[2019-02-03 16:24:04,441]    INFO      Interpreting config sections
[2019-02-03 16:24:04,442]    INFO        - cdm
[2019-02-03 16:24:04,442]    INFO        - domain
[2019-02-03 16:24:04,598]    INFO      Running phase: update
[2019-02-03 16:24:04,599]    INFO      Create resource records for section "test1234.entroserv.de"
[2019-02-03 16:24:07,241]    INFO      add (new) A for test1234.entroserv.de : 92.60.36.246
[2019-02-03 16:24:08,273]    INFO      delete A for test1234.entroserv.de : 1.2.3.4

Mehrere Einträge können mit Komma getrennt angegeben werden:

python2 -m cryptdomainmgr --update /etc/cryptdomainmgr/inwxcred.conf --config-content $'[domain:test1234.entroserv.de] \n handler=dnsuptools/inwx \n ip4=1.2.3.4,5.6.7.8,auto'

Die Einträge werden einzeln angelegt. Als letztes werden wieder alte Einträge entfernt:

[2019-02-03 16:35:18,958]    INFO      Interpreting config sections
[2019-02-03 16:35:18,958]    INFO        - cdm
[2019-02-03 16:35:18,959]    INFO        - domain
[2019-02-03 16:35:19,108]    INFO      Running phase: update
[2019-02-03 16:35:19,108]    INFO      Create resource records for section "test1234.entroserv.de"
[2019-02-03 16:35:20,947]    INFO      add (exists) A for test1234.entroserv.de : 1.2.3.4
[2019-02-03 16:35:21,774]    INFO      add (new) A for test1234.entroserv.de : 5.6.7.8
[2019-02-03 16:35:22,878]    INFO      add (new) A for test1234.entroserv.de : 92.60.36.246
[2019-02-03 16:35:24,237]    INFO      delete A for test1234.entroserv.de : 6.7.8.9

Soll ein Eintrag hinzugefügt werden, ohne schon vorhandene Einträge zu entfernen, muss der +=-Operator verwendet werden:

python2 -m cryptdomainmgr --update /etc/cryptdomainmgr/inwxcred.conf --config-content $'[domain:test1234.entroserv.de] \n handler=dnsuptools/inwx \n ip4+=6.5.4.3'

Die Ausgabe bestätigt, es wird nichts gelöscht:

[2019-02-03 16:39:50,893]    INFO      Interpreting config sections
[2019-02-03 16:39:50,894]    INFO        - cdm
[2019-02-03 16:39:50,894]    INFO        - domain
[2019-02-03 16:39:51,042]    INFO      Running phase: update
[2019-02-03 16:39:51,043]    INFO      Create resource records for section "test1234.entroserv.de"
[2019-02-03 16:39:53,004]    INFO      add (new) A for test1234.entroserv.de : 6.5.4.3

Es ist auch möglich einen Eintrag einfach nur zu löschen bzw. sicherzustellen, dass für diese Domain kein A-Record hinterlegt ist:

python2 -m cryptdomainmgr --update /etc/cryptdomainmgr/inwxcred.conf --config-content $'[domain:test1234.entroserv.de] \n handler=dnsuptools/inwx \n ip4=none'

Aktualisiert: