Cryptdomainmgr
Unterbrechungsfreie Erneuerung von X.509-Zertifikaten, TLSA-Einträgen und DKIM-Schlüsseln
Projektdaten | |
---|---|
Logo | |
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.
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'