Master/Slave-Replikation mit bind9

Datum: 14. April 2021

Im Folgenden soll die Einrichtung einer Bind9-Replikation zwischen zwei Nameservern beschrieben werden (Schutzziel Verfügbarkeit), wobei die Kommunikation zwischen beiden schließlich mit TSIG abzusichern ist (Schutzziel Authentizität).

Master/Slave-Replikation

Ubuntu als bind9-Slave einrichten

Davon ausgehend, dass auf Debian 10 bereits eine bind9-Installation mit eigener Zone namens „dom1.test“ läuft, soll mit der Einrichtung des Slaves begonnen werden. Es handet sich dabei um Ubuntu 20.04, dass in Form eines LXC-Containers innerhalb von lxd eingerichtet wird:

tux@deb10srv:~$ id
uid=1000(tux) gid=1000(tux) Gruppen=1000(tux),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),998(lxd)
tux@deb10srv:~$ ##   >> ist u.a. Mitglied von "lxd"
tux@deb10srv:~$
tux@deb10srv:~$ lxc list
+------------+---------+------+-----------------------------------------------+-----------+-----------+
|    NAME    |  STATE  | IPV4 |                     IPV6                      |   TYPE    | SNAPSHOTS |
+------------+---------+------+-----------------------------------------------+-----------+-----------+
| alp-router | RUNNING |      | 2003:f4:e71f:9607:216:3eff:fe99:225b (eth0)   | CONTAINER | 0         |
|            |         |      | 2003:f4:e71f:2a30:216:3eff:fe99:225b (eth0)   |           |           |
+------------+---------+------+-----------------------------------------------+-----------+-----------+
| alp-server | RUNNING |      | fd42:1580:a049:8f28:216:3eff:fe76:3e68 (eth0) | CONTAINER | 0         |
+------------+---------+------+-----------------------------------------------+-----------+-----------+
tux@deb10srv:~$
tux@deb10srv:~$ lxc stop alp-router
tux@deb10srv:~$ lxc stop alp-server
tux@deb10srv:~$
tux@deb10srv:~$ lxc launch -p extbridge ubuntu:20.04 ubu-dns2
Creating ubu-dns2
Retrieving image: rootfs: 30% (6.91MB/s)
Starting ubu-dns2
tux@deb10srv:~$
tux@deb10srv:~$ lxc list
+------------+---------+------+---------------------------------------------+-----------+-----------+
|    NAME    |  STATE  | IPV4 |                    IPV6                     |   TYPE    | SNAPSHOTS |
+------------+---------+------+---------------------------------------------+-----------+-----------+
| alp-router | STOPPED |      |                                             | CONTAINER | 0         |
+------------+---------+------+---------------------------------------------+-----------+-----------+
| alp-server | STOPPED |      |                                             | CONTAINER | 0         |
+------------+---------+------+---------------------------------------------+-----------+-----------+
| ubu-dns2   | RUNNING |      | 2003:f4:e71f:2a30:216:3eff:fe54:1dc6 (eth0) | CONTAINER | 0         |
+------------+---------+------+---------------------------------------------+-----------+-----------+
tux@deb10srv:~$

tux@deb10srv:~$ ## Den laufenden Container betreten:
tux@deb10srv:~$ lxc exec ubu-dns2 bash
root@ubu-dns2:~#
root@ubu-dns2:~# pwd
/root
root@ubu-dns2:~#
root@ubu-dns2:~# ls -F /
bin@   dev/  home/  lib32@  libx32@  mnt/  proc/  run/   snap/  sys/  usr/
boot/  etc/  lib@   lib64@  media/   opt/  root/  sbin@  srv/   tmp/  var/
root@ubu-dns2:~#
root@ubu-dns2:~# du -sh /
du: cannot read directory '/dev/.lxd-mounts': Permission denied
du: cannot read directory '/proc/sys/fs/binfmt_misc': Permission denied
du: cannot read directory '/proc/tty/driver': Permission denied
du: cannot access '/proc/193/task/193/fd/4': No such file or directory
du: cannot access '/proc/193/task/193/fdinfo/4': No such file or directory
du: cannot access '/proc/193/fd/3': No such file or directory
du: cannot access '/proc/193/fdinfo/3': No such file or directory
du: cannot read directory '/sys/kernel/tracing': Permission denied
du: cannot read directory '/sys/kernel/debug': Permission denied
du: cannot read directory '/sys/fs/pstore': Permission denied
1.5G        /
root@ubu-dns2:~#
root@ubu-dns2:~# ##  >> Schön zu sehen, dass der Container nicht voll privilegiert ist.
root@ubu-dns2:~#
root@ubu-dns2:~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:16:3e:54:1d:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
root@ubu-dns2:~#
root@ubu-dns2:~# ##    >> Das Suffix "@if13" wird nicht benötigt, -> ignorieren.
root@ubu-dns2:~#
root@ubu-dns2:~# ip addr show dev eth0
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:54:1d:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 2003:f4:e71f:2a30:216:3eff:fe54:1dc6/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 14390sec preferred_lft 1790sec
    inet6 fe80::216:3eff:fe54:1dc6/64 scope link
       valid_lft forever preferred_lft forever
