tinydns server einrichten

reinhard@finalmedia.de Sat 13 Nov 2021 12:26:47 PM CET

# djbdns (aka tinydns) ist ein minimalistischer, stabiler, sicherer und sehr performanter DNS Server von D. J. Bernstein (djb). Diese Anleitung beschreibt, wie djbdns zusammen mit daemontools auf einem debian host einzurichten ist.

Wir verwenden nur die UDP Variante, und verzichten auf die TCP Variante via ucspi-tcp.

Quellcode beziehen und Executables bauen

Zunächst brauchst du den Original Quellcode djbdns-1.05.tar.gz von djb.

Oder hier als Mirror zum direkten Download: djbdns-1.05.tar.gz

Alternativ existiert auch eine eine gepatchte Version mit Teilsupport für IPv6 und dnssec Funktionalität namens tinydnssec als tinydnssec-1.05-1.8.tar.bz2. Einen lokalen Mirror findest du hier: tinydnssec-1.05-1.8.tar.bz2. Beachte jedoch: Die gepatchte Version stammt nicht von djb. Setze diese daher nur ein, wenn du sie zwingend brauchst, z.B. wenn due IPv6 verwenden willst. Zum Patch beigetragen haben Felix von Leitner, Peter Conrad, Henryk Plötz, Pietro Cerutti.

Folgende sha256sum solltest du prüfen:

3ccd826a02f3cde39be088e1fc6aed9fd57756b8f970de5dc99fcd2d92536b48  djbdns-1.05.tar.gz
b767469b87a6bf2b020a54ef2f9d86f37237e19217305fa7c06f93e7cfa96195  tinydnssec-1.05-1.8.tar.bz2

Wir bauen jetzt die Executables aus den Originalquellen auf deiner Workstation. Ich nehme hierbei jetzt der Einfachheit halber an, dass diese die gleiche Systemarchitektur hat, wie deine Zielplattform. (Nehmen wir an, beides ist X86_64)


# quellverzeichnis erstellen und quellen dorthin entpacken
mkdir -p ~/src/djbdns/
tar -C ~/src/djbdns/ -x -v -z -f djbdns-1.05.tar.gz

# build konfiguration vornehmen
cd ~/src/djbdns/djbdns-1.05/
echo "gcc -static -O2 -include /usr/include/errno.h" > conf-cc
echo "gcc -s -static" > conf-ld

# binaries compilieren
cd ~/src/djbdns/djbdns-1.05/
make

# buildinfo (wenn du file installiert hast)
file tinydns
file tinydns-data
file axfrdns
file dnsq

# auswahl der erzeugten, statisch gelinkten binaries in einen tarball packen
cd ~/src/djbdns/djbdns-1.05/
tar cvzf tinydns_binaries.tgz tinydns tinydns-data axfrdns dnsq


Binaries auf Zielserver kopieren und Basiskonfiguration erstellen

Kopiere nun die soeben erzeugte tinydns_binaries.tgz z.B. via ssh auf deinen Zielserver und entpacke sie dort mittels:


ssh root@DEIN_ZIELSERVER "tar xvzC /usr/bin/" < tinydns_binaries.tgz

Nun auf dem Zielserver fortfahren:



# wir brauchen die daemontools und make
apt-get update
apt-get install daemontools daemontools-run make

mkdir -p  /etc/tinydns/root
mkdir -p  /etc/tinydns/env
mkdir -p  /etc/tinydns/log/main
chown nobody:root /etc/tinydns/log
chown nobody:root /etc/tinydns/log/main

cat << :::eof::: > /etc/tinydns/run && chmod +x /etc/tinydns/run
#!/bin/sh
exec 2>&1
exec envuidgid tinydns envdir ./env softlimit -d300000 /usr/bin/tinydns
:::eof:::

cat << :::eof::: > /etc/tinydns/log/run && chmod +x /etc/tinydns/log/run
#!/bin/sh
exec setuidgid nobody multilog t ./main
:::eof:::

# systemuser "tinydns" erstellen
adduser --system --no-create-home --disabled-login --disabled-password tinydns


Nun konfigurieren wir den Server. ACHTUNG! Ersetze hierbei in nachfolgenden Befehlen an der Stelle "ACHTUNG_HIER_IPv4_ADRESSE_DES_SERVERS" durch die öffentliche IPv4-Adresse deines Server:


