Bind DNS für Letsencrypt aufsetzen
Möchten man die Letsencrypt (LE) Zertifikate auch in einem internen Netzwerk hinter einer Firewall verwenden kann man die sogenannte HTTP Validation nicht nutzen. Bei dieser am meisten verwendeten Variante startet man den Prozess von dem Webserver aus und es wird von Letsencrypt über HTTP geprüft “ob man den Server auch kontrolliert”. Hinter einer Firewall geht das natürlich nicht. Hierfür gibt es die DNS Validierung.
Bei der DNS Validierung wird man beim Abruf eines Zertifikates aufgefordert im Domain Name System (DNS) einen bestimmten Eintrag hinzuzufügen. Hat man das gemacht und LE konnte diesen Eintrag prüfen bekommt man das Zertifikat. Natürlich kann man diese Einträge auch manuell über die DNS Administration hinzufügen aber das ist natürlich bei den regelmässigen Erneuerungen etwas mühselig. Deshalb gibt es verschiedene Methoden dies zu automatisieren. Diese hängen natürlich vom DNS Provider ab. Die grossen Provider bieten hierfür eine Schnittstelle an. Leider ist mein bisheriger nicht dabei. Da ich mich sowiso mal mit einem DNS Server beschäftigen wollte eine gute Begründung einen eigenen aufzusetzen. Und da dieser ja nur für eine interne Domaine “verantwortlich” ist und mein interner DNS Server ja auf meiner pfsense Firewall läuft braucht er nicht besonders mächtig und ausfallsicher sein.
Nach Rücksprache mit JP Mens (“I adore DNS..) fiel meine Wahl auf Bind 9 und der Prozess ist eigentlich recht einfach. In Anlehnung an dieses Dokument habe ich einen sogenannten “Authoritive Server” aufgesetzt und die dynamische Änderung der DNS Einträge eingerichtet
- Installation Bind
- Konfiguration der Domaine
- dynamische Änderungen zulassen
Im folgenden verwende ich den Namen “internal_domain” als Platzhalter der internen Domaine für die der DNS Server die LE Anfragen beantworten soll.
Installation
sudo apt-get update
sudo apt-get install bind9 bind9utils bind9-doc
Wir wollen keinen DNS Server “für die Welt” bereitstellen sondern nur für unsere eigene Domaine arbeiten
vi /etc/bind/named.conf.options
recursion no;
allow-transfer { none; };
Für welche Domaine “arbeiten wir” und wo liegen die Daten?
vi /etc/bind/named.conf.local
zone "internal-domain.net" {
type master;
file "/etc/bind/zones/db.internal-domain.net";
};
Wir starten mit einem Beispiel das wir leicht anpassen müssen
mkdir /etc/bind/zones
cp /etc/bind/db.local /etc/bind/zones/db.internal-domain.net
vi /etc/bind/zones/db.internal-domain.net
internal-net.net IN SOA ip-address.your-dns-server. your-mail.adresse.de. (
named-checkconf
named-checkzone internal-domain.net /etc/bind/zones/db.internal-domain.net
zone internal-domain.net/IN: loaded serial 3
OK
sudo service bind9 restart
Jetzt sollte man den neuen DNS Server etwas fragen können
dig internal-domain.net @ip-addres.your-dns-server
Jetzt gilt es das dynamische Ändern von DNS Einträgen zu konfigurieren. Von all den Beschreibungen fand ich diese hier am besten.
Die Schritte sind
- Erstellen eines Schlüssels.
- Definition das mit diesem Schlüssel bestimmte Einträge in Bind geändert werden dürfen.
- Testen
Den Schlüssel erstellen und mal schauen was drin ist
dnssec-keygen -a HMAC-MD5 -b 512 -n HOST internal-domain-net
Kinternal-domain-net.+157+55477
ls -ls Kinternal-domain-net.+157+55477.*
4 -rw------- 1 root root 120 Jun 10 11:07 Kinternal-domain-net.+157+55477.key
4 -rw------- 1 root root 229 Jun 10 11:07 Kinternal-domain-net.+157+55477.private
more Kinternal-domain-net.+157+55477.private
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: bhqqXRXPygW/DF7.........................Jb64XfiRUqZA==
Dieser Key muss nun unserer Bind Konfiguration hinzugefügt werden und ich lege fest das mit diesem Key TXT Einträge für bestimmte acme_challenges geändert werden dürfen. Mit den Wildcard Zertifikaten bin ich erst mal zurückhaltend. Ob das sinnvoll ist weiß ich noch nicht aber ich plane für verschiedene Serverkategorien verschiedene Schlüssel verwenden zu können. Das kann man auch einfacher haben.
vi /etc/bind/named.conf.local
key "internal-domain.net" {
algorithm hmac-MD5;
secret "vqbhqqXRXPygW/DF7.........................Jb64XfiRUqZA====";
};
zone "internal-domain.net" {
type master;
file "/etc/bind/zones/db.internal-domain.net";
update-policy {
grant internal-domain.net name _acme-challenge.oneofyourserver.internal-domain.net. txt;
};
};
Damit wir gleich auch dynamisch updaten können müssen wir noch die rechte ändern
chown -R bind /etc/bind/zones
So nach einem Neustart von Bind können wir jetzt “von außen” DNS Einträge ändern. Am einfachsten kann man das mit nsupdate testen
nsupdate -v -k Kinternal-doamin-net.+165+53408.key
> server ipaddress.your-dns-server
> zone internal-domain.net
> update add _acme-challenge.oneofyourserver.internal-domain.net. 60 IN TXT "xa4I5BUsvkxYiIr9TRITOCt7yjlx8bftKuTwu23iHq8"
> send
im Logfile sehen wir dann ein
updating zone 'internal-domain.net/IN': adding an RR at '_acme-challenge.oneofyourserver.internal-domain.net' TXT "xa4I5BUsvkxYiIr9TRITOCt7yjlx8bftKuTwu23iHq8"
Ob das ganze auch angekommen ist kann man mit einem
dig '_acme-challenge.oneofyourserver.internal-domain.net TXT @ipaddress.your-dns-server
prüfen.
Als nächstes steht die Konfiguration der internen Server auf dem Plan.