Bewertung 3


Die Kandidaten sollten in der Lage sein, BIND für die Ausführung als nicht privilegierter Benutzer und für die Ausführung in einer chroot-Umgebung zu konfigurieren. Dieses Lernziel beinhaltet die Konfiguration von DNSSEQ Statements wie key und trusted-keys, um Domain-Spoofing zu vermeiden. Ebenfalls enthalten ist die Fähigkeit, eine geteilte DNS-Konfiguration unter Verwendung des forwarders Statements zu konfigurieren und eine andere als die Standardversionszeichenkette als Antwort auf Anfragen anzugeben.

Schlüsseldateien, Begriffe und Hilfsmittel beinhalten:

  • SysV init Dateien oder rc.local
  • /etc/named.conf
  • /etc/passwd
  • dnskeygen

Auf den ersten Blick ist DNS eine relativ einfacher Dienst, der keine größeren Gefahren für ein System bietet. Wenn wir aber genauer hinsehen, dann stellt gerade das DNS eine gigantische Angriffsmöglichkeit dar. Sollte es einem Angreifer gelingen, die Einträge eines Nameservers zu fälschen, so kann er dafür sorgen, dass Clients, die eigentlich auf einen bestimmten Server zugreifen wollen, stattdessen auf einen anderen Rechner umgeleitet werden. Das kann alle möglichen Folgen haben, von der Umleitung von Mails bis hin zum Diebstahl sensibler Informationen wie Kreditkartennummern oder ähnliches…

Aus diesem Grund ist die Absicherung eines DNS-Servers heute eine Selbstverständlichkeit. Die in diesem Abschnitt genannten Techniken beziehen sich alle auf unterschiedliche Aspekte der Absicherung von DNS-Servern gegen Angriffe oder Fälschungen.

Ausführung von BIND unter Normaluserprivilegien

Grundsätzlich werden Systemdienste von Startscripts gestartet, die alle dem User root gehören. Wenn ein Dienst wie BIND also von einem solchen Startscript (wie etwa /etc/init.d/named oder /etc/rc.local) gestartet wird, dann läuft er standardmäßig unter der UID von root. Das ist eine unnötige Sicherheitslücke, denn BIND benötigt keinerlei Privilegien zur Ausführung, die es erzwingen würden, dass er unter der UID 0 läuft.

Aus diesem Grund kennt das Programm named zwei Parameter, die es ermöglichen, es unter einer anderen UserID laufen zu lassen: -u Username Führt named unter der UserID des genannten Users aus. -g Gruppenname Führt named unter der GroupID der genannten Gruppe aus.

Statt User- bzw. Gruppenname kann hier auch gleich eine User- bzw. GruppenID angegeben werden. Die einzig wirklich notwendige Voraussetzung für diese Technik ist, dass der angegebene User (bzw. das Gruppenmitglied der angegebenen Gruppe) Leserechte auf die Konfigurationsdateien von BIND hat und Schreibrechte in dem Verzeichnis, in dem Dateien wie etwa der Cache-Dump angelegt werden sollen.

In der Regel wird ein User named und eine Gruppe named angelegt, und in der entsprechenden Startdatei der Aufruf von named dann mit den Parametern für diesen User und diese Gruppe ausgestattet:

  /usr/sbin/named -u named -g named

Die Zugriffsrechte für /etc/named.conf werden so gesetzt, dass der User named lesenden Zugriff hat, das Verzeichnis /var/named wird dem User named übereignet:

  -rw-r-----   1  root     named    ...  /etc/named.conf
  drwxr-xr-x   4  named    named    ...  /var/named

