[dn42] AS4242420263 configuration - DNS with bind (Part 4/5)

Posted on Sep 1, 2024

This article is the 4th part of my dn42 experiment, it describes the configuration of a primary and secondary DNS servers, using bind under Debian 12.

For a DNS crash course, check this presentation by Stéphane Bortzmeyer.

My bind servers are configured using ansible, see my bind role, my zone files and inventory hosts files for gw-dn42 and gw2-dn42.

My bind servers cumulate several roles:

  • recursive resolvers/forwarders for all my dn42 hosts, to resolve official clearnet TLDs as well as the .dn42 TLD
  • authoritative name servers, to hold my zones hcartiaux.dn42 and the reverse zones of my networks 160/27.144.22.172.in-addr.arpa + 1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa

For real world applications, I recommend to read this guide published by ANSSI in August 2024. Especially, a good security practice would be to compartmentalize and separate the roles on distinct servers. Also, DNSSEC should be enabled, it is supported on dn42 but not described here.

This post is based on the official documentation pages about DNS within dn42 here and here.

Reminder

Registry - data/dns/hcartiaux.dn42

Remember in part 1, I’ve registered the domain name hcartiaux.dn42:

domain:             hcartiaux.dn42
admin-c:            HCARTIAUX-DN42
tech-c:             HCARTIAUX-DN42
mnt-by:             HCARTIAUX-MNT
nserver:            ns1.hcartiaux.dn42 172.22.144.161
nserver:            ns1.hcartiaux.dn42 fd28:7515:7d51:a::1
nserver:            ns2.hcartiaux.dn42 172.22.144.177
nserver:            ns2.hcartiaux.dn42 fd28:7515:7d51:c::1
source:             DN42

I’ve declared two name servers, ns1.hcartiaux.dn42 hosted gw-dn42 and ns2.hcartiaux.dn42 hosted on gw2-dn42.

I’ve chosen not to create dedicated servers/VMs for the name servers, because it’s overkill and my resources are limited, but it’s definitely recommended otherwise.

Network info

IP BlockPrimary name serverSecondary name server
fd28:7515:7d51::/48fd28:7515:7d51:a::1fd28:7515:7d51:c::1
172.22.144.160/27172.22.144.161172.22.144.177

dn42 recursive name servers

dig -tSRV _dns._udp.recursive-servers.dn42. @172.20.0.53
NameIPv4IPv6
a0.recursive-servers.dn42.172.20.0.53fd42:d42:d42:54::1
a3.recursive-servers.dn42.172.23.0.53fd42:d42:d42:53::1
b.recursive-servers.dn42.172.20.129.2fd42:4242:2601:ac53::53
j.recursive-servers.dn42.172.20.1.255fd42:5d71:219:0:216:3eff:fee8:c215
k.recursive-servers.dn42.172.20.14.33fdcf:8538:9ad5:1111::1
l.recursive-servers.dn42.172.22.108.53fd86:bad:11b7:53::2
t.recursive-servers.dn42.172.22.76.110fdbc:f9dc:67ad:2547::53

Bind installation

apt install bind9 bind9-utils
systemctl enable --now named

Bind tips

If you can’t figure out why the named daemon does not start, you can:

  • Check the configuration
named-checkconf /etc/bind/named.conf.local
  • Check your zone syntax
named-checkzone hcartiaux.dn42 /etc/bind/db.hcartiaux.dn42
  • Check the logs
journalctl -u named.service
  • Query a specific name server, request all the records of a zone
dig ANY hcartiaux.dn42. @172.20.129.1
  • Query a specific name server, request all the AAAA records of a host
dig -tAAAA librenms.hcartiaux.dn42. @fd42:d42:d42:53::1

Zones

Let’s prepare the zone files for the next sections, they are copied on the primary name server.

hcartiaux.dn42 (/etc/bind/db.hcartiaux.dn42)

This is a regular DNS zone, nothing particular here.

$ORIGIN  hcartiaux.dn42.
$TTL     300
@        3600  IN SOA   ns1.hcartiaux.dn42. hostmaster.hcartiaux.dn42. (
                        2024062100 ; Serial
                        10800      ; Refresh
                        3600       ; Retry
                        604800     ; Expire
                        300 )      ; Negative Cache TTL

; hcartiaux DN42 infrastructure
@              IN NS    ns1.hcartiaux.dn42.
@              IN NS    ns2.hcartiaux.dn42.
@              IN AAAA  fd28:7515:7d51:a::1
@              IN A     172.22.144.161
ns1            IN AAAA  fd28:7515:7d51:a::1
ns1            IN A     172.22.144.161
ns2            IN AAAA  fd28:7515:7d51:c::1
ns2            IN A     172.22.144.177

IPv4 reverse zone (/etc/bind/db.160-27.144.22.172.in-addr.arpa)

My IPv4 prefix is 172.22.144.160/27. The reverse zone name is in the form of <byte 4>-<netmask>.<byte 3>.<byte 2>.<byte 1>.in-addr.arpa. In this case: 160/27.144.22.172.in-addr.arpa

