====== DNS Zone-Transfers mit TSIG absichern ====== ===== Überlegungen ===== ==== Authorisierung ==== Klassisch werden Zone-Transfers dadurch authorisiert, dass die IP-Adresse (oder der Hostname) eines zum Zone-Transfer berechtigten Client-Systems (z.B. Secondary DNS, Monitoring Server, Admin Workstation) in "allow-transfer {};" eingetragen wird. Bei der Verwendung von TSIG übernimmt ein Shared Key die Authorisierung: ist der Request zum Zone-Transfer hiermit (mittels HMAC) signiert, geht der Server (meist: Primary DNS) davon aus, dass die Gegenstelle legitim ist. Und zwar unabhängig von der IP-Adresse des Clients. Das ist das Setup, wie es auf vielen Anleitungsseiten beschrieben ist. Nun wird der Shared Key häufig an eine andere Stelle übermittelt: den Provider, der die Frontend-Nameserver in einem Hidden-Primary-Setup stellt, den Provider oder guten Kumpel, der einem einen Secondary Nameserver bereit stellt. Und damit verlässt der Shared Key den eigenen Einflußbereich. Man hat keine Kontrolle mehr darüber, was mit dem Shared Key geschieht. Es bedarf also einer Möglichkeit, den angeforderten Zone-Transfer auf beides zu prüfen: korrekten Schlüssel und korrekte Client-IP-Adresse. Tatsächlich hält das [[https://ftp.isc.org/isc/bind9/cur/9.10/doc/arm/Bv9ARM.html|BIND 9 Administrator Reference Manual]] die [[https://ftp.isc.org/isc/bind9/cur/9.10/doc/arm/Bv9ARM.ch04.html#id-1.5.6.8|Lösung]] bereit. Für das diskutierte Problem lautet sie: allow-transfer { !{ !"acl-xfer-allowed"; any; }; key "key-name"; }; bzw. allow-transfer { !{ !10.0.0.1; any; }; key "key-name"; }; Das ist grob die syntaktisch etwas verbastelte Ansage: Sperre (!), was die folgende Bedingung erfüllt: NICHT (!) 10.0.0.1 oder beliebig (any) Damit werden alle Requests abgewiesen, die NICHT 10.0.0.1 entsprechen, ohne fuer 10.0.0.1 eine Entscheidung getroffen zu haben. Anschließend kann der Request bei passendem Key verifiziert werden, womit die gewünschte AND-Verknüpfung erreicht ist. Für ausschliesslichen TSIG-Betrieb ist das ausreichend. === Alternative Authorisierung mit TSIG oder IP-Adresse === Soll parallel ebenfalls mit nur der IP-Adresse des Clients authorisiert werden koennen, ergeben sich zwei Moeglichkeiten: * die zur Authorisierung hinreichenden IP-Adressen werden vorgenannt: allow-transfer { 10.0.1.1; 2000:1:1::1; !{ !10.0.0.1; any; }; key "key-name"; }; * der Ausdruck fuer den Key wird gekapselt: allow-transfer { { !{ !10.0.0.1; any; }; key "key-name"; }; 10.0.1.1; 2000:1:1::1; }; === Authorisierung fuer mehrere IP-Adressen mit dem selben Key === allow-transfer { !{ !10.0.0.1; !10.0.0.2; any; }; key "key-name"; }; ==== Namen der Schlüssel ==== Wenn der Shared Key mit einer fremden Gegenstelle (z.B. Provider) getauscht wird, lohnt es, sich Gedanken um den Namen machen. Der erste Ansatz mag sein, den Key einfach "provider" zu nennen. Das Problem ist, dass dies für den Provider nicht skaliert: er kann keine zwei Keys mit demselben Namen verwalten. Aus demselben Grund ist ein Name der Form "eigene-site" ebenfalls nicht sinnvoll, denn dann steht man selbst vor diesem Problem. Das fällt evtl. erst auf, wenn man einen zweiten Anbieter für Secondary Nameseerver hat - aber dann richtig. Auf der sicheren Seite ist man, wenn der Keyname die Hostnamen (als FQDN) der beiden beteiligten Rechner enthält. Die Verwendung der Domains selbst im Keynamen scheitert, sobald mehrere Domains beteiligt sind, denn es kann nur ein Keyname pro Server genutzt werden (auch wenn mehrere eingetragen werden können, zählt nur der erste). Ich habe mich schließlich entschieden für das Schema: k..-- für einzelne Secondary-DNS bzw. für multiple Secondaries: k.-- Das Trennstring "--" ergab sich aus der Anforderung, die Domainnamen voneinander zu trennen. ===== Erzeugen und Ausrollen der TSIG Keys ===== ** Dies sind Notizen, die ich waehrend der Einrichtung gemacht habe, ** ** diese sind nicht unbedingt korrekt oder vollstaendig! ** Auf dem Primary DNS: AXFRSERVER="ns.mydoma.in" AXFRSERVERIPS="10.0.0.1 fc00::6e73" AXFRCLIENT="provider.net" AXFRCLIENTIPS="10.1.0.1 10.2.0.1 10.3.0.1" KEYID="k.$AXFRSERVER--$AXFRCLIENT" echo $KEYID DIR=$( mktemp -d /tmp/tsig-XXXXXXXX ) ls -ld $DIR cd $DIR KEYFILENAME=$( dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST -r /dev/urandom "$KEYID" ) echo $KEYFILENAME KEY=$( awk '$1 == "Key:" { print $2 }' $KEYFILENAME.private ) echo $KEY cd - rm -rf "$DIR" touch /etc/bind/$KEYID vo -o /etc/bind/$KEYID cat << EOF > /etc/bind/$KEYID key "$KEYID" { algorithm HMAC-SHA512; secret "${KEY}"; }; // only the secondary needs those // but so we have one file generated for both roles EOF for i in $AXFRSERVERIPS ; do cat << EOF >> /etc/bind/$KEYID //#server $i { //# keys { "$KEYID"; }; //#}; EOF done cat /etc/bind/$KEYID vo -i /etc/bind/$KEYID vo /etc/bind/named.conf.local +include "/etc/bind/k.ns.mydoma.in--provider.net"; vo /etc/bind/named.conf.local acl zone-xfer-allowed { +{ !{ + !10.1.0.1; // from $AXFRCLIENTIPS + !10.2.0.1; // from $AXFRCLIENTIPS + !10.3.0.1; // from $AXFRCLIENTIPS + any; // catchall +}; key "k.ns.mydoma.in--provider.net"; }; # load new config: rndc reconfig Auf den Secondary DNS: * Kopieren der Datei /etc/bind/k.ns.mydoma.in--provider.net vom Primary DNS AXFRSERVER="ns.mydoma.in" AXFRCLIENT="provider.net" KEYID="k.$AXFRSERVER--$AXFRCLIENT" echo $KEYID vo -o /etc/bind/k.ns.mydoma.in--provider.net sed -i 's:^//#::' /etc/bind/k.ns.mydoma.in--provider.net vo -i /etc/bind/k.ns.mydoma.in--provider.net vo /etc/bind/named.conf.local +include "/etc/bind/k.ns.mydoma.in--provider.net"; # load new config: rndc reconfig