echo "ACHTUNG_HIER_IPv4_ADRESSE_DES_SERVERS" > /etc/tinydns/env/IP

echo "/etc/tinydns/root" > /etc/tinydns/env/ROOT

Nun die Zonendatei erstellen.


cat << :::eof::: > /etc/tinydns/root/data

# +++ syntax doku gleich mit in die configdatei ablegen +++
# Z = SOA fqdn:mname:rname:ser:ref:ret:exp:min:ttl:timestamp:lo
# & = NS fqdn:ip:x:ttl:timestamp:lo
# @ = MX fqdn:ip:x:dist:ttl:timestamp:lo
# + = A (Alias) fqdn:ip:ttl:timestamp:lo
# ^ = PTR fqdn:p:ttl:timestamp:lo
# ' = TXT fqdn:s:ttl:timestamp:lo  (Achtung, wenn innerhalb eines TXT Records ein Doppelpunkt Zeichen : auftritt, muss es als \072 geschrieben werden!)
# C = CNAME fqdn:p:ttl:timestamp:lo
# 6 = AAAA
# : = Generic record for fqdn  z.b. AAAA :cafeface.de:28:\052\000\030\050\040\000\001\040\000\000\000\000\000\000\000\002:3600
# = = fqdn:ip:ttl:timestamp:lo A und PTR

# +++ Fallstrick-Vermeidung +++
# Merke: Wenn innerhalb eines TXT Records ein Doppelpunkt Zeichen ":" auftritt, muss es als \072 geschrieben werden!
# IPv6 Records musst du auch oktal encodiert ablegen und den Type 28 verwenden.


# +++ gluecklicheadmins.de +++
Zgluecklicheadmins.de:ns1.finalmedia.de.:info.finalmedia.de.:1174921915:10800:3600:604800:600:3600
&gluecklicheadmins.de::ns1.finalmedia.de.:3600
&gluecklicheadmins.de::ns2.finalmedia.de.:3600
+gluecklicheadmins.de:159.69.122.236:3600
+demo.gluecklicheadmins.de:192.168.1.216:3600
@gluecklicheadmins.de::mail.finalmedia.de.:20:600
'gluecklicheadmins.de:v=spf1 mx include\072spf.finalmedia.de -all:500
+*.gluecklicheadmins.de:159.69.122.236:3600
Csmtp.gluecklicheadmins.de:mail.finalmedia.de:600
Cmail.gluecklicheadmins.de:mail.finalmedia.de:600
:gluecklicheadmins.de:28:\052\001\004\370\300\020\012\106\000\000\000\000\000\000\000\001:600


# +++ zufriedeneadmins.de +++
Zzufriedeneadmins:ns1.finalmedia.de.:info.finalmedia.de.:1174921915:10800:3600:604800:600:3600
&zufriedeneadmins.de::ns1.finalmedia.de.:3600
&zufriedeneadmins.de::ns2.finalmedia.de.:3600
+zufriedeneadmins.de:159.69.122.236:3600
+demo2.zufriedeneadmins.de:192.168.1.216:3600
@zufriedeneadmins.de::mail.finalmedia.de.:20:600
'zufriedeneadmins.de:v=spf1 mx include\072spf.finalmedia.de -all:500
+*.zufriedeneadmins.de:159.69.122.236:3600
Csmtp.zufriedeneadmins.de:mail.finalmedia.de:600
Cmail.zufriedeneadmins.de:mail.finalmedia.de:600
:zufriedeneadmins.de:28:\052\001\004\370\300\020\012\106\000\000\000\000\000\000\000\001:600


# alle anderen domains
# immer mit unbekannt antworten, statt client in timeout laufen zu lassen
&::a.root-servers.net

:::eof:::


cat << :::eof::: > /etc/tinydns/root/Makefile
data.cdb: data
	/usr/bin/tinydns-data
	md5sum data.cdb
:::eof:::


Und noch ein kleines Helper-Script, das aber nicht benötigt wird, wenn man den oben als alternative Quellencode genannte Version (IPv6 gepatcht) verwendet. Es ist also nur notwendig, wenn man djbs native Implementierung verwendet und AAAA Records daher in RAW Generic Type 28 octal codiert in der data File hinterlegt.