Jetzt kann der Nameserver komplett unter der Userkennung named laufen und alle notwendigen Aufgaben erledigen. Sollte es erwünscht sein, dass der Nameserver bestimmte Logdateien anlegt (siehe auch Kapitel 2.207.1, dann muss der User named auch in den entsprechenden Verzeichnissen Schreibrecht besitzen.

Ausführung von BIND in einer chroot-Umgebung

Eine zusätzliche Sicherheit wird dadurch erreicht, dass ein DNS-Server in einer chroot-Umgebung läuft. Um das zu realisieren, muss ein Verzeichnis angelegt werden, das aus der Sicht des Nameservers jetzt das Wurzelverzeichnis ist. Dieses Verzeichnis muss alle vom Nameserver benötigten Unterverzeichnisse, Dateien und Programme enthalten. Dazu kommt, dass eventuell benötigte Libraries für diese Programme auch in der chroot-Umgebung liegen müssen. Eine minimale Konfiguration eines solchen Verzeichnisses besteht aus

  + bin
     - ldconfig
     - named
     - named-xfer
  + dev
     - null
     - zero
  + etc
     - group
     - localtime
     - named.conf
  + lib   
     - libc-2.*.so
     - libc.so.6
     - ld-2.*.so
     - ld-linux.so.2  
  + var
     + named
         - 127.0.0.zone
         - localhost.zone
         - beispiel.xyz.zone
         - 67.45.199.in-addr.arpa.zone
     + run    

Nehmen wir an, diese Verzeichnisse liegen in /var/adm/named-umgebung. In diesem Fall würde der Aufruf des Nameservers im Startscript jetzt eben lauten

  chroot /var/adm/named-umgebung /usr/sbin/named -u named -g named

Besser ist es aber, den Parameter -t von named zu benutzen, der genau dafür gedacht ist, named in einer chroot Umgebung auszuführen. Außerdem sollten wir gleich das binary aus der chroot Umgebung starten:

  /var/adm/named-umgebung/bin/named -u named -g named -t /var/adm/named-umgebung

Damit ist aus der Sicht des Nameservers das Verzeichnis /var/adm/named-umgebung jetzt die Wurzel des Systems. Der Nameserver hat also – selbst wenn er wollte – keinerlei Zugriff auf irgend ein anderes Verzeichnis, er ist in einem Sandkasten gefangen, aus dem es keinen Ausgang gibt.

Damit der Nameserver auch den Syslog Daemon weiterbenutzen kann, muss dieser mit der Zusatzoption

  syslogd -a /var/adm/named-umgebung/dev/log

gestartet werden. Diese Anweisung erstellt beim Start des Syslogdaemosn einen neuen Socket innerhalb der chroot-Umgebung, auf den syslog zusätzlich lauscht.

Damit auch das Kontrollprogramm ndc auf den Nameserver zugreifen kann, muss die ganze BIND-Packung neu kompiliert werden mit ein paar kleinen Änderungen. Es geht um die Frage, in welcher Datei die PID des Nameservers zu finden ist, da unser Nameserver ja jetzt diese Datei in /var/adm/named-umgebung/var/run ablegt und ndc sie in /var/run sucht, muss hier eine Kleinigkeit verändert werden…

Verwendung von DNSSEC-Statements

Mit der zunehmenden Wichtigkeit des Internets und der damit folgenden zunehmenden Angreifbarkeit der Nameserver hat sich eine Arbeitsgruppe DNSSEC (DNS-Security) zusammengefunden, die es sich zur Aufgabe gemacht hat, das DNS sicherer zu machen um sogenanntes DNS-Spoofing (Fälschen von Nameserverantworten) zu verhindern. Die neueren Versionen von BIND unterstützen eben diese Methoden, was ja auch der Grund dafür ist, nicht mehr mit alten BIND-Versionen wie 4.9 zu arbeiten.

Die wichtigste Anforderung an Sicherheit im Rahmen des DNS-Systems ist die Sicherstellung, dass eine DNS-Antwort bzw. ein Zonentransfer eines Master-Servers an einen Slave-Server tatsächlich von dem Nameserver kommt, von dem sie erwartet wird. Um das zu gewährleisten, bietet DNSSEC eine Möglichkeit an, mit Schlüsselpaaren zu arbeiten, die eine Authentifizierung und Verifizierung ermöglichen.

Es gibt drei denkbare Arten von solchen Schlüsselpaaren: Zonenschlüssel zur Sicherstellung, dass eine Antwort auch tatsächlich vom authoritiven Server einer Zone stammt Hostschlüssel zur Sicherstellung dass ein Paket tatsächlich von dem Host stammt, von dem es vorgibt zu sein Userschlüssel zur Sicherstellung, dass eine Mail tatsächlich von dem User stammt, von dem sie vorgibt zu sein.

Wir werden uns hier jetzt auf die erste Methode beschränken, die Zonenschlüssel.

Um Schlüssel zu generieren, die den Anforderungen der DNSSEC genügen, gibt es das Programm dnskeygen. So erstellt beispielsweise der Befehl

  dnskeygen -D 1024 -z -n beispiel.xyz.

ein Schlüsselpaar für Zonenschlüssel (-z) für die Zone beispiel.xyz (-n beispiel.xyz.). Es werden zwei Dateien erstellt, die jetzt den öffentlichen und den privaten Schlüssel enthalten:

  -rw-r--r--   1 root root  572 Feb 27 16:37 Kbeispiel.xyz.+003+36569.key
  -rw-------   1 root root  688 Feb 27 16:37 Kbeispiel.xyz.+003+36569.private

Die Datei mit der Endung .key enthält den öffentlichen Schlüssel bereits in einem Format, das genau für die Nameserverdateien passt. Diese Datei kann jetzt einfach ans Ende der Zonendatei gehängt werden:

  cat Kbeispiel.xyz.+003+36569.key >> /var/named/beispiel.xyz.zone

Mit Hilfe des Befehls dnssigner und dem privaten Schlüssel kann jetzt jeder Eintrag des Nameservers signiert werden, damit sichergestellt wird, dass er tatsächlich vom entsprechenden Server kommt.

Im Eintrag der Zone in /etc/named.conf kann stattdessen aber auch ein Schlüssel angegeben werden, der Verwendung als öffentlicher Schlüssel finden soll. Dazu dienen die Schlüsselworte pubkey flags protocol alghorithm keyname Angaben zum verwendeten öffentlichen Schlüssel. key Spezifiziert Informationen für Authentizierung und Authorisierung. trusted-keys Definiert DNSSEC-Schlüssel, die fest eingebaut sind (siehe oben) und daher als verlässlich gelten.

Mit Hilfe der definierten Keys können jetzt ACLs (Access Control Lists) erstellt werden, die festlegen, wer was mit dem Nameserver machen darf. Dazu zählen

  • einfache Abfragen (allow-query)
  • rekursive Abfragen (allow-recursion)
  • Zonentransfer (allow-transfer)

Umgekehrt kann damit auch eine Liste festgelegt werden, wer bestimmte Sachen nicht machen darf (blackhole).

Geteilte DNS-Konfiguration – Forwarding

Forwarding kann benutzt werden um einen großen, rechnerüberspannenden Cache zu generieren und so den Datenverkehr über Links zu externen Nameservern zu reduzieren. Es kann auch benutzt werden, um Servern, die nicht direkt mit dem Internet verbunden sind, zu erlauben trotzdem Nachfragen an entfernte Nameserver zu schicken. Forwarding spielt nur für diejenigen Abfragen eine Rolle, für die der Server nicht authoritativ ist und deren Antworten nicht bereits im Cache liegen.

Mit der Anweisung (im Optionsblock der Datei /etc/named.conf)

  forward only|first

kann angegeben werden, ob alle Anfragen an die Forwarder weitergeleitet wird (only) oder sie nur zuerst gefragt werden (first), bevor selbst nach einem Namen gesucht wird.

Die Anweisung forward hat nur dann eine Bedeutung, wenn – ebenfalls im Optionsblock – eine Liste von DNS-Servern angegeben wurde, die als Forwarder zur Verfügung stehen. Dazu dient der Befehl

  forwarders {
    IP-Adresse;
    IP-Adresse;
    ...
  };

Wenn diese Angaben aber nicht im Optionsblock, sondern innerhalb der Definition von Zonen gemacht wird, so kann dafür gesorgt werden, dass verschiedene Server im lokalen Netz für verschiedene Zonen zuständig sind, ohne dass ein externer User davon Kenntnis bekäme. Für ihn sähe es immer noch so aus, dass der Nameserver, den er aufgerufen hat, die Antwort auch selbst gespeichert hätte. Das wird zur Absicherung eines DNS-Servers benutzt, um von Vorneherein die Wahrscheinlichkeit geringer zu halten, dass ein Angreifer überhaupt erfährt, welchen Server er angreifen müsste um DNS-Spoofing anzuwenden.

Versionsnummer verändern

Schon im Abschnitt 2.207.1 haben wir die Möglichkeit kennengelernt, mit Hilfe der Option version einen aus der Luft gegriffenen Versionsstring zu erzeugen, der auf Anfragen von Clients gesendet werden soll. Das hat tatsächlich auch eine sicherheitsrelevante Bedeutung, denn das Wissen um die echte Version ermöglicht es einem Angreifer, genau die bekannten Schwachstellen eben dieser Version auszunützen.