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.