cat << :::eof::: > /etc/tinydns/ipv6_to_octal_syntax
#!/bin/sh
# reinhard@finalmedia.de
# Sat 13 Nov 2021 10:35:02 AM CET
#
# Dieses Script benoetigt: sipcalc, xxd, od, head, tr
#
test $# -lt 1 && echo "Beispielaufruf: \
$0 2a01:4f8:c010:a46::1" && exit 1
echo -n ":subdomain.domain:28:"
sipcalc "$1" | grep Expanded | cut -d- -f2 | \
tr -dc "0-9a-f\n" | xxd -ps -r | od -to1 | \
head -n1 | cut -c 8- | tr " " "\\" 2>/dev/null | \
tr -d "\n"
echo ":600"
:::eof:::

chmod +x /etc/tinydns/ipv6_to_octal_syntax

So. Nun erstellen wir noch einen zweiten Dienst, der dann als IPv6 Variante fungiert und an die öffentliche IPv6 Adresse deines Zielservers bindet. Hierzu verwenden wir für tinydns_ipv6 das gleiche root verzeichnis, das auch tinydns benutzt. Daten werden also nicht doppelt gepflegt. Für den zusätzlichen Service definieren wir lediglich eine individuelle env.


mkdir -p /etc/tinydns_ipv6/env
mkdir -p /etc/tinydns_ipv6/log/main
ln -s /etc/tinydns/root /etc/tinydns_ipv6/root
ln -s /etc/tinydns/env/ROOT /etc/tinydns_ipv6/env/ROOT
cp -rap /etc/tinydns/run /etc/tinydns_ipv6/run
cp -rap /etc/tinydns/log/run /etc/tinydns_ipv6/log/run

Wenn du die tinydnssec variante oder die reine ipv6 patch variante von fefe verwendenst, dann jetzt auch noch die ipv6 Variante konfigurieren. Hier ist nur die IP-Adresse anzupassen, an die die zweite Instanz binden soll. Rest bleibt gleich.

ACHTUNG! Ersetze natürlich an der Stelle "ACHTUNG_HIER_IPv6_ADRESSE_DES_SERVERS" natürlich durch die öffentliche IPv6 Adresse deines Servers. Alles andere so belassen.



echo "ACHTUNG_HIER_IPv6_ADRESSE_DES_SERVERS" > /etc/tinydns_ipv6/env/IP


Wie starte ich nun tinydns?

Einfach mittels daemontools. Beispiel: Unsere beiden neuen Dienste dauerhaft an den Start bringen


ln -s /etc/tinydns /etc/service/
ln -s /etc/tinydns_ipv6 /etc/service/

cd /etc/service

svstat tinydns
svstat tinydns_ipv6


Wie teste ich, ob mein dns server nun korrekt antwortet?



envdir /etc/tinydns/env sh -c 'dnsq A gluecklicheadmins.de $IP'

Oder auch bei dir auf deiner Workstation, wenn dein Zielserver öffentlich erreichbar ist und du z.b. dig aus den bind utils bei dir nutzt


dig gluecklicheadmins.de AAAA +short @IP_DES_SERVERS
dig gluecklicheadmins.de A +short @$IP_DES_SERVERS
dig gluecklicheadmins.de TXT +short @$IP_DES_SERVERS
dig demo.gluecklicheadmins.de A +short @$IP_DER_SERVERS

Wie trage ich neue Zonen oder Records ein?

Einfach auf dem neuen DNS Server die Datei data editieren. Danach die cdb file aktualisieren, indem du make aufrufst. Das führt letzlich nur ein /usr/bin/tinydns-data von der data zur data.cdb aus, und zwar nur, wenn es auch Änderungen gab an der data Datei. Also:


cd /etc/tinydns/root/
nano data
make

Ergänzungen

Wenn du die Zonen via LDAP verwalten willst, kannst Du dazu das tool ldap2dns (ldap2dns_0.3.1.tar.gz) verwenden und dort das -o flag, um tinydns kompatibele data files zu erzeugen, die dann mit tinydns-data wie gehabt zur cdb eingelesen werden können.