TinyDNS (djbdns) auf Linux Debian Server installieren und konfigurieren

Einleitung

Ziel: Auf einem Server mit Debian Linux (zum Zeitpunkt der Erstellung dieses Beitrags in Version 7.6 „Wheezy“) sollen ein Master-Nameserver und ebenfalls ein Slave-Nameserver mit TinyDNS betrieben werden.

Voraussetzung: zwei IPs, die auf den Server zeigen (sollte bei den meisten Anbietern kein Problem sein, einfach vorher erkundigen). Für den privaten Gebrauch – wie bei mir – reicht das alle Mal, wenn ich quasi nur einen Nameserver betreibe. Denn wenn mein Server nicht erreichbar ist, bringt mir das auch nichts, dass DNS geht. Die meisten Registry-Stellen (wie die DENIC, die alle .de-Domains verwaltet) verlangen jedoch mindestens 2 Nameserver, die auf unterschiedlichen IPs liegen / zeigen. Daher ist dieses ebenfalls ein kleiner Workaround für das „Problem“.

Natürlich könnt Ihr diese Anleitung auch genauso verwenden, wenn Ihr nur einen Nameserver auf einem Server betreiben (also auch nur auf einer IP lauschen) wollt. Dazu müssen einfach nur bei der Konfiguration ein paar Befehle weggelassen werden (wird an den entsprechenden Stellen unten noch einmal erklärt).

Inhalt


Voraussetzung schaffen um mittels apt das Paket djbdns installieren zu können

Hinweis: Das Programm TinyDNS ist ein Teil des djbdns Pakets von D. J. Bernstein. Bitte also nicht wundern, dass wir hier nicht direkt ein Paket tinydns installieren.

Zunächst die Datei /etc/apt/sources.list erweitern, da das benötigte Paket djbdns nur in „sid“ (unstable) verfügbar ist. Am Ende der Datei diese Zeilen einfügen:

## add unstable (sid)
deb http://ftp.de.debian.org/debian/ unstable main contrib non-free

Danach die Datei /etc/apt/preferences anpassen, damit nicht plötzlich Pakete ungewollt aus „unstable“ Quellen installiert oder aktualisiert werden (was zu kaputten Abhängigkeiten zwischen Paketen führen kann!). Sofern Ihr diese Datei schon bearbeitet habt, wisst Ihr sicherlich was Ihr tut. Ansonsten sollte die Datei ziemlich leer sein und Ihr braucht einfach nur am Ende der Datei diese Zeilen einfügen:

Package: *
Pin: release a=unstable
Pin-Priority: -1

Anschließend einmal die Listen für apt neu einlesen:

apt-get update

Nun kann das eigentliche Paket installiert werden:

apt-get install -t sid djbdns

Dabei wird daemontools, etc. mit installiert. TinyDNS benötigt diese zwar intern, aber wir werden den Dienst trotzdem nachher mit einem eigenen kleinen Start-/Stopp-Skript bedienen.


TinyDNS vorkonfigurieren, damit der Dienst auf zwei IPs lauscht

Nun werden die beiden Nameserver aufgesetzt. Wir wollen ja nach außen auf beide Nameserver-IPs lauschen, daher müssen wir TinyDNS für jede IP Konfigurieren und zwei Dienste starten (jeder lauscht dann auf eine IP des Standard UDF Ports 53). Als Beispiel hier hat der Server die beiden IPs 1.2.3.4 (für den Master Nameserver) und 5.6.7.8 (für den Slave Nameserver):

## add system users needed by tinydns
useradd --system --home-dir /nonexistent --shell /bin/false tinydns
useradd --system --home-dir /nonexistent --shell /bin/false dnslog

## add main configuration for master
tinydns-conf tinydns dnslog /etc/tinydns-master 1.2.3.4

## add main configuration for slave
tinydns-conf tinydns dnslog /etc/tinydns-slave 5.6.7.8

## make sure master and slave share the same domain configuration
rm -rf /etc/tinydns-slave/root
ln -fs /etc/tinydns-master/root /etc/tinydns-slave/root

Tipp: Wer nur eine Instanz installieren möchte (also bspw. nur einen Master Nameserver), muss einfach die letzten 3 Befehle (markierte Zeilen ab Zeile 8) weglassen.

Der letzte Block (Zeile 12 und 13) sorgt dafür, dass wir später nicht jede Domain einzeln für den Master und dann noch für den Slave konfigurieren müssen. Für den Slave wurde einfach eine Verknüpfug (symbolic link) zur Konfiguration des Masters anlegt, daher sind die Konfiguration immer identisch und liegen phsikalisch unter /etc/tinydns-master/root (egal welche Konfiguration man auch öffnet bzw. editiert).