$ORIGIN  160/27.144.22.172.in-addr.arpa.
$TTL     300
@        3600  IN SOA   ns1.hcartiaux.dn42. hostmaster.hcartiaux.dn42. (
                        2024070600 ; Serial
                        10800      ; Refresh
                        3600       ; Retry
                        604800     ; Expire
                        300 )      ; Negative Cache TTL

@              IN NS    ns1.hcartiaux.dn42.
@              IN NS    ns2.hcartiaux.dn42.

161            IN PTR   ns1.hcartiaux.dn42.
177            IN PTR   ns2.hcartiaux.dn42.

IPv6 reverse zone (/etc/bind/db.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa)

My IPv6 prefix is fd28:7515:7d51::/48, the reverse zone name is based on the expanded and reverse prefix, in my case:

  1. Expanded prefix: f.d.2.8.7.5.1.5.7.d.5.1
  2. Reversed prefix: 1.5.d.7.5.1.5.7.8.2.d.f
  3. Reverse zone name: 1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa.
$ORIGIN  1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa.
$TTL     300
@        3600  IN SOA   ns1.hcartiaux.dn42. hostmaster.hcartiaux.dn42. (
                        2024070600 ; Serial
                        10800      ; Refresh
                        3600       ; Retry
                        604800     ; Expire
                        300 )      ; Negative Cache TTL

@              IN NS    ns1.hcartiaux.dn42.
@              IN NS    ns2.hcartiaux.dn42.

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.0.0.0 IN PTR ns1.hcartiaux.dn42.
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.c.0.0.0 IN PTR ns2.hcartiaux.dn42.

Bind configuration

Common

In /etc/bind/named.conf.local:

  • Specify the listen interface
listen-on {
    any;
};

listen-on-v6 {
    any;
};
  • Disable the RFC1918 default empty reverse zones
empty-zones-enable no;
  • Disable DNSSEC validation (sorry) for dn42 zones and TLD
validate-except {
  "dn42";
  "20.172.in-addr.arpa";
  "21.172.in-addr.arpa";
  "22.172.in-addr.arpa";
  "23.172.in-addr.arpa";
  "10.in-addr.arpa";
  "d.f.ip6.arpa";
};

Forwarding

