Djbdns

Aus Gentoo Linux Wiki

Wechseln zu: Navigation, Suche
Dieser Artikel ist Teil der HOWTO Sammlung.
Installationsmethoden LiveCDs Kernel & Hardware Laptops & Notebooks Portage System Netzwerke & Services X Software Anderes alphabetischer HOWTO Index


Inhaltsverzeichnis

[Bearbeiten] Einleitung

In diesem Artikel wird beschrieben, wie der DNS-Server "djbdns", der eine Alternative zu "bind" ist, installiert und konfiguriert wird. Die Ausführungen beruhen auf der Version djbdns-1.05-r17. djbdns gilt als sicherer als bind. Ein weiterer Vorteil ist, dass er extrem schlank ist. Auf meinem System dauert der emerge von djbdns und daemontools nur 45 Sekunden. Auf die Problematik des "Zonentransfers" zwischen primary und secondary DNS-Server will ich hier nicht eingehen. Folgendes Szenario wird zu Grunde gelegt:

LAN                                        DMZ       Internet
10.1.1.10       10.1.1.1                   10.1.2.1  88.88.88.1
Client -------> DNS-1 (intern) ---------------> DNS-2 -----------> ...
                DNS-cache für Clients           DNS-cache für DNS-1
                DNS-authoritativ für            DNS-autoritativ für 
                  "intern.example.com"            example.com"
                  für interne Anfragen            für externe Anfragen

DNS-1 dient sowohl als DNS-cache als auch als authoritativer DNS-Server für die Zone "intern.example.com". Da er selbst keine Internetverbindung hat, leitet er alle DNS-Anfragen, die sich nicht auf "intern.example.com" beziehen, an DNS-2 weiter. DNS-2 ist ein DNS-cache für Anfragen von DNS-1. Er kann so konfiguriert werden, dass er sie selbst rekursiv auflöst oder an einen öffentlichen DNS-Serer forwardet. Zusätzlich ist er authoritativer DNS-Server für die Zone "example.com" für Anfragen aus dem Internet. In der Praxis würde man aus Sicherheitsgründen die Funktionalität des authoritativen DNS-Servers auf einen separaten Server legen.

[Bearbeiten] Installation

Code: Installation von djbdns und daemontools
echo "net-dns/djbdns doc" >> /etc/portage/package.use
echo "sys-process/daemontools doc"  >> /etc/portage/package.use
emerge -av net-dns/djbdns


Die Konfiguration kann sehr komfortabel mit Hilfe des Scripts "djbdns-setup" durchgeführt werden. Im folgenden will ich jedoch die manuelle Installation beschreiben, weil man hierbei die Zusammenhänge besser erkennen kann.

Bei der Installation werden drei Benutzer automatisch angelegt, die bei den folgenden Anweisungen angegeben werden müssen. Die Namen der Benutzer sind: dnscache, tinydns und dnslog.

Code: spezielle Benutzer für dnscache und tinydns
grep dns /etc/passwd # dnscache, tinydns und dnslog


[Bearbeiten] DNS-1 (intern)

Hier werden sowohl der DNS-cache als auch der authoritative DNS für die interne DNS-Zone eingerichtet. Beide verwenden Port 53, sind jedoch an unterschiedliche Netzwerkinterfaces gebunden. Interessanter Weise ist der authoritative DNS-Dämon ("tinydns") nur an das Loopback-Interface gebunden, also i.A. an 127.0.0.1. Das heißt, die Clients können keine direkten Anfragen an den authoritativen DNS-Server ("tinydns") stellen. Die Clients adressieren prinzipiell nur den DNS-cache ("dnscache"), der an das LAN-Interface, also 10.1.1.1. gebunden ist. Dieser entscheidet dann, ob er die Anfrage an tinydns weiterreicht (bei diesem Vorgang ist dnscache der Client und tinydns der Server). Dies tut er nur dann, wenn sich die Anfrage auf eine von tinydns gehostete Zone bezieht, also auf "intern.example.com" bzw. "1.1.10.in-addr.arpa". Alle anderen Anfragen werden weitergeleitet an DNS-2. Wie der Name schon sagt, werden Anfragen gecacht, so dass das Ergebnis bei der nächsten Anfrage sofort an den Client übermittelt werden kann.

