Create your own DNSsec server with bind
What is a DNS?
A Domain Name System (DNS) is a distributed service for associating an Internet domain name with its IP address(es), as well as with other records. There are four types of DNS servers.
- The recursive DNS resolver, which sends queries to the other three types of DNS servers and sends the IP address of the domain to be searched.
- The root DNS server, which finds the IP address of the top-level domain. The server that manages .com, .net, .xyz.
- The TLD DNS server redirects the DNS resolver to the authoritative server for the zone in question.
- The authoritative DNS server then sends the IP address associated with the zone it manages to the DNS resolver, which in turn sends it to the host.
Why create an authoritative DNS?
For educational purposes, it’s useful to understand how DNS works, and there’s nothing better than hands-on practice for that ;) DNS is a distributed technology; anyone can have one, so there’s no need to depend on an external service.
Installation
Bind
To configure the DNS zone, we’ll use bind. In our case, we’ll be using two DNS servers. The first will be the primary DNS server (ns1.example.com), where we’ll define our various records. The second will be the secondary DNS server (ns2.example.com), which will take over if the first fails, for example.
apt-get install bind9 dnsutils
Once installed, configuration files can be found in /etc/bind
.
Bind or Bind 9?
Configuration
Primary DNS
ns1 architecture
Several files are required to configure our DNS zone.
Our /etc/bind
folder will have this architecture:
/etc/bind
├── bind.keys
├── db.0
├── db.127
├── db.255
├── db.empty
├── db.local
├── named.conf
├── named.conf.default-zones
├── named.conf.local
├── named.conf.options # options for dns server
├── rndc.key
├── zones # folder for zone files
│ ├─── db.51
│ ├─── db.domain.tld
└── zones.rfc1918
Zone options
The /etc/bind/named.conf.options
file is generated by default. It will allow us to define our DNS options.
options {
directory "/var/cache/bind" ;
listen-on { any ; } ;
# Resolve ipv6 queries
listen-on-v6 { any ; } ;
# Useful if you wish to configure DNSSEC
dnssec-validation auto ;
# message indicating that the domain name does not exist
auth-nxdomain no ;
# Do not give any information about your server
version none ;
hostname none ;
server-id none ;
recursion no ;
} ;
It is necessary to provide only the information required for the service to function properly. To this end, we’ve added a number of options to prevent the version of our distribution from being sent version none;
,
Local DNS server configuration
The local DNS server named.conf.local
allows us to define the zones associated with the norte DNS server.
include "/etc/bind/zones.rfc1918" ;
zone "domain.tld" {
type master ; # defines that the server is master and not secondary
file "/etc/bind/zones/db.domain.tld" ; # zone file path
allow-transfer { XXX.XXX.XX.XX ; } ; # IP address ns2 - secondary DNS
} ;
Don’t forget to replace “domain.tld” with your domain name and to include the IP of your secondary DNS server in allow-transfer. It’s important not to allow everyone to transfer, otherwise all your records will be recovered, and consequently the IPs of your machines.
Zone options
The /etc/bind/named.conf.options
file is generated by default. It will enable us to define our DNS options.
options {
directory "/var/cache/bind" ;
listen-on { any ; } ;
# Resolve ipv6 requests
listen-on-v6 { any ; } ;
# Useful if you wish to configure DNSSEC
dnssec-validation auto ;
# message indicating that the domain name does not exist
auth-nxdomain no ;
# Do not give any information about your server
version none ;
hostname none ;
server-id none ;
recursion no ;
} ;
It is necessary to provide only the information required for the service to function properly. To this end, we’ve added a number of options to prevent the version of our distribution from being sent version none;
,
Local DNS server configuration
The local DNS server named.conf.local
allows us to define the zones associated with the norte DNS server.
include "/etc/bind/zones.rfc1918" ;
zone "domain.tld" {
type master ; # defines that the server is master and not secondary
file "/etc/bind/zones/db.domain.tld" ; # zone file path
allow-transfer { XXX.XXX.XX.XX ; } ; # IP address ns2 - secondary DNS
} ;
Don’t forget to replace “domain.tld” with your domain name and to include the IP of your secondary DNS server in allow-transfer. It’s important not to allow everyone to transfer, otherwise all your records will be recovered, and consequently the IPs of your machines.
Zone configuration
We’re going to create a zones
folder that will contain our zone records.
Next, we’ll create the file containing the records required for our domain name to function properly.
mdkir /etc/bind/zones
cd /etc/bind/zones
touch db.domain.tld
In our db.domain.tld
file, we will define the records.
;
BIND data file for local loopback interface
;
$TTL 86400
@ IN SOA ns1.doamin.tld. mail.domain.tld. (
2021043003; Serial
43200 ; Refresh
7200 ; Retry
2419200 ; Expiration
86400 ) ; Negative cache TTL
NS records for name servers
IN NS ns1.doamin.tld.
IN NS ns2.doamin.tld.
A records for name servers
ns2.doamin.tld. IN A XXX.XX.XX.X
ns1.doamin.tld. IN A XX.XXX.XXX.XXX
ns1.doamin.tld. IN AAAA 0000:000:0000:0000::1
ns2.doamin.tld. IN AAAA 0000:000:0000:0000::1
Mail handler or MX record for the domain hwdomain.io
; A records for domain names
The Start of Authority (SOA) record is used to provide zone information and to indicate whether this server is in charge of the zone in question.
The first two pieces of information after SOA indicate the name of the master DNS server and the e-mail address of the technical contact (for the example mail.domain.tld
).
- Serial, is a repository allowing other servers to know if the file has been modified. It is therefore important to modify the file each time it is changed.
Tip
To keep increments consistent, you can use this standard: YYYYMMDDXX.
- Refresh: data refresh period.
- Retry: if an error occurs during the last refresh, it will be repeated at the end of the retry period.
- Expiration : the server will be considered unavailable after the expiration time.
- Negative cache TTL: defines the lifetime of an NXDOMAIN response from us.
Verification
Now that we have a complete master DNS server, we need to check the configuration files for errors. To do this, we’ll use the named
command.
First, we’ll check the files in /etc/bind with named-checkconf -z
.
named-checkconf -z
/etc/bind/zones/db.domain.tld.
zone localhost/IN : loaded serial 2
zone 127.in-addr.arpa/IN : loaded serial 1
zone 0.in-addr.arpa/IN : loaded serial 1
zone 255.in-addr.arpa/IN : loaded serial 1
Next, we check the validity of the zone file /etc/bind/db.domain.tld
.
named-checkzone domain.tld /etc/bind/zones/db.domain.tld
zone domain.tld/IN: loaded serial 2021043003
OK
If all goes well, we can now start the bind service.
systemctl start bind9
# and check the status
systemctl status bind9
● named.service - BIND domain name server
Loaded : loaded (/lib/systemd/system/named.service ; enabled ; vendor preset : enabled).
Active : active (running) since Sat 2021-05-27 19:39:54 UTC ; 49min ago
Docs : man:named(8)
Process: 124185 ExecStart=/usr/sbin/named $OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 124187 (named)
Tasks: 6 (limit: 3760)
Memory: 5.4M
CPU: 72ms
CGroup: /system.slice/named.service
└─124187 /usr/sbin/named -u bind
Let’s now configure the secondary server to ensure redundancy in the event of failure of the master DNS server.
Secondary DNS
ns2 architecture
The installation part is identical. In the bind architecture, we’ll make a few modifications to the local and options files, but the concept is the same. In addition, the zones
folder will not be present.
/etc/bind
├── bind.keys
├── db.0
├── db.127
├── db.255
├── db.empty
├── db.local
├── named.conf
├── named.conf.default-zones
├── named.conf.local
├── named.conf.options
├── rndc.key
└── zones.rfc1918
Zone options
Zone options will be identical to those in ns1, except that we won’t allow zone transfers to allow-transfer { none ; };
people.
So let’s modify the /etc/bind/named.conf.options
file.
options {
directory "/var/cache/bind" ;
dnssec-validation auto ;
allow-transfer { none ; } ;
auth-nxdomain no ; # compliant with RFC1035
listen-on-v6 { any ; } ;
version none ;
hostname none ;
server-id none ;
recursion no ;
} ;
Local DNS server configuration
The local DNS server named.conf.local
allows us to define the zones associated with the norte DNS server.
include "/etc/bind/zones.rfc1918" ;
zone "domain.tld" {
type slave ;
file "db.domain.tld" ;
masters { XXX.XX.X.XX ; } ; # IP address ns1 - primary DNS
} ;
We can check the verification, and if it’s valid, we’ll move on to the test!
Glue registration
For DNS to be operational, it’s important to define the ip linked to your primary and secondary DNS at your registrar.
Tests
The most important part of this section is to perform dig
queries on our two authoritative DNS servers to check that they are responding correctly.
dig A domain.tld # request IPV4 throw dns resolver
dig ns domain.tld # find name server for zone domain.tld
dig domain.tld @ns1.domain.tld # request primary server
dig domain.tld @ns2.domain.tld # request secondary server
# Bonus
dig AXFR domain.tld @ns1.domain.tld
dig AXFR domain.tld @ns2.domain.tld
# result : Transfer failed.
dig chaos txt version.bind @ns1.domain.tld +short # check version
# result : no response
Verisign can also be useful for checking configuration.
Bonus
DNSSEC
You can find script and README.md to generate your keys and run this script periodically with a crontab.