root@ubu-dns2:~#

root@ubu-dns2:~# ip addr add 192.168.2.231/24 dev eth0
root@ubu-dns2:~#
root@ubu-dns2:~# ip -4 addr show dev eth0
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link-netnsid 0
    inet 192.168.2.231/24 scope global eth0
       valid_lft forever preferred_lft forever
root@ubu-dns2:~#
root@ubu-dns2:~# ping -c2 192.168.2.225
PING 192.168.2.225 (192.168.2.225) 56(84) bytes of data.
64 bytes from 192.168.2.225: icmp_seq=1 ttl=64 time=0.236 ms
64 bytes from 192.168.2.225: icmp_seq=2 ttl=64 time=0.129 ms

--- 192.168.2.225 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.129/0.182/0.236/0.053 ms
root@ubu-dns2:~#

  ## Reboot tut gut (mit aktiviertem promiscuous Modus auf der kabelgebundenen Netzwerkbrücke)...

tux@deb10srv:~$
tux@deb10srv:~$ lxc list
+------------+---------+----------------------+---------------------------------------------+-----------+-----------+
|    NAME    |  STATE  |         IPV4         |                    IPV6                     |   TYPE    | SNAPSHOTS |
+------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| alp-router | RUNNING | 192.168.2.103 (eth0) | 2003:f4:e71f:2a30:216:3eff:fe99:225b (eth0) | CONTAINER | 0         |
+------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| alp-server | STOPPED |                      |                                             | CONTAINER | 0         |
+------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| ubu-dns2   | RUNNING | 192.168.2.104 (eth0) | 2003:f4:e71f:2a30:216:3eff:fe54:1dc6 (eth0) | CONTAINER | 0         |
+------------+---------+----------------------+---------------------------------------------+-----------+-----------+
tux@deb10srv:~$
tux@deb10srv:~$
tux@deb10srv:~$ lxc exec ubu-dns2 bash
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link-netnsid 0
    inet 192.168.2.104/24 brd 192.168.2.255 scope global dynamic eth0
       valid_lft 1806998sec preferred_lft 1806998sec
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# ps -A
  PID TTY          TIME CMD
    1 ?        00:00:00 systemd
   63 ?        00:00:00 systemd-journal
   85 ?        00:00:00 systemd-udevd
  112 ?        00:00:00 snapfuse
  113 ?        00:00:03 snapfuse
  114 ?        00:00:00 snapfuse
  163 ?        00:00:00 systemd-network
  165 ?        00:00:00 systemd-resolve
  179 ?        00:00:00 accounts-daemon
  182 ?        00:00:00 cron
  183 ?        00:00:00 dbus-daemon
  187 ?        00:00:00 networkd-dispat
  188 ?        00:00:00 rsyslogd
  191 ?        00:00:00 snapd
  193 ?        00:00:00 systemd-logind
  195 ?        00:00:00 atd
  202 console  00:00:00 agetty
  214 ?        00:00:00 sshd
  224 ?        00:00:00 polkitd
  229 ?        00:00:00 unattended-upgr
  354 pts/0    00:00:00 bash
  362 pts/0    00:00:00 ps
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# ## IP-Adressierung auf Ubunut-Art festschreiben:
root@ubu-dns2:~# vi /etc/netplan/50-cloud-init.yaml
root@ubu-dns2:~# cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init’s
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    renderer: networkd
    ethernets:
        eth0:
            dhcp4: false
            dhcp6: false
            addresses: [192.168.2.231/24]
            gateway4: 192.168.2.1
            nameservers:
                    addresses: [192.168.2.225]
root@ubu-dns2:~#
root@ubu-dns2:~# netplan apply
root@ubu-dns2:~#
root@ubu-dns2:~# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link-netnsid 0
    inet 192.168.2.231/24 brd 192.168.2.255 scope global eth0
       valid_lft forever preferred_lft forever