[Bearbeiten] dnscache

Ich plädiere dafür, das Basisverzeichnis unterhalb von /etc statt /var einzurichten. /var kann sich auf einem anderen physikalischen Medium befinden, das beim Booten hineingemountet wird (s. /etc/fstab). Falls der mount aus irgendeinem Grunde fehlschlägt, hätte man keine DNS-Funktionalität zur Verfügung. Dagegen liegt /etc i.A. direkt auf der Root-Partition.

Theoretisch können mehrere dnscaches auf einem Server installiert werden, wobei jeder dnscache ein eigenes Netzwerkinterface benötigt, an das er gebunden wird. Wenn der dnscache nur vom Rechner selbst in Anspruch genommen werden soll, kann er ans Loopbackinterface gebunden werden (127.0.0.1). In diesem Falle müsste der tinydns an 127.0.0.2 gebunden werden. Im Allgemeinen wird man den dnscache jedoch an ein oder mehrere externe Interfaces binden. Für jede dnscache-Instanz wird ein separates Basis-Verzeichnis angelegt, das sinnvoller Weise nach der IP-Adresse des Interfaces benannt wird. Ich verwende im folgenden die Variablen $CACHE1_IP für DNS-1 und $CACHE2_IP für DNS-2 (s. Skizze oben).

CACHE1_IP=10.1.1.1

[Bearbeiten] dnscache Basisverzeichnis

Code: dnscache Basisverzeichnis einrichten
mkdir /etc/dnscache
dnscache-conf dnscache dnslog /etc/dnscache/$CACHE1_IP $CACHE1_IP
# dnscache = User für dnscache
# dnslog   = User fürs logging
# /etc/dnscache/$CACHE1_IP = Basisverzeichnis für den dnscache
# $CACHE1_IP = IP-Adresse des LAN-Interfaces, an das dnscache gebunden werden soll
# Sie wird automatisch hier eingetragen: /etc/dnscache/$CACHE1_IP/env/IP


[Bearbeiten] daemontools

dnscache und tinydns werden über die sog. daemontools gestartet. Dies ist eine Art "Superdämon", der die in seine Obhut gestellten Dämonen startet und ständig überprüft, ob sie gestartet bleiben. Die daemontools setzen voraus, dass es das Verzeichnis /service gibt und überwachen alle Dämonen, auf die es einen Link in diesem Verzeichnis gibt.

Code: Service-Verzeichnis anlegen
mkdir /service


Der Link muss auf das Basisverzeichnis des zu überwachenden Dämons zeigen, also auf /etc/dnscache/$CACHE1_IP.

Code: Link erstellen
ln -s /etc/dnscache/$CACHE1_IP /service/dnscache_$CACHE1_IP


Code: daemontools starten
/etc/init.d/svscan start
rc-update add svscan default # ins Default Runlevel aufnehmen


Leider sind die daemontools schlecht dokumentiert, daher im folgenden die wichtigsten Optionen.

svc -u /service/dnscache_$CACHE1_IP # "up" 
svc -d /service/dnscache_$CACHE1_IP # "down"
svc -t /service/dnscache_$CACHE1_IP # "term" (=restart)

[Bearbeiten] Überprüfungen

Code: Überprüfungen
ps aux | grep svscan #  svscan gestartet?
netstat -tulpen | grep dnscache # tcp- und udp- Port 53 geöffnet und an $CACHE1_IP gebunden?
svstat /service/dnscache_$CACHE1_IP # was sagt die Überwachung der daemontools?


[Bearbeiten] Die Datei "@"

In der Datei "@" stehen standardmäßig die IP-Adressen der DNS-Root-Server. Da der DNS-1 keinen Zugriff aufs Internet hat, müssen die Einträge gelöscht, bzw. auskommentiert und durch die IP-Adresse des dnscaches auf DNS-2 ersetzt werden.