Das wars. TinyDNS lauscht nun auf beiden IPs sobald der TinyDNS Server gestartet wird.


Domains hinterlegen (Zonefile konfigurieren), damit unsere Nameserver korrekt antworten

Nun muss dem TinyDNS „nur noch eben schnell“ erklärt werden, für welche Domains er verantwortlich ist und Antworten ausspucken soll. Hierzu wechselt Ihr zunächst in den Ordner /etc/tinydns-master/root in dem die Konfigurationsdatei (Zonefile) abgelegt wird.

Natürlich könnt Ihr die diversen add- Skripte nutzen, die sich ebenfalls in diesem Ordner befinden. Ich empfehle jedoch die Datei data in diesem Ordner direkt zu bearbeiten und hierbei die offizielle Dokumentation für tinydns-data zu Rate zu ziehen.

Das Format sieht zunächst vielleicht komisch aus, auf jeden Fall anders als man es ggf. von BIND Zonefiles kennt. Doch wenn man das Prinzip einmal verstanden hat, ist es ganz einfach das TinyDNS Zonefile zu schreiben.

Hier ein paar nützliche Links (alle Seiten auf englisch):

Die konkreten Einträge für diesen Blog (ansas-meyer.de) sieht bei mir so aus:

# soa
Zansas-meyer.de.:ns1.dhm80.de.:hostmaster.dhm80.de.:2014082701:3600:1800:604800:600:3600
# a
+ansas-meyer.de.:81.169.227.63:3600
+*.ansas-meyer.de.:81.169.227.63:3600
# ns
&ansas-meyer.de.::ns1.dhm80.de.:3600
&ansas-meyer.de.::ns2.dhm80.de.:3600
# mx
@ansas-meyer.de.::mx1.dhm80.de.:5:3600
@ansas-meyer.de.::mx2.dhm80.de.:5:3600
# txt
'ansas-meyer.de.:v=spf1 a mx -all:3600

Die einzelnen Schritte sehen dann zusammengefasst so aus:

cd /etc/tinydns-master/root/
vi data
## do your changes
make

Wichtig: Am Ende nicht vergessen das make auszuführen (in dem Ordner /etc/tinydns-master/root/), damit die Konfiguration aktualisiert wird (siehe Zeile 4)!

Das wars. TinyDNS weiß nun was er bei den eingerichteten Domains bei einer Anfrage antworten soll.

Wenn TinyDNS auch bei unbekannten Domains immer antworten soll

Von Haus aus antwortet TinyDNS nur auf Anfragen von Domains, die Ihr im Zonefile angelegt habt. Kennt TinyDNS eine Domain nicht, so erhält der aufrufende Client nach ein paar Sekunden ein Timeout. Ich persönlich finde das gut, da Euer Nameserver dadurch weniger anfällig ist.

Wenn Ihr jedoch wollt, dass TinyDNS immer antwortet (uns sei es halt mit „habe keinen Eintrag zu der Domain“), dann fügt einfach am Anfang des Zonefile data folgendes ein:

# make this nameserver always answer instead of letting client run into timeout
&::a.root-servers.net

Dienst sauber mittels Start-Stopp-Skript einrichten, damit dieser beim Systemstart auch automatisch gestartet wird (ohne deaemontools!)

Eine neue Datei namens /etc/init.d/tinydns anlegen mit diesem Inhalt:

#!/bin/bash

### BEGIN INIT INFO
# Provides:          tinydns
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Should-Start:      $network $syslog
# Should-Stop:       $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop tinydns
# Description:       tinydns is a Domain Name Server (DNS)
### END INIT INFO

## list of servers
servers="master slave"

## used for return code
errors=0