root@ubu-dns2:~#
root@ubu-dns2:~# ping -c3 ping.de
PING ping.de (83.97.42.2) 56(84) bytes of data.
64 bytes from lilly.ping.de (83.97.42.2): icmp_seq=1 ttl=54 time=23.2 ms
64 bytes from lilly.ping.de (83.97.42.2): icmp_seq=2 ttl=54 time=22.9 ms
64 bytes from lilly.ping.de (83.97.42.2): icmp_seq=3 ttl=54 time=23.1 ms

--- ping.de ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 22.867/23.055/23.227/0.147 ms
root@ubu-dns2:~#
root@ubu-dns2:~# ##  >> OK, es läuft mit dieser Konfiguration soweit...
root@ubu-dns2:~#
root@ubu-dns2:~# ## System aktualisieren, bind9 installieren:
root@ubu-dns2:~# apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
Get:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]

  (gekürzt)

Get:33 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 c-n-f Metadata [224 B]
Get:34 http://archive.ubuntu.com/ubuntu focal-backports/multiverse amd64 c-n-f Metadata [116 B]
Fetched 18.0 MB in 6s (2987 kB/s)
Reading package lists... Done
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following package was automatically installed and is no longer required:
  libfreetype6
Use 'apt autoremove' to remove it.
The following packages will be upgraded:
  alsa-ucm-conf apt apt-utils curl landscape-common libapt-pkg6.0 libcurl3-gnutls libcurl4 libnss-systemd libpam-systemd libsystemd0 libudev1
  open-vm-tools systemd systemd-sysv systemd-timesyncd ubuntu-keyring udev
18 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 9540 kB of archives.
After this operation, 506 kB of additional disk space will be used.
Do you want to continue? [Y/n]
Get:1 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libnss-systemd amd64 245.4-4ubuntu3.6 [95.8 kB]
Get:2 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 udev amd64 245.4-4ubuntu3.6 [1366 kB]
Get:3 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libudev1 amd64 245.4-4ubuntu3.6 [77.1 kB]
Get:4 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 systemd-sysv amd64 245.4-4ubuntu3.6 [10.3 kB]
Setting up libnss-systemd:amd64 (245.4-4ubuntu3.6) ...
Setting up libpam-systemd:amd64 (245.4-4ubuntu3.6) ...
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for dbus (1.12.16-2ubuntu2.1) ...
Processing triggers for initramfs-tools (0.136ubuntu6.4) ...
root@ubu-dns2:~#
root@ubu-dns2:~# apt-get install bind9 dnsutils
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
  libfreetype6
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  bind9-utils dns-root-data python3-ply
Suggested packages:
  bind-doc resolvconf python-ply-doc
The following NEW packages will be installed:
  bind9 bind9-utils dns-root-data dnsutils python3-ply
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 460 kB of archives.
After this operation, 1971 kB of additional disk space will be used.
Do you want to continue? [Y/n]

