19.5 Domain Name System (DNS) Server
Das Domain Name System ist eines der grundlegenden Dienste im Internet. Seine wichtigste Aufgabe ist die Übersetzung von IP-Adressen in Rechnernamen (einschließlich Domain) und umgekehrt. Prinzipiell sind Rechner- und Domain-Namen nur dazu da, den Benutzern und Systemverwaltern das Leben leichter zu machen. Das Internet käme auch ohne diese Namen aus. Wenn Sie etwas größere lokale Netzwerke zu administrieren haben, werden Sie den Einsatz eines Nameservers schätzen. Dieser sorgt dafür, dass Sie die Clients des Netzwerks nicht mühsam von Hand mit IP-Adressen versehen müssen.
19.5.1 BIND
Sie können einen freien DNS-Server für Linux mit Hilfe von BIND (Berkeley Internet Name Domain) einrichten. Nachfolgend erfahren Sie, wie Sie einen Nameserver für eine eigene Domain einrichten, die entweder weltweite oder private IP-Adressen besitzen kann.
BIND-Konfiguration
Im jetzt beschriebenen Beispiel gibt es zwei Subnetze im lokalen Netz. Sie können anhand dieses Beispiels natürlich BIND auch in einem einfachen lokalen Netz oder einem Netz mit mehr als zwei Subnetzen einrichten, indem Sie die Konfiguration für ein Subnetz weglassen oder sie für ein drittes vornehmen. Die wichtigsten Eckdaten für die Konfiguration sind:
- zwei lokale Netze mit den Adressen 172.30.2.x und 172.30.3.x
- ein Router (router.artemis.home), der die beiden Netze verbindet
- ein nicht permanenter Internetzugang über den Server
- der Server hermes.artemis.home.
Gleichen Sie die Adresse in der folgenden Zeile entsprechend ab mit der IP-Adresse 173.30.2.1 und gleichzeitig mit der dynamischen Adresse hermes.mars.de.
Resolver
Der Resolver verwendet die Dateien /etc/hosts, /etc/host.conf und /etc/resolv.conf. Mit libc6, die in allen Distributionen mittlerweile Standard ist, kommt noch /etc/nsswitch.conf hinzu. Die Konfiguration des DNS-Servers erfolgt in diesem Beispiel in der Reihenfolge, wie sie in /etc/hosts angegeben ist. So können auch Namen, die außerhalb der privaten Domain liegen, ohne Befragen eines externen Nameservers aufgelöst werden.
order hosts, bind
multi on
hosts: files dns
Obwohl in dieser Datei recht viel stehen kann (siehe die Manpage), genügt uns eine einzige Zeile. Diese legt im Prinzip dasselbe fest wie /etc/host.conf. Sie ist nicht nötig auf älteren Systemen, die libc5 verwenden.
Dies sind die wenigen verbleibenden Einträge in /etc/hosts. Auf die Zeile mit 127.0.0.1 können Sie im Prinzip auch noch verzichten. Doch es ist wahrscheinlich effizienter, die häufig gebrauchte Adresse von localhost aus der Datei zu lesen, als sie von einem DNS-Server zu erfragen.
Sparpotential bei Verwendung von UMTS
Der Eintrag hermes.mars.de sorgt dafür, dass kein externer Nameserver gefragt wird, da diesem Namen ja eigentlich keine statische IP-Adresse zugeordnet ist. Dies kann Telefonkosten sparen, wenn Sie zum Beispiel per UMTS ins Internet gehen.
# host database
127.0.0.1 localhost loopback
172.30.2.1 hermes.mars.de
Die private Domain (172.30.x.x) habe ich artemis.home getauft. Der Nameserver-Eintrag dürfte offensichtlich sein. home ist keine offizielle TLD (Top Level Domain), Namenskonflikte mit Servern, die im Internet erreichbar sind, sind also ausgeschlossen.
domain artemis.home
nameserver 172.30.2.1
Die Konfigurationsdatei von BIND
Nachfolgend zeige ich Ihnen den Inhalt der Konfigurationsdatei von BIND, /etc/named.conf. Dieser Name ist fest vorgegeben. Er könnte auch ein Link auf /var/named/conf sein. Frühere Versionen von BIND (vor 8.1) verwendeten die Datei /etc/named.boot.
options {
directory "/var/named";
forward only;
forwarders {
212.227.14.1;
};
};
zone "artemis.home" {
type master;
file "named.artemis.home";
};
zone "2.30.172.in-addr.arpa" {
type master;
file "named.172.30.2";
};
zone "3.30.172.in-addr.arpa" {
type master;
file "named.172.30.3";
};
zone "0.0.127.in-addr.arpa" {
type master;
file "named.127.0.0";
};
zone "." {
type hint;
file "root.cache";
};
Diese Datei besagt Folgendes:
- Alle weiteren Konfigurationsdateien werden in /var/named gefunden.
- Es sind sogenannte Primary-Nameserver für die Zonen artemis.home sowie 172.30.2, 172.30.3 und 127.0.0 (für den Reverse Lookup) vorhanden. Die entsprechenden Konfigurationsdateien sind named.artemis.home, named.173.30.2, named.172.30.3 und named.127.0.0 (frei wählbar).
- Anfragen, die nicht beantwortet werden können, werden an die Systeme weitergeleitet, die in forwarders genannt sind.
- Die Root-Nameserver stehen in root.cache. Diese Datei ist allerdings leer, da alle Anfragen über die forwarders abgewickelt werden.
- Die Option forward only ist notwendig, sonst werden unbekannte Adressen überhaupt nicht aufgelöst.
named.artemis.home enthält alle Namen des lokalen Netzes, inklusive des lokalen Hosts und des Loop Back. Der SOA-Record muss immer vorhanden sein, ebenso der NS-Record. Der Name postmaster.hermes.artemis.home ist der administrative Kontakt, der mit einer real existierenden E-Mail-Adresse postmaster@hermes.artemis.home korrespondiert. In einem offiziellen Netz müsste dies natürlich eine offiziell erreichbare E-Mail-Adresse sein. Meist wird hostmaster@... verwendet.
Die Seriennummer serial ist eine willkürliche Zahl, die bei jeder Änderung hochgezählt werden sollte. Eine gute Möglichkeit ist die hier gezeigte Konvention, das Datum der Änderung (20090502) und eine laufende Nummer aus zwei Ziffern (02) zu verwenden. Das $TTL 86400 gibt an, wie lange ein Eintrag im Cache behalten wird. Überall dort, wo ein Hostname ohne abschließenden Punkt steht, wird automatisch .artemis.home ergänzt. Statt localhost könnten Sie also auch Folgendes schreiben: localhost.artemis.home.
$TTL 86400
@ IN SOA hermes postmaster.hermes (
2009050202 10800 1800 3600000 259200 )
@ IN NS hermes
localhost IN A 127.0.0.1
loopback IN CNAME localhost
hermes IN A 172.30.2.1
router IN A 172.30.2.2
zeus IN A 172.30.2.3
19.5.2 DNS-Zonen
Diese Datei ergibt sich in offensichtlicher Weise aus named.artemis.home, jedoch sind localhost und die Hosts im Subnetz 172.30.3.x hier nicht enthalten, da sie in anderen Zonen liegen als 172.30.2.x. Hier treiben wir es mit den Abkürzungen auf die Spitze. Sie definieren mit $ORIGIN, was an die Einträge auf der linken Seite angehängt werden soll (natürlich nur, wenn diese keinen Punkt am Ende haben). Aus der simplen 1 wird dadurch 1.2.30.172.in-addr.arpa., was für die IP-Adresse 172.30.2.1 steht.
$TTL 86400
@ IN SOA hermes postmaster.hermes.artemis.home. (
1999010902 10800 1800 3600000 259200 )
@ IN NS hermes.artemis.home.
1 IN PTR hermes.artemis.home.
2 IN PTR router.artemis.home.
und
$TTL 86400
@ IN SOA hermes postmaster.hermes.artemis.home. (
1999010902 10800 1800 3600000 259200 )
@ IN NS hermes.artemis.home.
1 IN PTR router.artemis.home.
2 IN PTR venus.artemis.home.
Das ist dasselbe wie oben, also für die Zone 127.0.0, die nur localhost enthält.
$TTL 86400
@ IN SOA hermes postmaster.hermes.artemis.home. (
1997110901 10800 1800 3600000 259200 )
@ IN NS hermes.artemis.home.
1.0.0.127.in-addr.arpa. IN PTR localhost.artemis.home.
19.5.3 Sekundärer Nameserver
Ein sekundärer Nameserver erhöht die Fehlertoleranz, da er bei einem Ausfall des primären Servers dessen Aufgaben übernehmen kann. Es wird dieselbe Konfiguration verwendet wie oben beschrieben. In diesem Beispiel nehme ich an, dass der sekundäre Nameserver die Adresse 172.30.2.4 hat. Auf allen Rechnern muss die Datei /etc/resolv.conf um die Adresse des sekundären Nameservers ergänzt werden. Das Resultat ist:
domain artemis.home
nameserver 172.30.2.1
nameserver 172.30.2.4
Das Einrichten des sekundären Nameservers erfordert drei einfache Schritte:
- Anlegen des Verzeichnisses /var/named:
mkdir /var/named
- Anlegen der Datei /var/named/root.cache:
touch /var/named/root.cache
- Kopieren der Datei /etc/named.conf vom primären Nameserver. Diese Datei muss geringfügig abgeändert werden. Ersetzen
Sie alle Zeilen type master; durch type slave;. Dann ergänzen Sie jede Zone außer "."\ durch eine Zeile masters 172.30.2.1;.
options {
directory "/var/named";
forward only;
forwarders {
212.227.14.1;
};
};
zone "artemis.home" {
type slave;
file "named.artemis.home";
masters { 172.30.2.1; };
};
zone "2.30.172.in-addr.arpa" {
type slave;
file "named.172.30.2";
masters { 172.30.2.1; };
};
zone "3.30.172.in-addr.arpa" {
type slave;
file "named.172.30.3";
masters { 172.30.2.1; };
};
zone "0.0.127.in-addr.arpa" {
type slave;
file "named.127.0.0";
masters { 172.30.2.1; };
};
zone "." {
type hint;
file "root.cache";
};
Die file-Einträge haben in dieser Datei eine andere Bedeutung als beim primären Nameserver. Sie müssen beim sekundären Nameserver nicht vorhanden sein, jedoch kann der Server, wenn er beendet wird, seine Zonen-Informationen in diese Dateien schreiben, um den nächsten Start zu beschleunigen. Nun muss der Nameserver nur noch gestartet werden. Vergessen Sie nicht, in den Init-Files für einen automatischen Start zu sorgen! Sie testen den neuen Nameserver, indem Sie den alten Nameserver stoppen. Dann führen Sie ping und nslookup von verschiedenen Rechnern und mit verschiedenen Zieladressen aus. Starten Sie anschließend den alten Nameserver wieder. Ihr Netz ist jetzt gegen den Ausfall eines Nameservers gesichert.
19.5.4 BIND absichern
Der DNS-Server BIND, die am weitesten verbreitete Implementierung von DNS, hat eine lange Historie von Sicherheitslücken. Diese waren teilweise besonders fatal, weil DNS mit Root-Rechten lief. Das war notwendig, da der Port des DNS-Protokolls, Port 53, nur von Root geöffnet werden kann. Dieser Abschnitt zeigt, wie Sie BIND die Root-Rechte nehmen und wie Sie andere Aspekte des Servers sicherer machen.
Seit Version 8.2 ist BIND in der Lage, nach dem Binden von Port 53 die Root-Rechte abzugeben und als normaler Benutzer weiterzumachen. Zusätzlich kann er in ein bestimmtes Verzeichnis wechseln und dort ein chroot ausführen, um dieses Verzeichnis niemals mehr zu verlassen.
Das Abgeben der Root-Rechte ist ohne nennenswerten Aufwand machbar. Sie legen einen Benutzer und eine Gruppe dns an. Starten Sie named mit der Option -u dns. Das einzige Problem, dem Sie jetzt gegenüberstehen könnten, ist, dass named nun keine ausreichenden Rechte mehr in seinen Verzeichnissen hat.
Deswegen schieben Sie noch ein chown-Kommando nach:
groupadd -g 150 dns
useradd -u 150 -g 150 -M -s /bin/false dns chown -R dns.dns /var/named
Wenn nun noch die Datei /etc/named.conf für dns lesbar ist, haben Sie es geschafft. Achten Sie auf die Log-Ausgaben in /var/log/messages, um zu sehen, ob nichts schiefgegangen ist. In den obigen Kommandos bin ich davon ausgegangen, dass BIND die Standardpfade verwendet. Die Nummern für Benutzer und Gruppe dns sind natürlich nur Beispiele.
Entwurzelung
Die obige Schnellmaßnahme schützt Sie davor, dass ein Angreifer unmittelbar Root-Rechte erlangen kann. Doch das ist nicht genug. Nun müssen Sie named aus seinen Standardpfaden entfernen und in eine chroot-Umgebung einbinden. Die chroot-Umgebung ist nichts anderes als eine abgemagerte Dateihierarchie, in der sich nur named und die von ihm benötigten weiteren Dateien befinden. Durch den Systemaufruf chroot(2) kann sich ein Programm selbst in dieser Umgebung einsperren und dann nie mehr daraus entweichen. Eine »Flucht« könnte allenfalls auf sehr trickreichen Wegen gelingen, wenn das Programm Root-Rechte hat. Diese sollten Sie ihm wie oben beschrieben nehmen.
Die chroot-Umgebung muss in irgendeinem Verzeichnis im normalen Dateisystem ihren Ursprung haben. Ich habe dafür /home/dns gewählt. Wenn Sie »von außen« eine Datei/home/dns/etc/localtime sehen, dann sieht ein Programm nach dem Ausführen von chroot /home/dns diese als /etc/localtime.
Der Nachteil einer chroot-Umgebung ist die Duplizierung einiger Dateien, darunter auch libc. Dies belegt zusätzlichen Platz auf der Festplatte, doch auf einem Nameserver dürfte davon genug zur Verfügung stehen. Mit folgenden einfachen Schritten legen Sie die komplette chroot-Umgebung an:
mkdir -m 0700 /home/dns
mkdir -m 0755 /home/dns/etc
mkdir -m 0755 /home/dns/lib
mkdir -m 0755 /home/dns/dev
mkdir -m 0755 /home/dns/usr
mkdir -m 0755 /home/dns/usr/sbin
mkdir -m 0755 /home/dns/var
mkdir -m 0755 /home/dns/var/named
mkdir -m 0755 /home/dns/var/run
mknod -m 666 /home/dns/dev/null c 1 3
cp /etc/localtime /home/dns/etc/
cp /etc/named.conf /home/dns/etc/
cp /var/named/* /home/dns/var/named
chown -R dns.dns /home/dns/var/named /home/dns/var/run
cp /usr/sbin/{named,named-xfer} /home/dns/usr/sbin
cp /lib/libc.so.6 /home/dns/lib
cp /lib/libpthread.so.0 /home/dns/lib
cp /lib/libnsl.so.1 /home/dns/lib
cp /lib/ld-linux.so.2 /home/dns/lib
cp /usr/local/lib/libdns.so.3 /home/dns/lib
cp /usr/local/lib/libisc.so.3 /home/dns/lib
cp /usr/local/lib/liblwres.so.1 /home/dns/lib
cp /usr/local/lib/libomapi.so.3 /home/dns/lib
Die letzten cp-Befehle verweisen auf symbolische Links, doch das Kopieren bewirkt, dass die echte Library-Datei kopiert wird. Wenn Sie noch etwas Platz sparen möchten, führen Sie als letzten Befehl noch
strip /home/dns/lib/*
aus. Das verkleinert libc auf etwa 1,3 MB und die anderen Librarys entsprechend.
Nun müssen Sie noch Syslog präparieren. Programme schreiben ins Syslog, indem sie in die Pipe /dev/log schreiben. Diese wird von Syslog angelegt. Unser eingesperrtes BIND kann aber nicht auf /dev/log zugreifen. Doch zum Glück können Sie Syslog dazu bringen, mehrere solcher Pipes anzulegen. Da Sie eine Pipe in /home/dns/dev benötigen, fügen Sie in dem rc-Skript, in dem Syslog gestartet wird (zum Beispiel /etc/init.d/syslog), die Argumente -a /home/dns/dev/log hinzu. Dann stoppen Sie Syslog und starten es wieder neu. Die Änderung ist nun aktiv.%\textcolor{red}{Fast wörtlich der gleiche Text wie in Tipp Nr. 237 auf S. 892.)}
Der Start von BIND in der neuen Umgebung ist unspektakulär. Sie stoppen BIND, sofern er noch läuft, und ändern dann das rc-Skript, in dem BIND gestartet wird. Fügen Sie dem Aufruf die Argumente -u dns -t /home/dns hinzu, speichern Sie die Datei, und starten Sie dann BIND neu. Prüfen Sie /var/log/messages. Dort muss sich BIND gemeldet und erklärt haben, dass er bereit ist. (Bei manchen Distributionen ist es stattdessen /var/log/daemon.log.)
Zone Transfer einschränken
Ein sogenannter Zone Transfer ist nötig zum Datenabgleich zwischen den DNS-Servern. Wenn Sie DNS nur für das Intranet verwenden, dann sollte ein Zone Transfer ins Internet überhaupt nicht möglich sein. Dies können Sie durch die Bindung an spezifische Netzwerk-Interfaces und Paketfilter (siehe den Abschnitt »Paketfilter«) erreichen. Am wirksamsten ist die Kombination dieser Maßnahmen.
Ist ein Zone Transfer zu einem Partner-DNS-Server nötig, so erlauben Sie diesen Transfer nur den jeweiligen Servern. Deren IP-Adressen sind ja ohnehin bekannt. Tragen Sie Folgendes in /home/dns/etc/named.conf ein (die IP-Adresse ersetzen Sie natürlich durch die Adressen Ihrer Partnerserver):
options {
...
allow-transfer {
217.17.17.17;
}
...
};
Nur an die nötigen Netzwerk-Interfaces binden
Standardmäßig bindet BIND sich an alle vorhandenen Netzwerk-Interfaces. Dies können Sie mit einem Eintrag in /home/dns/etc/named.conf einschränken:
options {
...
listen-on {
192.168.1.1;
192.168.2.1;
}
...
};
Die Adressen sind natürlich nur Beispiele. Wenn Sie irgendwo den Eintrag 127.0.0.1 als DNS-Server haben, sollten Sie auch 127.0.0.1 zu der Liste hinzufügen – ich sehe allerdings wenig Sinn in solch einer Konfiguration. Wenn Sie DNS nur für das Intranet verwenden, dann sollte das Netzwerk-Interface, das zum Internet führt, nicht in der Liste enthalten sein.
Tipp 268: Unerwünschte BIND-Verbindungen unterdrücken |
Wenn Sie BIND in einem lokalen Netz benutzen, das über eine Wählleitung ans Internet angeschlossen ist und keine Flatrate besitzt, könnten die beiden folgenden Optionen Sie interessieren, die unter options in /home/dns/etc/named.conf eingetragen werden. Diese Optionen haben jedenfalls nichts mit Sicherheit zu tun, sondern sollen nur unerwünschte Verbindungsanforderungen unterdrücken: |
dialup yes reduziert die Aktivitäten bei Zone Transfers. |
notify no sendet keine NOTIFY-Nachrichten bei Konfigurationsänderungen. |
Paketfilter
Paketfilter können unerwünschte Zugriffe auf den DNS-Server verhindern. Wie diese Filter aussehen sollten, ist aber stark von der individuellen Netzwerk-Topologie und der Platzierung des DNS-Servers abhängig. Wenn Sie DNS nur für das Intranet verwenden, dann sollte der Server von außen nicht erreichbar sein. Sie würden in diesem Fall also alle auf Port 53 ankommenden UDP-Pakete verwerfen. Zone Transfers sollten auch unterbunden werden. Das bedeutet, sämtliche TCP-Pakete von oder nach Port 53 zu verwerfen.
Soll der DNS-Server dagegen aus dem Internet erreichbar sein, können Sie mit Paketfiltern wenig machen. Es empfiehlt sich dann, für das Intranet und die nach außen sichtbaren Rechner separate DNS-Server aufzusetzen.
19.5.5 Probleme mit der Namensauflösung
Ein Problem, das beim Einrichten des Internetzugangs unter Ubuntu auftreten kann, ist die gestörte Namensauflösung von Internetseiten. Der DNS-Server wird dem Anwender in der Regel dynamisch zugewiesen. Oft sind solche Nameserver jedoch überlastet. Dann tun Sie gut daran, einen weniger frequentierten Server zu definieren. Das kann entweder mit dem Netzwerkkonfigurationswerkzeug oder durch direkte Bearbeitung der Datei /etc/dhcp3/dhclient.conf erfolgen. Der notwendige Eintrag hat folgende Gestalt:
prepend domain-name-servers 62.72.64.237
In der Datei ist bereits ein entsprechender Eintrag vorhanden. Dort müssen Sie das Kommentarzeichen # entfernen und die IP-Adresse ändern.
Um die Änderungen ohne Neustart des Systems zu übernehmen, ist noch folgender Befehl erforderlich:
sudo /etc/init.d/networking restart
Welcher DNS-Server gerade genutzt wird, erfahren Sie durch folgenden Befehl:
grep nameserver /etc/resolv.conf
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.