DNS-Server mit Bind

From Linuxwiki
Revision as of 11:20, 5 June 2022 by Sunflower (talk | contribs)
Jump to navigation Jump to search

Definition DNS

Domain Name System: Auflösung von Hostnamen in IP-Adressen und umgekehrt.

Möglichkeiten der Namensauflösung

a) lokal
Eine Möglichkeit der Namensauflösung ist eine Eintragung von Hostnamen und zugehörigen IP-Adressen in die /etc/hosts.
Dies ist aber allenfalls ein temporärer Workaround, z.B. für Hosts in abgeschotteten Umgebungen.

b) zentral
In größeren Netzwerken sollte dies zur Entlastung der Clients und Reduzierung des Konfigurationsaufwandes zentral durch (einen) Nameserver erfolgen. Die Namensauflösung sollte vorwärts (Name -> IP-Adresse) und rückwärts (IP-Adresse -> Name) funktionieren. Als zugehörige Software wird hier BIND in der aktuellen Version (9) besprochen.

Varianten

  • Caching-Only-Nameserver: Der Nameserver verwaltet selbst keine Zonen, sondern cached nur Informationen anderer Nameserver zwischen.
  • Stand-Alone-Nameserver: Ein DNS-Server hält alle Zonendaten alleine vor.
  • Master-Slave: Zur Lastverteilung oder Ausfallsicherheit. Der Master überträgt die Zonendaten an den/die Slave(s).

Einrichten des Servers

In unserem Beispiel wird ein Standalone-Server besprochen.

Installation der Software

# aptitude install bind9


Konfiguration des Servers

Die Konfigurationsdateien im Ordner /etc/bind editieren.

Achtung: Kommentarzeichen in den Bind-config-files können „;“ „//“ oder „#“ sein. In der named.conf ist ; als Kommentar nicht erlaubt!

Idealerweise muss man in der named.conf nichts verändern, sondern nur weitere Dateien einsourcen:

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

Beispiel-Config vom Bind für die lokale Domain example.de:

In der named.conf.local werden sogenannte Zonefiles eingetragen:

zone “example.de“ { type master; file “/etc/bind/db.example“; };

Falls der Nameserver außerhalb der eigenen Domain auf andere definierte Nameserver zugreifen muss, muss zusätzlich ein Forwarder in die named.conf.options eingetragen werden (der Eintrag muss innerhalb des options-Abschnitts erfolgen):

forwarders {
 10.0.1.4;
};

wobei 10.0.1.4 i.d. Fall die IP des übergeordneten Nameservers ist.

Als nächstes wenden wir uns den Hosteinträgen für das lokale Netz zu:

db.example.de als Kopie von db.local anlegen:

; Zonenfile fuer example.de ; $TTL 604800

 example.de.      IN      SOA     server. root.example.de. (
  	                        1         ; Serial
   	                     	604800         ; Refresh
     	                        86400         	; Retry
               	        2419200        ;  Expire
              	                600 )     	; Negative Cache TTL (default 604800)
; Nameserver
IN      NS      server.example.de.
; Rechnername zu zugehoeriger IP-Adresse
server		IN       A        <IP>
client1		IN	A	<IP>
client2		IN	A	<IP>

..... (weitere Rechner)

router		IN	A	192.168.100.254

Beachte immer den Punkt am Ende des FQDN/ der Domain ! (z.B. server.example.de.)

TTL (Time to live) sollte ganz oben im Zonefile stehen und drückt aus, wie lange sich ein abgefragtes Objekt im Cache befinden darf (Default: 1 Woche, ist i.d.R. zu lang).

Weitere Parameter:

  • serial /seriell
 Seriennummer, die nach jeder Änderung hochgezählt werden sollte (Zonentransfer an eventuelle Slaves)
  • refresh = aktualisieren
 Intervall, in dem sich die Slaves mit dem Master abstimmen sollen, ob sich an der Seriennummer etwas geändert hat
  • retry = wiederholen
Wenn der Master nicht antwortet, versucht es der Slave nach Ablauf dieser Zeit nochmal.
  • expire = ablaufen
Antwortet der Master innerhalb dieser Zeit nicht, erkennt der Slave, dass seine Zonendaten nicht mehr aktuell sind und stellt sie nicht mehr zur Verfügung
  • Negative cache TTL
Minimum, in dem negative Antworten (z.B. NS nicht erreicht) im Cache gehalten werden. Es empfiehlt sich, den Default von 1 Woche auf einen geringeren Wert (z.B. 10 Minuten) herunterzudrehen, weil es sonst im Fehlerfall sehr lange dauern kann, bis der Cache expired.

Es besteht auch die Möglichkeit, einem Host 2 Namen zuzuweisen. Der Eintrag sieht dann folgendermaßen aus:

ujulala		IN	CNAME	client1 