Adding group `bind’ (GID 119) ...
Done.
Adding system user `bind’ (UID 112) ...
Adding new user `bind’ (UID 112) with group `bind’ ...
Not creating home directory `/var/cache/bind’.
wrote key file "/etc/bind/rndc.key"
named-resolvconf.service is a disabled or a static unit, not starting it.
Created symlink /etc/systemd/system/bind9.service → /lib/systemd/system/named.service.
Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /lib/systemd/system/named.service.
Processing triggers for systemd (245.4-4ubuntu3.6) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for ufw (0.36-6) ...
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
root@ubu-dns2:~#
root@ubu-dns2:~# ##   >> Prima, es sind keine Paketfilterregeln vorhanden  :-)

Wenn Ubuntu als minimaler Secondary Nameserver (Slave) fungieren soll, ist im Prinzip nur die Zonendefinition erforderlich. Hierbei muss für unsere Domäne type slave; gesetzt werden, außerdem geben wir mittels masters { 192.168.2.225; }; bekannt, von welchem Rechner die Datensätze zu beziehen sind:

root@ubu-dns2:~# vi /etc/bind/named.conf.local
root@ubu-dns2:~# cat /etc/bind/named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "dom1.test" {
        type slave;
        masters { 192.168.2.225; };
};

root@ubu-dns2:~#
root@ubu-dns2:~# ## Wir befragen explizit unseren eigenen Nameserver (egal, was in der resolv.conf steht):
root@ubu-dns2:~# host alp-router.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

Host alp-router.dom1.test not found: 3(NXDOMAIN)
root@ubu-dns2:~#
root@ubu-dns2:~# ##     >> Ja klar, noch weiß er nichts davon.
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# ## Den named zum ersten Mals starten = "Datensätze herunterladen" (AXFR):
root@ubu-dns2:~# systemctl restart bind9
root@ubu-dns2:~#
root@ubu-dns2:~#

my@bash $ journalctl -f
-- Logs begin at Thu 2021-04-08 09:39:36 CEST. --
Apr 08 12:14:43 deb10srv named[486]: client @0x7f23180d5c40 192.168.2.231#51823 (dom1.test): transfer of 'dom1.test/IN': AXFR started (serial 2)
Apr 08 12:14:43 deb10srv named[486]: client @0x7f23180d5c40 192.168.2.231#51823 (dom1.test): transfer of 'dom1.test/IN': AXFR ended
Apr 08 12:15:01 deb10srv CRON[5428]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 08 12:15:01 deb10srv CRON[5429]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 08 12:15:01 deb10srv CRON[5428]: pam_unix(cron:session): session closed for user root

root@ubu-dns2:~# ## Was vorhin einen Fehler brachte, klappt jetzt:
root@ubu-dns2:~# host alp-router.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

alp-router.dom1.test has address 192.168.2.230
root@ubu-dns2:~#
root@ubu-dns2:~#
root@ubu-dns2:~# ##   >> Damit ist der Slave schon einsatzbereit.

Die Angabe des masters ist ausschlaggebend; notfalls kann sich der sekundäre Bind9-Server die Zonen-Datensätze beim Neustart selber ziehen, ohne vorher ein notify vom primären Server erhalten zu haben.

Ändert sich aber auf dem Master etwas, erfährt es der Slave allerdings noch nicht!

Debian für bind9-Master anpassen

Die nächsten Schritte auf dem primären Masterserver Debian 10 sind folgende:

  1. In der Zonendefinition für dom1.test (named.conf.local) hinzuzufügen: notify yes;

  2. In der Zonendatei (db.dom1.test) hinzuzufügen:

    • @         IN    NS      ubu-dns2.dom1.test.

    • ubu-dns2  IN    A       192.168.2.231

Zuerst tragen wir also in der Zonendefinition notify yes; ein, danach müssen wir den Slave in die Zone mit einem NS- und einem A-Record ausstatten:

my@bash $ vi /etc/bind/named.conf.local
my@bash $
my@bash $ nl /etc/bind/named.conf.local
     1      //
     2      // Do any local configuration here
     3      //

     4      // Consider adding the 1918 zones here, if they are not used in your
     5      // organization
     6      //include "/etc/bind/zones.rfc1918";

     7      zone "dom1.test" {
     8              type master;
     9              notify yes;
    10              file "/etc/bind/db.dom1.test";
    11      };

    12      zone "2.168.192.in-addr.arpa" {
    13              type master;
    14              notify yes;
    15              file "/etc/bind/db.192.168.2";
    16      };
my@bash $
my@bash $ ##   >> Zeilen 9 und 14 sind neu hinzugekommen


my@bash $ vi /etc/bind/db.dom1.test
my@bash $
my@bash $ nl /etc/bind/db.dom1.test
     1      $TTL    604800
     2      @       IN      SOA     deb10srv.dom1.test. root.deb10srv.dom1.test. (
     3                                    4         ; Serial
     4                               604800         ; Refresh
     5                                86400         ; Retry
     6                              2419200         ; Expire
     7                               604800 )       ; Negative Cache TTL
     8      ;
     9      @               IN      NS      deb10srv.dom1.test.
    10      @               IN      NS      ubu-dns2.dom1.test.

    11      deb10srv        IN      A       192.168.2.225
    12      ubu-dns2        IN      A       192.168.2.231

    13      ; Weitere Records für andere Hosts...
    14      alp-router      IN      A       192.168.2.230
    15      winhost         IN      A       10.2.3.4
    16      alp-server      IN      A       10.1.1.2
my@bash $
my@bash $
my@bash $ ##   >> In  Zeile 3 wurde der Serial-Wert erhöht,
my@bash $ ##   die Zeilen 10 und 12 sind neu hinzugekommen.
my@bash $
my@bash $ rndc reload
server reload successful
my@bash $

Via ‚journalctl -f‘ sehen wir hier auf dem Slave, dass etwas übertragen wurde:

Apr 09 06:29:50 ubu-dns2 named[194]: client @0x7febdc01df80 192.168.2.225#37921: received notify for zone 'dom1.test'
Apr 09 06:29:50 ubu-dns2 named[194]: zone dom1.test/IN: notify from 192.168.2.225#37921: serial 4
Apr 09 06:29:50 ubu-dns2 named[194]: zone dom1.test/IN: Transfer started.
Apr 09 06:29:50 ubu-dns2 named[194]: transfer of 'dom1.test/IN' from 192.168.2.225#53: connected using 192.168.2.231#35239
Apr 09 06:29:50 ubu-dns2 named[194]: zone dom1.test/IN: transferred serial 4
Apr 09 06:29:50 ubu-dns2 named[194]: transfer of 'dom1.test/IN' from 192.168.2.225#53: Transfer status: success
Apr 09 06:29:50 ubu-dns2 named[194]: transfer of 'dom1.test/IN' from 192.168.2.225#53: Transfer completed: 1 messages, 9 records, 260 bytes, 0.001 secs (260000 bytes/sec)
Apr 09 06:29:50 ubu-dns2 named[194]: zone dom1.test/IN: sending notifies (serial 4)

root@ubu-dns2:~ # host alp-server.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

alp-server.dom1.test has address 10.1.1.2
root@ubu-dns2:~ #
root@ubu-dns2:~ # ##   >> Die Auflösung klappt nun auf dem Slave einwandfrei.
root@ubu-dns2:~ #
root@ubu-dns2:~ # ## Zum Test, ob auch kleine Änderungen an bestehenden Datensätzen repliziert werden:
root@ubu-dns2:~ # host winhost.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

winhost.dom1.test has address 10.2.3.4
root@ubu-dns2:~ #
root@ubu-dns2:~ # ##    >> Es kommt derzeit noch die alte Adresse 10.2.3.4 zurück.

Nun änderen wir diesen Datensatz auf dem Master:

my@bash $ vi /etc/bind/db.dom1.test

my@bash $ grep winhost /etc/bind/db.dom1.test
winhost             IN      A       111.222.33.244
my@bash $
my@bash $ grep Serial /etc/bind/db.dom1.test
                          5         ; Serial
my@bash $
my@bash $ rndc reload
server reload successful
my@bash $
my@bash $
my@bash $ ## Aus dem Journal des Masters:
Apr 09 08:38:57 deb10srv named[501]: reloading configuration succeeded
Apr 09 08:38:57 deb10srv named[501]: reloading zones succeeded
Apr 09 08:38:57 deb10srv named[501]: zone dom1.test/IN: loaded serial 5
Apr 09 08:38:57 deb10srv named[501]: zone dom1.test/IN: sending notifies (serial 5)
Apr 09 08:38:57 deb10srv named[501]: all zones loaded
Apr 09 08:38:57 deb10srv named[501]: running
Apr 09 08:38:57 deb10srv named[501]: client @0x7f07bc0d5c40 192.168.2.231#50565 (dom1.test): transfer of 'dom1.test/IN': AXFR-style IXFR started (serial 5)
Apr 09 08:38:57 deb10srv named[501]: client @0x7f07bc0d5c40 192.168.2.231#50565 (dom1.test): transfer of 'dom1.test/IN': AXFR-style IXFR ended
Apr 09 08:38:59 deb10srv named[501]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Apr 09 08:38:59 deb10srv named[501]: resolver priming query complete

my@bash $ host winhost
winhost.dom1.test has address 111.222.33.244
my@bash $
my@bash $ ##    >> Klarer Fall: der Master weiß es natürlich schon...

Nun kommt der Test auf dem Slave, der aber auch schon erfolgreich ist:

root@ubu-dns2:~ # host winhost.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

winhost.dom1.test has address 111.222.33.244
root@ubu-dns2:~ #
root@ubu-dns2:~ # ##    >> Die neue Adresse ist dem Slave jetzt ebenfalls bekannt: 111.222.33.244

Zusammenfassung Master/Slave

  • Slave:

    • Zonendefinition mit „slave“ und „masters“ zur named.conf hinzugefügt

    • systemctl restart bind9, -> schon lädt er sich die Datensaätze vom Master herunter

  • Master:

    • In der Zonendatei den neuen Slave mit NS und A bekanntgegeben

    • In den Zonendefinitionen „notify yes;“ hinzugefügt

    • rndc reload, -> und schon werden die Slaves informiert (Serial-Werterhöhung!)

Master/Slave via TSIG absichern

HINWEIS: Es geht hier NICHT um Vertraulichkeit (Datenpakete verschlüsseln), sondern nur um die Beglaubigung der Identitäten, also das Schutzziel „Authentizität“.

Primary/Master = Debian 10

Auf dem Master einen symmetrischen Schlüssel erzeugen:

my@bash $ dnssec-keygen -a HMAC-MD5 -b 512 -n HOST rndc-key
Krndc-key.+157+48660
my@bash $

Bei neueren bind9-Versionen wie bei Ubuntu oder SuSE funktioniert das allerdings anders:

root@ubu-dns2:~ # dnssec-keygen -a HMAC-MD5 -b 512 -n HOST rndc-key
dnssec-keygen: fatal: unknown algorithm "
root@ubu-dns2:~ # ##     >> Aber bitte trotzdem merken: "dnssec-keygen -a HMAC-MD5 ..." ist LPI-relevant!
root@ubu-dns2:~ # ##                                                      ========
root@ubu-dns2:~ #
root@ubu-dns2:~ # whatis tsig-keygen
tsig-keygen (8)      - ddns key generation tool
root@ubu-dns2:~ # ##    >> wegen dem unsicher gewordenem MD5 (Kollisionsprobleme!)

Das neue Kommando benötigt keine Optionen, es erzeugt direkt den Konfigrationsabschnitt, am besten gleich mit SHA512:

root@ubu-dns2:~ # tsig-keygen -a hmac-sha512
key "tsig-key" {
    algorithm hmac-sha512;
    secret "HI8hXf1DZk8TflLQXG7v0oGvleTpqhBJBcU3le6SAroRXuxhbqQZcQUQ7AF0HRnlqDzna82aIoLypgrwRHK0Vw==";
};
root@ubu-dns2:~ #

Das erledigen wir aber lieber auf dem Debian-Master, dort gibt es das neue Kommando auch:

my@bash $ tsig-keygen -a hmac-sha512 > tsig.key
my@bash $
my@bash $ cat /etc/bind/tsig.key
key "tsig-key" {
    algorithm hmac-sha512;
    secret "4wfQL5tLrPvXWZFKX7rBzbcZ+etfvnqSGoSSX4muJMBq8B/CkS+3EpP+J0IWFH1ZhpfFBFBGp/j+UPyn41QNVA==";
};
my@bash $
my@bash $ ## Datei anpassen, um mittels 'server' den entfernten Server zu spezifizieren:
my@bash $ vi  /etc/bind/tsig.key

my@bash $ cat /etc/bind/tsig.key
key "tsig-key" {
    algorithm hmac-sha512;
    secret "4wfQL5tLrPvXWZFKX7rBzbcZ+etfvnqSGoSSX4muJMBq8B/CkS+3EpP+J0IWFH1ZhpfFBFBGp/j+UPyn41QNVA==";
};

# Slave server IP # 1
server 192.168.2.231 {
        keys {
                tsig-key;
    };
};
my@bash $

Diese Datei müssen wir nun inkludieren:

my@bash $ echo 'include "/etc/bind/tsig.key";' >> /etc/named.conf
my@bash $
my@bash $ ## Dateirechte kontrollieren/anpassen:
my@bash $ chmod 640 /etc/bind/tsig.key
my@bash $
my@bash $ pwd
/etc/bind
my@bash $
my@bash $ ls -l tsig.key
-rw-r----- 1 root bind 241 Apr  9 12:03 tsig.key
my@bash $
my@bash $ chown bind: tsig.key
my@bash $
my@bash $ systemctl restart bind9
my@bash $
my@bash $ systemctl status bind9
● bind9.service - BIND Domain Name Server
   Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2021-04-09 12:06:43 CEST; 15s ago
     Docs: man:named(8)
  Process: 2675 ExecStart=/usr/sbin/named $OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 2676 (named)
    Tasks: 4 (limit: 545)
   Memory: 13.1M
   CGroup: /system.slice/bind9.service
           └─2676 /usr/sbin/named -u bind

Apr 09 12:06:42 deb10srv named[2676]: zone 2.168.192.in-addr.arpa/IN: loaded serial 1
Apr 09 12:06:42 deb10srv named[2676]: zone 255.in-addr.arpa/IN: loaded serial 1
Apr 09 12:06:42 deb10srv named[2676]: zone 127.in-addr.arpa/IN: loaded serial 1
Apr 09 12:06:43 deb10srv named[2676]: zone localhost/IN: loaded serial 2
Apr 09 12:06:43 deb10srv named[2676]: all zones loaded
Apr 09 12:06:43 deb10srv systemd[1]: Started BIND Domain Name Server.
Apr 09 12:06:43 deb10srv named[2676]: running
Apr 09 12:06:43 deb10srv named[2676]: zone dom1.test/IN: sending notifies (serial 5)
Apr 09 12:06:44 deb10srv named[2676]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Apr 09 12:06:44 deb10srv named[2676]: resolver priming query complete
my@bash $

Den neuen Schlüssel ‚tsig-key‘ als Kriterium für erlaubte AXFR-Transfers mittels allow-transfer heranziehen:

my@bash $ vi named.conf.local
my@bash $
my@bash $ ## Die Zeile "allow-transfer { key tsig-key; };" wurde 2x eingefügt:
my@bash $ cat named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "dom1.test" {
    type master;
    notify yes;
    allow-transfer { key tsig-key; };
    file "/etc/bind/db.dom1.test";
};

zone "2.168.192.in-addr.arpa" {
    type master;
    notify yes;
    allow-transfer { key tsig-key; };
    file "/etc/bind/db.192.168.2";
};
my@bash $
my@bash $
my@bash $ named-checkconf && echo OK
OK
my@bash $ systemctl restart bind9

Der entfernte Slave nun versucht nun, sich die Datensätze komplett neu herunterzuladen:

root@ubu-dns2:~ # systemctl restart bind9
root@ubu-dns2:~ #
root@ubu-dns2:~ # journalctl -f

  (gekürzt)

Apr 09 12:15:01 deb10srv named[2737]: client @0x7f3b1c0d6710 192.168.2.231#47143 (dom1.test): zone transfer 'dom1.test/AXFR/IN' denied
Apr 09 12:15:51 deb10srv named[2737]: client @0x7f3b1c0d6710 192.168.2.231#56975 (dom1.test): zone transfer 'dom1.test/AXFR/IN' denied

Richtig, es geht nicht mehr, wir erhalten nun den Fehler „zone transfer ‚dom1.test/AXFR/IN‘ denied“!

Secondary/Slave (Ubuntu 20.04)

Weiter gehts nun auf dem sekundären DNS-Server, die einzelnen Schritte sind:

  • Die /etc/bind/tsig.key auf sichere Weise zum Secondary DNS-Server kopieren

  • Die kopierte Datei anpassen und inkludieren (bei ‚server‘ die IP-Adresse von Debian angeben)

  • Rechte anpassen (Owner des bind9-Prozesses)

  • Daemon neu starten, testen…

root@ubu-dns2:~ # vi /etc/bind/tsig.key
root@ubu-dns2:~ #
root@ubu-dns2:~ # cat /etc/bind/tsig.key
key "tsig-key" {
    algorithm hmac-sha512;
    secret "4wfQL5tLrPvXWZFKX7rBzbcZ+etfvnqSGoSSX4muJMBq8B/CkS+3EpP+J0IWFH1ZhpfFBFBGp/j+UPyn41QNVA==";
};

# Master server IP:
server 192.168.2.225 {
        keys {
                tsig-key;
    };
};
root@ubu-dns2:~ #
root@ubu-dns2:~ # ##    >> Lediglich die IP ist anzupassen.
root@ubu-dns2:~ #
root@ubu-dns2:~ # chmod 640 /etc/bind/tsig.key
root@ubu-dns2:~ # chown bind: /etc/bind/tsig.key
root@ubu-dns2:~ #
root@ubu-dns2:~ # echo 'include "/etc/bind/tsig.key";' >> /etc/bind/named.conf
root@ubu-dns2:~ #
root@ubu-dns2:~ # systemctl restart bind9
root@ubu-dns2:~ #
root@ubu-dns2:~ # host winhost.dom1.test 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases:

winhost.dom1.test has address 123.123.123.123
root@ubu-dns2:~ #
root@ubu-dns2:~ #  ##    >> jetzt läuft es wieder...
root@ubu-dns2:~ #
root@ubu-dns2:~ #

my@bash $ ## Aus dem Journal des Masters:
my@bash $
Apr 09 14:46:47 deb10srv named[1450]: automatic empty zone: HOME.ARPA
Apr 09 14:46:47 deb10srv named[1450]: none:106: 'max-cache-size 90%' - setting to 435MB (out of 483MB)
Apr 09 14:46:47 deb10srv named[1450]: configuring command channel from '/etc/bind/rndc.key'
Apr 09 14:46:47 deb10srv named[1450]: configuring command channel from '/etc/bind/rndc.key'
Apr 09 14:46:47 deb10srv named[1450]: reloading configuration succeeded
Apr 09 14:46:47 deb10srv named[1450]: reloading zones succeeded
Apr 09 14:46:47 deb10srv named[1450]: all zones loaded
Apr 09 14:46:47 deb10srv named[1450]: running
Apr 09 14:46:47 deb10srv named[1450]: zone dom1.test/IN: loaded serial 7
Apr 09 14:46:47 deb10srv named[1450]: zone dom1.test/IN: sending notifies (serial 7)
Apr 09 14:46:47 deb10srv named[1450]: client @0x7eff600d64e0 192.168.2.231#37019/key tsig-key (dom1.test): transfer of 'dom1.test/IN': AXFR-style IXFR started: TSIG tsig-key (serial 7)
Apr 09 14:46:47 deb10srv named[1450]: client @0x7eff600d64e0 192.168.2.231#37019/key tsig-key (dom1.test): transfer of 'dom1.test/IN': AXFR-style IXFR ended
Apr 09 14:46:48 deb10srv named[1450]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Apr 09 14:46:48 deb10srv named[1450]: resolver priming query complete

my@bash $

Alles bestens…

Zusammenfassung/Übung (scripting fähig)

Anstelle der Kommandozeile dnssec-keygen -a HMAC-MD5 -b 512 -n HOST rndc-key (LPI-relevant!) soll das modernere tsig-keygen verwendet werden. Dabei ist die folgende Zusammenfassung zugleich auch als Übung nutzbar.

a) Master (Debian LXD-Host, IP: 192.168.2.225)

my@bash $ tsig-keygen -a hmac-sha512 > /etc/bind/tsig.key
my@bash $ PS2=""
my@bash $ cat >> /etc/bind/tsig.key <<EOF

# Slave server IP Nr. 1:
server 192.168.2.231 {
        keys {
                tsig-key;
    };
};
EOF
my@bash $
my@bash $ echo 'include "/etc/bind/tsig.key";' >> /etc/bind/named.conf
my@bash $ chmod 640 /etc/bind/tsig.key
my@bash $ chown bind: /etc/bind/tsig.key
my@bash $ sed  '/file /i\\tallow-transfer { key tsig-key; };' /etc/bind/named.conf.local
my@bash $ systemctl restart bind9
my@bash $ scp /etc/bind/tsig.key tux@192.168.2.231:   ## Auf dem Ziel muss /usr/sbin/sshd laufen!
  ...
my@bash $

b) Slave (Ubuntu Container, IP: 192.168.2.231)

my@bash $ mv /home/tux/tsig.key /etc/bind/
my@bash $ sed -i 's/192.168.2.231/192.168.2.225/' /etc/bind/tsig.key
my@bash $ chown bind: /etc/bind/tsig.key
my@bash $ systemctl restart bind9

Zum Vergleich sind hier die relevanten Dateien des Masters samt Inhalt:

my@bash $ cat /etc/bind/tsig.key
key "tsig-key" {
    algorithm hmac-sha512;
    secret "4wfQL5tLrPvXWZFKX7rBzbcZ+etfvnqSGoSSX4muJMBq8B/CkS+3EpP+J0IWFH1ZhpfFBFBGp/j+UPyn41QNVA==";
};

# Slave server IP # 1
server 192.168.2.231 {
        keys {
                tsig-key;
    };
};
my@bash $
my@bash $
my@bash $
my@bash $ cat /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/tsig.key";
my@bash $
my@bash $
my@bash $
my@bash $ cat /etc/bind/named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "dom1.test" {
    type master;
    notify yes;
    allow-transfer { key tsig-key; };
    file "/etc/bind/db.dom1.test";
};

zone "2.168.192.in-addr.arpa" {
    type master;
    notify yes;
    allow-transfer { key tsig-key; };
    file "/etc/bind/db.192.168.2";
};
my@bash $
my@bash $
my@bash $
my@bash $ cat /etc/bind/db.dom1.test
$TTL        604800
@   IN      SOA     deb10srv.dom1.test. root.deb10srv.dom1.test. (
                         10         ; Serial
                     604800         ; Refresh
                      86400         ; Retry
                    2419200         ; Expire
                     604800 )       ; Negative Cache TTL
;
@           IN      NS      deb10srv.dom1.test.
@           IN      NS      ubu-dns2.dom1.test.

deb10srv    IN      A       192.168.2.225
ubu-dns2    IN      A       192.168.2.231

; Weitere Records für andere Hosts...
alp-router  IN      A       192.168.2.230
winhost             IN      A       123.0.0.99
alp-server  IN      A       10.1.1.2
my@bash $

Und dies sind die relevanten Dateien des Slaves:

root@ubu-dns2:~ # cat /etc/bind/tsig.key
key "tsig-key" {
    algorithm hmac-sha512;
    secret "4wfQL5tLrPvXWZFKX7rBzbcZ+etfvnqSGoSSX4muJMBq8B/CkS+3EpP+J0IWFH1ZhpfFBFBGp/j+UPyn41QNVA==";
};

# Master server IP:
server 192.168.2.225 {
        keys {
                tsig-key;
    };
};
root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ # cat /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/tsig.key";
root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ # cat /etc/bind/named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "dom1.test" {
        type slave;
        masters { 192.168.2.225; };
};

root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ #
root@ubu-dns2:~ # cat /etc/bind/db.dom1.test
cat: /etc/bind/db.dom1.test: No such file or directory
root@ubu-dns2:~ #
root@ubu-dns2:~ # ##   >> Richtig: die vierte Datei gibt es hier nicht!

Have a lot of fun…