Datei: /etc/dnscache/$CACHE1_IP/root/servers/@
10.1.2.1 # interne IP-Adresse des DNS-2 in der DMZ


[Bearbeiten] zugelassene IPs/Subnetze

Sodann muss dnscache mitgeteilt werden, welche IP-Adressen bzw. Subnetze seinen Dienst in Anspruch nehmen dürfen. dnscache prüft hierzu den Inhalt des Verzeichnisses /etc/dnscache/$CACHE1_IP/root/ip/. Alle Adressen, zu denen es eine gleichnamige Datei gibt, werden zugelassen. Der Inhalt der Datei ist beliebig, es kommt nur auf den Dateinamen an!

Code: Datei(en) für zugelassene Subnetze/IPs erstellen
touch /etc/dnscache/$CACHE1_IP/root/ip/10.1.1 # entspricht dem Subnetz 10.1.1.0/24


Leider ist es nicht möglich, spezielle Subnetze direkt anzugeben, z.B. 10.1.0.0/22 (255.255.252.0). In diesem Fall muss der IP-range in Form einzelner Dateien angegeben werden.

Code: Subnetz 255.255.252.0 "auflösen"
touch /etc/dnscache/$CACHE1_IP/root/ip/10.1.{0,1,2,3}


[Bearbeiten] DNS-Zonen

dnscache muss noch wissen, welche DNS-Anfragen an den authoritativen DNS-Server tinydns übergeben werden sollen. Für jede gehostete DNS-Zone muss eine gleichnamige Datei erstellt werden. Inhalt der Datei muss die Bind-IP-Adresse des tinydns sein, also i.A. "127.0.0.1". Diese Art der Konfiguration ist in der Tat gewöhnungsbedürftig. Auf der anderen Seite erhöht die "Zerstückelung" der Konfigurationsinformationen die Sicherheit und dies ist eines der wichtigsten Kriterien!

Code: gehostete DNS-Domänen, deren Auflösung an tinydns übergeben wird
echo "127.0.0.1" > /etc/dnscache/$CACHE1_IP/root/servers/intern.example.com
echo "127.0.0.1" > /etc/dnscache/$CACHE1_IP/root/servers/1.1.10.in-addr.arpa # Reverse-Lookup-Zone


[Bearbeiten] tinydns

Analog zum dnscache können ein oder mehrere Instanzen eingerichtet werden. Pro Instanz wird ein Basisverzeichnis angelegt. Im Allgemeinen kommt man mit einer Instanz aus.

Ich verwende im folgenden die Variablen $TINY1_IP für DNS-1 und $TINY2_IP für DNS-2 (s. Skizze oben).

TINY1_IP=127.0.0.1

[Bearbeiten] Basisverzeichnis

Code: tinydns Basisverzeichnis einrichten
mkdir /etc/tinydns
tinydns-conf tinydns dnslog /etc/tinydns/$TINY1_IP/ $TINY1_IP
# tinydns  = User für tinydns
# dnslog   = User fürs logging
# /etc/tinydns/$TINY1_IP = Basisverzeichnis für tinydns
# $TINY1_IP = IP-Adresse des Interfaces, an das tinydns gebunden wird.
# Sie wird automatisch hier eingetragen: /etc/tinydns/$TINY1_IP/env/IP


[Bearbeiten] Link für daemontools

Code: Link erstellen
ln -s /etc/tinydns/$TINY1_IP /service/tinydns_$TINY1_IP
ls -la /service  # tinydns -> /etc/tinydns


[Bearbeiten] forwardonly-Flag

Da der dnscache auf dem internen DNS-Server selbst keine rekursive DNS-Auflösung vornimmt, sondern alle Anfragen an den vorgelagerten DNS-Server weiterleitet, muss das forwardonly-Flag gesetzt werden:

Code: forwardonly-Flag setzen
echo "1" > /etc/dnscache/$CACHE1_IP/env/FORWARDONLY


[Bearbeiten] Überprüfungen