-> ujulala und client1 sind ein und derselbe Rechner.

Überprüfung auf Fehler

Mit named-checkconf kann man die named.conf auf Fehler überprüfen.

Mit named-checkzone lassen sich die Zonenfiles auf Syntax checken

# named-checkzone example.de /etc/bind/db.example

service named restart startet den Nameserverdienst neu.

Reverse lookup einrichten

Reverse lookup: dient zur Auflösung von IP-Adressen in Namen.

Wie wird's gemacht?

In die named.conf muss eingetragen werden, wo die Datei fürs Reverse-Lookup zu finden ist.

zone "1.168.192.in-addr.arpa" {
   type master;
   file "/etc/bind/named.rev";
};

in-addr.arpa ist die Domain für reverse lookup (unabhängig vom selbst gewählten Domainnamen)

Das Format der Datei named.rev ist:

; BIND data file for local loopback interface
;
$TTL    600
@       IN      SOA     server.example.de. root.example.de. (
                             1          ; Serial
                        604800          ; Refresh
                         86400          ; Retry
                       2419200          ; Expire
                        604800 )        ; Negative Cache TTL
;
               IN      NS      server.example.de.

Die Einträge der Hosts sehen wie folgt aus:

<Hostanteil der IP>	IN	PTR	<FQDN>		also z.B.
2               IN      PTR     client1.example.de.

Hier wird also nur der Host-IP-Anteil eingetragen. Bei einer 192.168.1.2/24-Adresse ist das also nur die „2“. Beachte: statt „A (Host)“ muss hier „PTR“ (Pointer) stehen.

Und weil es mit ipv6 gleich noch mehr Spaß macht, hier noch ein Konfigurationsbeispiel für die IPs 2001:780:11b::1/48 und 2001:780:11b::2/48

;
; 2001:780:11b/48
;
; Zone file built with the fpsn.net IPv6 Reverse DNS zone builder
; http://tools.fpsn.net/ipv6-inaddr
;
$TTL 3d ; Default TTL (bind 8 needs this, bind 9 ignores it)
@       IN SOA server.example.de. hostmaster.example.de. (
               201009301       ; Serial number (YYYYMMdd)
               24h             ; Refresh time
               30m             ; Retry time
               2d              ; Expire time
               1d              ; minimum-ttl (bind 8 ignores this, bind 9 needs it)
)
; Name server entries
@                                IN     NS    server.example.de.
; IPv6 PTR entries

; Subnet #2
$ORIGIN b.1.1.0.0.8.7.0.1.0.0.2.ip6.arpa.

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN      PTR     server.example.de. 
2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN      PTR     client1.example.de.

Auch die named.rev lässt sich mit named-checkzone testen. Bind nochmal starten.

Überprüfung der Funktionalität

Auf dem Nameserver in der Datei /etc/resolv.conf folgenden Eintrag erstellen:

search example.de
nameserver 127.0.0.1
nameserver ::1

Eine lokale Abfrage starten, z.B. mit

# dig @localhost server.example.de

Konfiguration der Clients

a) Linux/BSD

/etc/resolv.conf anpassen:

search <domainname>
nameserver <IP>

In der Datei /etc/nsswitch.conf kontrollieren, ob die Zeile

hosts:          files dns

vorhanden ist.

b) Windows Systemsteuerung -> Netzwerkverbindungen (LAN) -> Eigenschaften -> Allgemein -> TCP/IP -> Eigenschaften -> DNS-Server: IP eintragen

Dann unter „Erweitert“ den Reiter DNS auswählen. Unter „Diese DNS-Suffixe anhängen“ den Domainnamen (unter Windows ist das in dem Fall eine Arbeitsgruppe) eintragen, also in unserem Beispiel example.de.

Diese Einstellungen entfallen i.d.R., wenn DHCP benutzt wird.

Security

Aus Sicherheitsgründen ist es ratsam, den bind-Prozess in einer eigenen chroot-Umgebung laufen zu lassen, d.h. In einem Unterverzeichnis, von dem aus es nicht möglich ist, ins Hauptverzeichnis (/) zu gelangen.

Beispiel: Das Konfigurationsverzeichnis soll nach /var/lib/bind/etc/bind/ verschoben werden. Aus Sicht des Users named ist das /-Verzeichnis dann /var/lib/bind. In der chroot-Umgebung müssen sich die Unterverzeichnisse

dev  etc  usr  var

befinden. Dorthin werden folgende Dateien kopiert/angelegt:

|-- dev
|   |-- core -> /proc/kcore
|   |-- full
|   |-- kmem
|   |-- loop0
|   |-- loop1
|   |-- ...
|   |-- mem
|   |-- null
|   |-- port
|   |-- ram -> ram1
|   |-- ram0
|   |-- ram1
|   |-- ram...
|   |-- random
|   |-- tty
|   |-- urandom
|   `-- zero

Diese Devices nicht kopieren, sondern mit

MAKEDEV std

anlegen.

|-- etc
|   |-- apparmor.d
|   |   |-- force-complain
|   |   `-- usr.sbin.named
|   |-- bind
|   |   |-- 192.168.99.zone
|   |   |-- db.0
|   |   |-- db.127
|   |   |-- db.255
|   |   |-- db.empty
|   |   |-- db.local
|   |   |-- db.root
|   |   |-- named.conf
|   |   |-- named.conf.local
|   |   |-- named.conf.options
|   |   |-- example.de
|   |   |-- reverse-2001-780-11b_48.IP6.ARPA
|   |   |-- ... (weitere Zonendateien)
|   |   |-- rndc.key
|   |   `-- zones.rfc1918
|   |-- group
|   |-- localtime
|   `-- ufw
|       `-- applications.d
|           |-- bind9
|           `-- postfix

|-- usr
|    -- sbin
|       |-- dnssec-dsfromkey
|       |-- dnssec-keyfromlabel
|       |-- dnssec-keygen
|       |-- dnssec-signzone
|       |-- named
|       `-- rndc

|-- var
   |-- cache
   |   `-- bind
   |-- log
   |-- run
       `-- bind
           `-- run

Damit das Startscript weiß, ob und wo bind chrooted gestartet werden muss, muss ihm der Parameter -t <pfad> mitgegeben werden. Dies passiert in der Datei /etc/default/bind9:

# run resolvconf?
RESOLVCONF=yes

# startup options for the server
OPTIONS="-u bind -t /var/named"

In der Prozessliste erscheint dann auch o.g. Parameter:

bind      2331  0.0  2.0  53920 21292 ?   	Ssl  Apr28   1:36 /usr/sbin/named -u bind -t /var/named

Überprüfen der Funktionalität

Läuft der entsprechende Prozess?

# ps auxw| grep bind

Befehle zur Namensauflösung:

host (-a) <IP> oder <hostname> 

zur Namensauflösung

nslookup <IP> oder <hostname>

tool zur Namensauflösung (Paketname: dnsutils)

dig <IP> oder <FQDN>

reverse lookup mit dig -x ... dasselbe, aber etwas ausführlicherer Output

Noch mehr Security

TSIG

Falls man ein Master-Slave-Zonenkonstrukt am Start hat, empfiehlt es sich, die Remotesteuerung per rndc nur mit rndc-key zu erlauben. Nur wer im Besitz des Keys ist, wird als Quelle für Zonentransfers akzeptiert.

ergänzen in der named.conf:

controls {   inet 127.0.0.1 port 953
             allow { 127.0.0.1; } keys { "rndc-key"; };
 };

include "/etc/bind/rndc.key";

den rndc-key erzeugen mit:

dnssec-keygen -a hmac-md5 -b <bit-length> -n HOST <key-file-name>

Zonentransfer nur für bestimmten Key erlauben:

zone "example.de" {
       type master;
       file "/etc/bind/example.de";
       allow-transfer {  key TRANSFER; };
};

rndc.conf und rndc.key sollten nur von root gelesen werden dürfen!

(Näheres unter https://www.oreilly.com/library/view/dns-bind/0596004109/ch03s04.html )

Certification Authority Authorization (CAA)

Im Prinzip kann jede CA für jede beliebige Domain Zertifikate ausstellen, was in der Vergangenheit auch schon passiert ist. Ein Gegenmittel ist ein CAA-Eintrag im Zonefile.

example.de.  CAA 128 issue "letsencrypt.org"

Eine CA, die sich an die Standards hält, sollte vor dem Erstellen eines Zertifikats an Hand des CAA-Eintrags im DNS prüfen, ob sie überhaupt berechtigt ist.

Weiteres unter

https://blog.qualys.com/ssllabs/2017/03/13/caa-mandated-by-cabrowser-forum

SSH Key Fingerprints im Zonefile

Wer kennt nicht die (meist unbeachteten) Abfragen, die beim 1. Einloggen per ssh bei einem neuen Server gestellt werden?

The authenticity of host 'www.example.de (47.11.8.15)' can't be established.
ECDSA key fingerprint is SHA256:dEGnbSELHvvr9Tzf6gHXuL3LL+uQsoC9rFz1clHRptM.
Are you sure you want to continue connecting (yes/no)?

Abhilfe verschafft hier das Hinterlegen des Fingerprints des ssh-Keys im DNS:

root # ssh-keygen -r www -f /etc/ssh/ssh_host_ed25519_key.pub >> example.de 

Nun noch das Zonefile reloaden und der SSH Key wird beim Einloggen via DNS überprüft.

Nähere Infos hier:

https://simon.butcher.name/archives/2011/01/16/SSH-key-fingerprints-in-DNS