Djbdns
Aus Gentoo Linux Wiki
| 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
