[dn42] AS4242420263 configuration - DNS with bind (Part 4/5)
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 networks160/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 Block | Primary name server | Secondary name server |
---|---|---|
fd28:7515:7d51::/48 | fd28:7515:7d51:a::1 | fd28:7515:7d51:c::1 |
172.22.144.160/27 | 172.22.144.161 | 172.22.144.177 |
dn42 recursive name servers
dig -tSRV _dns._udp.recursive-servers.dn42. @172.20.0.53
Name | IPv4 | IPv6 |
---|---|---|
a0.recursive-servers.dn42. | 172.20.0.53 | fd42:d42:d42:54::1 |
a3.recursive-servers.dn42. | 172.23.0.53 | fd42:d42:d42:53::1 |
b.recursive-servers.dn42. | 172.20.129.2 | fd42:4242:2601:ac53::53 |
j.recursive-servers.dn42. | 172.20.1.255 | fd42:5d71:219:0:216:3eff:fee8:c215 |
k.recursive-servers.dn42. | 172.20.14.33 | fdcf:8538:9ad5:1111::1 |
l.recursive-servers.dn42. | 172.22.108.53 | fd86:bad:11b7:53::2 |
t.recursive-servers.dn42. | 172.22.76.110 | fdbc: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:
- Expanded prefix:
f.d.2.8.7.5.1.5.7.d.5.1
- Reversed prefix:
1.5.d.7.5.1.5.7.8.2.d.f
- 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.
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
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 oneA
and oneAAAA
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 onePTR
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 anotherPTR
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.