case "$1" in
    start)
        for server in $servers
        do
            echo "starting tinydns (${server})..."

            ## try to get pid of current tinydns server
            pid=`cat /var/run/tinydns-${server}.pid 2>/dev/null`

            ## check if pid exists and process is still running
            if test -n "$pid" && kill -0 "$pid" >/dev/null 2>&1; then
                echo "tinydns[$pid] already running (${server})"
                errors=1
            ## start server & save pid-file
            else
                cd /etc/tinydns-${server}
                ./run < /dev/null > /dev/null 2>&1 &
                echo $! >/var/run/tinydns-${server}.pid
            fi
        done
    ;;

    stop)
        for server in $servers
        do
            echo "stopping tinydns (${server})..."

            ## try to get pid of current tinydns server
            pid=`cat /var/run/tinydns-${server}.pid 2>/dev/null`

            ## check if pid exists and process is still running
            if [ ! -n "$pid" ]; then
                echo "cannot find tinydns to kill (${server})"
                errors=1

            ## stop server and delete pid-file (try to kill process)
            else
                kill "$pid" >/dev/null 2>&1 && sleep 1
                kill -0 "$pid" >/dev/null 2>&1 && kill -9 "$pid" >/dev/null 2>&1 && sleep 1
                if kill -0 "$pid" >/dev/null 2>&1; then
                    echo "tinydns[$pid] is not killable (${server})"
                    errors=1
                else
                    rm /var/run/tinydns-${server}.pid
                fi
            fi
        done
    ;;

    restart)
        $0 stop
        $0 start
    ;;

    update)
        echo "updating tinydns config..."
        set -e
        for server in $servers
        do
            cd /etc/tinydns-${server}/root
            cat domains/* > data
            make
            break
        done
    ;;

    killall)
        echo "killing all tinydns processes..."
        pkill -u tinydns tinydns
        for server in $servers
        do
            rm /var/run/tinydns-${server}.pid
        done
    ;;

    *)
        echo "Usage: $0 {start|stop|restart|update|killall}"
        errors=1
esac

exit $errors

Tipp: Wer nur eine Instanz installieren möchte (also bspw. nur einen Master Nameserver), muss einfach in der markierten Zeile 16 den Teil slave rauslöschen, damit nur ein Master gestartet wird. Diese Zeile würde dann so aussehen: servers="master"

Damit das Skript auch ausgeführt werden kann müssen wir die Berechtigungen noch anpassen:

chmod 755 /etc/init.d/tinydns

Wichtig: Die ersten Zeilen im Skript, die einfach nur wie Kommentare aussehen, dienen nun der Steuerung für den Systemstart (diese Zeilen also bitte nicht ändern, es sei denn Ihr wisst was Ihr tut… oder einfach hier nachlesen). Nun muss der Dienst noch in die Startroutinen des Servers eingetragen werden, damit TinyDNS auch bspw. beim Neustart des Servers gleich gestartet wird. Das geht ganz einfach mit diesem Befehl, der nur einmalig ausgeführt werden muss:

update-rc.d tinydns defaults

Das wars. TinyDNS statet nun automatisch bei jedem Neustart.


Ein paar nützliche Befehle um den Nameserver manuell zu steuern und zu überwachen

Mit diesen Befehlen könnt Ihr die Nameserver manuell zu starten, kontrollieren oder beenden:

## check if tinydns is running (should have two entries when running master & slave)
ps auxf | grep tinydns

## check if tinydns is listening to the desired ips and ports
netstat -tulpen

## kill all tinydns processed (stop tinydns)
pkill tinydns

## use tinydns service script we created unter /etc/init.d/tinydns(master & slave)
service tinydns start
service tinydns stop
service tinydns restart

Ich hoffe dieses How-to hat Euch helfen können. Was habt Ihr ggf. anders gemacht? Läuft alles? Schreibt mir doch einfach ein paar Zeilen dazu.  Ich würde mich freuen.


Update (26.04.2015): Abschritt „Voraussetzung schaffen“ überarbeitet und die automatische Installation bzw. Aktualisierung auf „testing“ bzw. „sid“ Pakete über APT-Pinning ausgeschlossen.

Das könnte dich auch interessieren …

2 Antworten

  1. Henrik sagt:

    Vielen Dank für die Anleitung, aber Vorsicht beim cut n paste der preferences fuer das pinning!

    Wenn man in Zeile 4 ist ein Leerzeichen mit-kopiert, werden die beiden pinnings als eines aufgefasst, und man macht unbeabsichtigt ein teil-upgrade auf Debian testing!

    • Ansas sagt:

      Danke für den Hinweis, Henrik.

      Leider mogelt mir das WordPress Plugin „Crayon Syntax Highlighter“ einfach ein Leerzeichen in die „eigentlich“ leeren Zeilen :/ Das ist mir bis zu Deinem Kommentar gar nicht aufgefallen. In diesem Zuge habe ich mal den Entwickler des Plugins darauf angesprochen, siehe https://github.com/aramk/crayon-syntax-highlighter/issues/344

      Ich habe zudem diesen Beitrag grad mal ein wenig vereinfacht. Da nur das Release „unstable“ benötigt wird, habe ich die Integration des Releases „testing“ entfernt.

      VG Ansas

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte beachte die Hinweise zum Datenschutz