In this mode, bind will forward the requests for the dn42 zones to recursive resolvers (configured in the forwarders blocks.

ClieR<netquestAf1o7r2.s2h0e.l1l2.9f.r2.8burble.Fdonr4w2>arR<deeqruestAf1o7r2.s2h0e.l1l2.9f.r2.8burRbelceu.rdsni4v2>eR<<reeqsuoelsvteRrSeOtAurfnRoernqsus1eh.sRebtelutlrAu.brflfnreod..r1nbd74uns22r4h.b2e2all0uel.t..1hdf2onr9r4..i2>b2tu8artbilvee.dsne4r2verns1.bur>ble.dn42

In /etc/bind/named.conf.local, define the dn42 zones and the forwarder servers in the dn42 network. DNS requests on this zones will be redirected to the servers fd42:d42:d42:53::1 or fd42:d42:d42:54::1.

zone "dn42" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "20.172.in-addr.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "21.172.in-addr.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "22.172.in-addr.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "23.172.in-addr.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "10.in-addr.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

zone "d.f.ip6.arpa" {
        type forward;
        forwarders {
            fd42:d42:d42:53::1;
            fd42:d42:d42:54::1;
        };
};

Primary name server

⚠ For the explanations behind the concepts of primary and secondary name servers, refer to "section 3.2. Authoritative Name Servers" <https://bind9.readthedocs.io/en/latest/chapter3.html#authoritative-name-servers> in the bind documentation.

The primary name server hosting our zones is gw-dn42, it hosts the original zone file and notify the secondary servers of any zone update (when the serial is incremented).

The zones below are defined in /etc/bind/named.conf.local on gw-dn42.

zone "hcartiaux.dn42" {
        type primary;
        file "/etc/bind/db.hcartiaux.dn42";
        notify yes;
        allow-transfer {
            fd28:7515:7d51:c::1;
        };
};

zone "160/27.144.22.172.in-addr.arpa" {
        type primary;
        file "/etc/bind/db.160-27.144.22.172.in-addr.arpa";
        notify yes;
        allow-transfer {
            fd28:7515:7d51:c::1;
        };
};

zone "1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa" {
        type primary;
        file "/etc/bind/db.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa";
        notify yes;
        allow-transfer {
            fd28:7515:7d51:c::1;
        };
};

Secondary name server

The secondary name server hosting our zones is gw2-dn42. It retrieves the zone files from the configured primary server.

The zones below are defined in /etc/bind/named.conf.local on gw2-dn42.

zone "hcartiaux.dn42" {
        type secondary;
        file "db.hcartiaux.dn42.saved";
        primaries {
            fd28:7515:7d51:a::1;
        };
};

zone "160/27.144.22.172.in-addr.arpa" {
        type secondary;
        file "db.160-27.144.22.172.in-addr.arpa.saved";
        primaries {
            fd28:7515:7d51:a::1;
        };
};

zone "1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa" {
        type secondary;
        file "db.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa.saved";
        primaries {
            fd28:7515:7d51:a::1;
        };
};

Configure and test !

Reload the configuration

rndc reload

Test

  • Query the server using dig
dig ANY hcartiaux.dn42. @::1

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> ANY hcartiaux.dn42. @::1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23874
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 182e8e0218e47c3a0100000066d4d2e551a71219ee50ca49 (good)
;; QUESTION SECTION:
;hcartiaux.dn42.                        IN      ANY

;; ANSWER SECTION:
hcartiaux.dn42.         300     IN      NS      ns1.hcartiaux.dn42.
hcartiaux.dn42.         300     IN      NS      ns2.hcartiaux.dn42.
hcartiaux.dn42.         300     IN      AAAA    fd28:7515:7d51:a::1
hcartiaux.dn42.         300     IN      A       172.22.144.161
hcartiaux.dn42.         3600    IN      SOA     ns1.hcartiaux.dn42. hostmaster.hcartiaux.dn42. 2024062100 10800 3600 604800 300

;; ADDITIONAL SECTION:
ns1.hcartiaux.dn42.     300     IN      AAAA    fd28:7515:7d51:a::1
ns2.hcartiaux.dn42.     300     IN      AAAA    fd28:7515:7d51:c::1
ns1.hcartiaux.dn42.     300     IN      A       172.22.144.161
ns2.hcartiaux.dn42.     300     IN      A       172.22.144.177

;; Query time: 0 msec
;; SERVER: ::1#53(::1) (TCP)
;; WHEN: Sun Sep 01 22:47:33 CEST 2024
;; MSG SIZE  rcvd: 286
  • Query the server for a reverse record
dig -x fd28:7515:7d51:a::1 @::1

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> -x fd28:7515:7d51:a::1 @::1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5419
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 3c8b3cab23298d660100000066d4d7728a9e4f9f1170607a (good)
;; QUESTION SECTION:
;1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.0.0.0.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa. IN PTR

;; ANSWER SECTION:
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.0.0.0.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa. 300 IN PTR ns1.hcartiaux.dn42.

;; Query time: 0 msec
;; SERVER: ::1#53(::1) (UDP)
;; WHEN: Sun Sep 01 23:06:58 CEST 2024
;; MSG SIZE  rcvd: 161
  • Test that the recursion works using another DNS server
dig AAAA hcartiaux.dn42 @fd42:d42:d42:54::1

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> AAAA hcartiaux.dn42 @fd42:d42:d42:54::1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15741
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;hcartiaux.dn42.                        IN      AAAA

;; ANSWER SECTION:
hcartiaux.dn42.         246     IN      AAAA    fd28:7515:7d51:a::1

;; Query time: 7 msec
;; SERVER: fd42:d42:d42:54::1#53(fd42:d42:d42:54::1) (UDP)
;; WHEN: Sun Sep 01 22:26:56 CEST 2024
;; MSG SIZE  rcvd: 71

At this point, we can say that the bind server configuration is functional.

“Eat your own dog food”

By default, bind is configured as a recursive resolver on the root name servers, so in this case, bind is functional both for dn42 and for the rest of the internet.

I’ve configured my servers to use the local bind server by default:

sed -i 's/^DNS=.*$/DNS=::1/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
cat /etc/resolv.conf
# This is /run/systemd/resolve/resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
# ...

nameserver ::1
search hcartiaux.dn42

Try a few queries:

host ns1.hcartiaux.dn42
ns1.hcartiaux.dn42 has address 172.22.144.161
ns1.hcartiaux.dn42 has IPv6 address fd28:7515:7d51:a::1

host internal.dn42
internal.dn42 has address 172.23.0.80
internal.dn42 has IPv6 address fd42:d42:d42:80::1

host burble.dn42
burble.dn42 has address 172.20.129.3
burble.dn42 has IPv6 address fd42:4242:2601:ac80::1

host 172.20.129.3
3.129.20.172.in-addr.arpa is an alias for 3.0/27.129.20.172.in-addr.arpa.
3.0/27.129.20.172.in-addr.arpa domain name pointer burble.dn42.

host fd42:4242:2601:ac80::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.c.a.1.0.6.2.2.4.2.4.2.4.d.f.ip6.arpa domain name pointer burble.dn42.

Next step - librenms !

In the last part, we will set-up another virtual machine to host the librenms monitoring tool.

Let’s prepare the DNS records on the primary server. Do not forget to increase the serial on the SOA record, otherwise the updates zone files will never be transferred to the secondary server.

  • In /etc/bind/db.hcartiaux.dn42, add one A and one AAAA records.
librenms       IN AAAA  fd28:7515:7d51:d::2
librenms       IN A     172.22.144.186
  • In /etc/bind/db.160-27.144.22.172.in-addr.arpa, add one PTR record.
186            IN PTR   librenms.hcartiaux.dn42.
  • In /etc/bind/db.1.5.d.7.5.1.5.7.8.2.d.f.ip6.arpa, add another PTR record.
2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.0.0.0 IN PTR librenms.hcartiaux.dn42.