Code: weitere Überprüfungen
svstat /service/*  # tinydns müsste von den daemontools automatisch gestartet werden
netstat -tulpen | grep tiny # udp-Port 53 an $TINY1_IP gebunden?


[Bearbeiten] DNS-Records

DNS-Einträge können direkt in die Datei /etc/tinydns/root/data erfolgen oder über spezielle Scripte. Vom Programmautor von djbdns wird empfohlen, die Scripte zu verwenden, weil hierbei ein Syntaxcheck erfolgt.

Code: DNS-Einträge
cd /etc/tinydns/$TINY1_IP/root
./add-ns intern.example.com  10.1.1.1    # NS-record für ns1.intern.example.com
./add-ns 1.1.10.in-addr.arpa 10.1.1.1    # NS-record für ns1.1.1.10.in-addr.arpa
./add-mx intern.example.com 10.1.1.5        # MX-record für Domäne intern.example.com
./add-host  mail.intern.example.com   10.1.1.5  # A-record für mail.intern.example.com
./add-host  fritz.intern.example.com  10.1.1.6  # A-record für fritz.intern.example.com
./add-alias www.intern.example.com    10.1.1.6  # CNAME-record www -> fritz


Daraus resultiert folgende Datei:

Datei: /etc/tinydns/$TINY1_IP/root/data
.intern.example.com:10.1.1.1:a:259200
.1.1.10.in-addr.arpa:10.1.1.1:a:259200
@intern.example.com:10.1.1.5:a::86400
=mail.intern.example.com:10.1.1.5:86400
=fritz.intern.example.com:10.1.1.6:86400
+www.intern.example.com:10.1.1.6:86400


Nach jeder Änderung der Datei (direkt oder über Scripte) muss "make" aufgerufen werden. Hierbei wird die Datei "data.cdb" erstellt, die für den schnellen Datenzugriff von tinydns optimiert ist. Nur "data.cdb" wird von tinydns für die DNS-Auflösung verwendet.

Code: make
# /etc/tinydns/$TINY1_IP/root/make (..original funktioniert leider nicht, besser wie D.J.Bernstein vorgeschlagen. (geändert von Spezi2u)

cd /etc/tinydns/$TINY1_IP/root/
/usr/bin/tinydns-data


[Bearbeiten] Restarten von dnscache und tinydns

Es gibt zwei Möglichkeiten, wobei im Zweifelsfall der restart des svscan vorzuziehen ist.

Code: Restart des dnscache
# Dämon einzeln restarten:
svc -t /service/dnscache_$CACHE1_IP   # nur dnscache restarten
svc -t /service/tinydns_$TINY1_IP   # nur tinydns  restarten
# alle unterhalb von /service/ verlinkten Dämonen restarten
/etc/init.d/svscan restart


[Bearbeiten] Konfiguration der /etc/resolv.conf

Auf DNS-1 und den Clients sollte die IP-Adresse des dnscaches auf DNS-1 eingetragen werden. Die Clients adressieren also prinzipiell nur den dnscache, nicht den authoritativen tiyndns, der auf 127.0.0.1 liegt und daher von außen nicht erreichbar ist.

Datei: /etc/resolv.conf
nameserver 10.1.1.1
search intern.example.com
domain intern.example.com


[Bearbeiten] DNS-2 (extern)

Die Konfiguration von dnscache und tinydns kann analog zu DNS-1 erfolgen, jedoch sind folgende Unterschiede zu beachten:

[Bearbeiten] bind-adressen

CACHE2_IP=10.1.2.1
TINY2_IP=88.88.88.1

Der tinydns wird in diesem Falle an das externe Interface gebunden, da es keinen Sinn ergeben würde, auf dem externen Interface einen dnscache zur Verfügung zu stellen.

[Bearbeiten] Datei "@"

Ein weiterer Unterschied ist der Inhalt der Datei "@". Es gibt zwei Möglichkeiten:

1) Die Datei enthält die IP-Adressen der DNS-Root-Server,
die nach der Installation standardmäßig dort eingetragen sind.
2) Die Datei enthält die IP-Adresse(n) eines oder besser mehrerer
schneller öffentlicher DNS-Server.

[Bearbeiten] forwardonly-Flag

Wenn man sich für 2) entscheidet, muss das forwardonly-Flag gesetzt werden:

Code: forwardonly-Flag setzen
echo "1" > /etc/dnscache/$CACHE2_IP/env/FORWARDONLY


Wenn man sich für 1) entscheidet, kann man die Datei "FORWARDONLY" löschen, falls sie existiert oder eine "0" dort eintragen:

Code: forwardonly-Flag zurücksetzen
echo "0" > /etc/dnscache/$CACHE2_IP/env/FORWARDONLY


[Bearbeiten] zugelassene IPs/Subnetze

Der dnscache auf dem DNS-2 soll nicht direkt von den Clients, sondern nur vom dnscache des DNS-1 adressiert werden können.

Code: Datei für zugelassene IP-Adresse erstellen
touch /etc/dnscache/$CACHE2_IP/root/ip/10.1.1.1 # IP-Adresse von DNS-1


[Bearbeiten] DNS-Einträge erstellen

Code: DNS-Einträge
cd /etc/tinydns/$TINY2_IP/root
./add-ns example.com           88.88.88.1   # NS-record für ns1.example.com
./add-ns 88.88.88.in-addr.arpa 88.88.88.1   # NS-record für ns1.88.88.88.in-addr.arpa
./add-mx example.com           88.88.88.5   # MX-record für Domäne example.com
./add-host mail.example.com    88.88.88.5   # A-record für mail.example.com
./add-host  www.example.com    88.88.88.6   # A-record für www.example.com
make
# ein anschließender restart/reload des tinydns ist normaler Weise nicht notwendig


[Bearbeiten] Tests

Optimaler Weise sollten die Tests auf den Clients durchgeführt werden. Da dort vermutlich djbdns mit den dazugehörigen Tools nicht installiert ist, können Vorabtests auch auf dem DNS-1 durchgeführt werden, wenn die /etc/resolv.conf identisch mit der auf den Clients ist.

Code: Test: externer DNS-Name
dnsip www.google.de # externen DNS-Namen auflösen
# (1) resolver schaut in /etc/resolv.conf nach IP des dnscaches
# (2) resolver schickt rekursive DNS-Anfrage an 10.1.1.1:53 (=dnscache)
# (3) dnscache prüft, ob www.google.de von tinydns gehostet wird: 
#     darüber entscheidet der Inhalts von /etc/dnscache/$CACHE1_IP/server/
# (4) wenn nicht, holt dnscache sich den/die DNS-forwarder bzw. -Root-Server
      aus der Datei /etc/dnscache/$CACHE1_IP/root/server/@
# (5) prüfen des Inhalts der Datei /etc/dnscache/$CACHE1_IP/env/FORWARDONLY:
      bei "1": forward der rekursiven DNS-Anfrage an den DNS-forwarder.
      bei "0": rekursive DNS-Auflösung wird selbst durchgeführt.


Code: Test: interner DNS-Name
dnsip fritz.intern.example.com # internen DNS-Namen auflösen
# (1) resolver schaut in /etc/resolv.conf nach IP des dnscaches
# (2) resolver schickt rekursive DNS-Anfrage an 10.1.1.1:53 (=dnscache)
# (3) dnscache prüft, ob intern.example.com von tinydns gehostet wird: 
# (4) wenn ja, schickt er eine iterative DNS-Anfrage an tinydns auf 127.0.0.1


Code: Test: reverse Lookup
dnsname 10.1.1.5    # DNS-Namen einer IP-Adresse finden


Code: Test: cache-Funktion
time dnsip www.yahoo.de # Zeitmessung: wie lange dauert die Auflösung?
time dnsip www.yahoo.de # wie lange dauert die Auflösung beim zweiten Aufruf?


SK, Ostfildern, 20.7.2006

'Persönliche Werkzeuge