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.

Letsencrypt