tyrel.cloud


All posts tagged:


Bind9 - DNS Cheat Sheet

Updated by Tyrel on 2020-05-01

Summary

Standing up a DNS lab environment using Bind9

DNS Cheat Sheet - BIND9


DNS


Content Overview

In this blog post we are going to be setting up an internal zone (tyrel.local) on a home network, we will be using a laptop running Ubuntu 18.0.4 (Bionic), this will be our Master, and a Raspberry pi running Raspbian OS (Buster), this will be our Slave.

Sections:


Topology

Topology


Install

sudo apt-get update && sudo apt-get --yes install bind9 bind9-doc dnsutils

Once installation is complete bind9 is started automatically, named is the daemon name.


Configure

The main configuration file for bind is /etc/bind/named.conf. In this file we find references for other configuration files:

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

The only thing we are going to be adding to the main config file is logging, which we will do a little bit later. So lets get started with options.

Options

The options configuration file /etc/bind/named.conf.options is where the global options are defined. By default without any other configuration we have a recursive caching server.

Here's an overview of whats enabled/configured by default:

We really don't need to do anything in the options file for a basic setup.

Zones

The first configuration piece we are going to do is in /etc/bind/named.conf.local, this is where we define our zones and their types.

1. Zone Definition Config:

Edit the file /etc/bind/named.conf.local and Add the following:

sudo nano /etc/bind/named.conf.local

MASTER

zone "tyrel.local" {
  type master;
  file "/etc/bind/db.tyrel.local";
  allow-transfer { 192.168.1.2; };
};
zone "1.168.192.in-addr.arpa" {
  type master;
  allow-transfer { 192.168.1.2; };
  file "/etc/bind/db.192";
};

SLAVE

zone "tyrel.local" {
  type slave;
  masterfile-format text;
  file "/etc/bind/db.tyrel.local";
  masters { 192.168.1.254; };
};
zone "1.168.192.in-addr.arpa" {
  type slave;
  masterfile-format text;
  file "/etc/bind/db.192";
  masters { 192.168.1.254; };
};

2. Forward Lookup Zone File

Create the zone file /etc/bind/db.tyrel.local

At a Minimum We need to define:

sudo nano /etc/bind/db.tyrel.local

MASTER

$TTL 1h                                                                         ; default TTL
tyrel.local.  IN  SOA   ns1.tyrel.local. contact.tyrel.local. ( 1 1d 2h 4w 1h ) ; SOA Record
tyrel.local.            IN      NS      ns1.tyrel.local.                        ; NS records
tyrel.local.            IN      NS      ns2.tyrel.local.                        ; NS records
ns1.tyrel.local.        IN      A       192.168.1.254                           ; A records
ns2.tyrel.local.        IN      A       192.168.1.2                             ; A records

3. Reverse Lookup Zone File

Create the zone file /etc/bind/db.192

Note In this file we are using @ instead of defining the Origin as we did in the Forward Lookup Zone, which would have been 1.168.192.in-addr.arpa

sudo nano /etc/bind/db.192

MASTER

$TTL 1h                                                                        ; default TTL
@     IN      SOA     ns1.tyrel.local. contact.tyrel.local. ( 1 1d 2h 4w 1h )  ; SOA Record
      IN      NS      ns1.tyrel.local.                                         ; NS Record
      IN      NS      ns2.tyrel.local.                                         ; NS Record
254   IN      PTR     ns1.tyrel.local.                                         ; 192.168.1.254 PTR
2     IN      PTR     ns2.tyrel.local.                                         ; 192.168.1.2 PTR

Verify Config

Once we have our Zone files configured we need to verify they are correct with the following:

named-checkconf -z

zone tyrel.local/IN: loaded serial 1
zone 1.168.192.in-addr.arpa/IN: loaded serial 1
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

named-checkzone tyrel.local /etc/bind/db.tyrel.local

zone tyrel.local/IN: loaded serial 1
OK

named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192

zone 1.168.192.in-addr.arpa/IN: loaded serial 1
OK

Restart Service

Once the verification checks out we need to reload the service for the changes to take effect.

sudo systemctl restart bind9

Basic Functionality Testing

At this Point we should be able to query both the master and the slave for the NS and PTR records.

Using NSLOOKUP:

nslookup ns2 192.168.1.254

Server:     ns1
Address:    192.168.1.254#53

Name:   ns2.tyrel.local
Address: 192.168.1.2

nslookup 192.168.1.2 192.168.1.254

2.1.168.192.in-addr.arpa    name = ns2.tyrel.local.

Using DIG:

dig @192.168.1.254 ns2.tyrel.local A +short

192.168.1.2

dig @192.168.1.254 -x 192.168.1.2 PTR +short

ns2.tyrel.local.

Logging

This is optional but recommended as it makes troubleshooting much easier.

By default logging is done to /var/syslog

This is a useful adaptation that will log everything to /var/log/named/ directory and split the logs out to there respective category.

The files will rotate once they reach 5MB and 3 versions will be kept in rotation.

sudo mkdir /var/log/named

sudo chown bind:bind /var/log/named

sudo nano /etc/bind/named.conf

Append the following:

logging {
    channel default_file {
        file "/var/log/named/default.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel general_file {
        file "/var/log/named/general.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel database_file {
        file "/var/log/named/database.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel security_file {
        file "/var/log/named/security.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel config_file {
        file "/var/log/named/config.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel resolver_file {
        file "/var/log/named/resolver.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel xfer-in_file {
        file "/var/log/named/xfer-in.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel xfer-out_file {
        file "/var/log/named/xfer-out.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel notify_file {
        file "/var/log/named/notify.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel client_file {
        file "/var/log/named/client.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel unmatched_file {
        file "/var/log/named/unmatched.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel queries_file {
        file "/var/log/named/queries.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel network_file {
        file "/var/log/named/network.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel update_file {
        file "/var/log/named/update.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel dispatch_file {
        file "/var/log/named/dispatch.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel dnssec_file {
        file "/var/log/named/dnssec.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };
    channel lame-servers_file {
        file "/var/log/named/lame-servers.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
    };

    category default { default_file; };
    category general { general_file; };
    category database { database_file; };
    category security { security_file; };
    category config { config_file; };
    category resolver { resolver_file; };
    category xfer-in { xfer-in_file; };
    category xfer-out { xfer-out_file; };
    category notify { notify_file; };
    category client { client_file; };
    category unmatched { unmatched_file; };
    category queries { queries_file; };
    category network { network_file; };
    category update { update_file; };
    category dispatch { dispatch_file; };
    category dnssec { dnssec_file; };
    category lame-servers { lame-servers_file; };
};

Again Restart the service to have this take effect:

sudo systemctl restart bind9

Zone Transfers

Most of the zone transfer config was done when we defined our zones, we still need to modify the owner of the /etc/bind directory and /etc/bind/db.* files. This will allow the named daemon running as user "bind" to modify these files.

SLAVE ONLY

sudo chown -R bind:bind /etc/bind

Verification

In order to verify zone transfers are function we need to kick off a zone transfer. We can do this a few ways:

Quick SLAVE verification

dig @192.168.1.254 tyrel.local. axfr

; <<>> DiG 9.11.5-P4-5.1-Raspbian <<>> @192.168.1.254 tyrel.local. axfr
; (1 server found)
;; global options: +cmd
tyrel.local.        3600    IN  SOA ns1.tyrel.local. contact.tyrel.local. 1 86400 7200 2419200 3600
tyrel.local.        3600    IN  NS  ns1.tyrel.local.
tyrel.local.        3600    IN  NS  ns2.tyrel.local.
ns1.tyrel.local.    3600    IN  A   192.168.1.254
ns2.tyrel.local.    3600    IN  A   192.168.1.2
tyrel.local.        3600    IN  SOA ns1.tyrel.local. contact.tyrel.local. 1 86400 7200 2419200 3600
;; Query time: 2 msec
;; SERVER: 192.168.1.254#53(192.168.1.254)
;; WHEN: Sun Apr 26 11:16:06 EDT 2020
;; XFR size: 6 records (messages 1, bytes 216)

MASTER

sudo nano /etc/bind/db.tyrel.local

SLAVE

cat /var/log/named/xfer-in.log

transfer of 'tyrel.local/IN' from 192.168.1.254#53: connected using 192.168.1.2#59733
transfer of 'tyrel.local/IN' from 192.168.1.254#53: Transfer status: success
transfer of 'tyrel.local/IN' from 192.168.1.254#53: Transfer completed: 1 messages, 6 records, 216 bytes, 0.040 secs (14250 bytes/sec)
transfer of '1.168.192.in-addr.arpa/IN' from 192.168.1.254#53: connected using 192.168.1.2#53103
transfer of '1.168.192.in-addr.arpa/IN' from 192.168.1.254#53: Transfer status: success
transfer of '1.168.192.in-addr.arpa/IN' from 192.168.1.254#53: Transfer completed: 1 messages, 7 records, 238 bytes, 0.004 secs (59500 bytes/sec)

cat /etc/bind/db.tyrel.local

$ORIGIN .
$TTL 3600   ; 1 hour
tyrel.local     IN SOA  ns1.tyrel.local. contact.tyrel.local. (
                1          ; serial
                86400      ; refresh (1 day)
                7200       ; retry (2 hours)
                2419200    ; expire (4 weeks)
                3600       ; minimum (1 hour)
                )
            NS  ns1.tyrel.local.
            NS  ns2.tyrel.local.
$ORIGIN tyrel.local.
ns1         A   192.168.1.254
ns2         A   192.168.1.2

Note The transferred zone file format is much different than the original file


Manage

Common management actions

Adding Records

1. Edit Forward Lookup Zone File /etc/bind/db.tyrel

MASTER

Add a variety of records using different methods as an example

Be sure to increment the Serial Number in the SOA Record

nano /etc/bind/db.tyrel.local

tyrel.local.  IN  SOA   ns1.tyrel.local. contact.tyrel.local. ( **8** 1d 2h 4w 1h ) ; SOA Record
mail        IN  A       192.168.2.254          ; A to go with MX
@           IN  MX      10 mail                ; MX Record
@               TXT     "Administrator: Tyrel" ; TXT Record
openvpn     IN  A       192.168.1.2            ; A to go with SRV
_vpn._udp       SRV     0 0 1194 openvpn       ; SRV Record
blog            A       192.168.1.254          ; A Record
info        IN  CNAME   blog                   ; CNAME Record
jupyter     IN  A       192.168.1.15           ; A Record
notebook        A       192.168.1.254
pi              A       192.168.1.15
pi1b            A       192.168.1.2
pi2b            A       192.168.1.15
pi3b            A       192.168.1.7
2. Check Configs

named-checkconf -z

named-checkzone tyrel.local /etc/bind/db.tyrel.local

3. Restart Service

sudo systemctl restart bind9

4. Verify Lookups

dig @ns1 tyrel.local TXT +short

"Administrator: Tyrel"

dig @ns1 tyrel.local MX +short

10 mail.tyrel.local.

dig @ns1 _vpn._udp.tyrel.local SRV +short

0 0 1194 openvpn.tyrel.local.

5. Verify Zone Transfer on Slave

cat /etc/bind/db.tyrel.local

$ORIGIN .
$TTL 3600   ; 1 hour
tyrel.local     IN SOA  ns1.tyrel.local. contact.tyrel.local. (
                    **8          ; serial**
                    86400      ; refresh (1 day)
                    7200       ; retry (2 hours)
                    2419200    ; expire (4 weeks)
                    3600       ; minimum (1 hour)
                    )
                NS  ns1.tyrel.local.
                NS  ns2.tyrel.local.
                MX  10 mail.tyrel.local.
                TXT "Administrator: Tyrel"
$ORIGIN tyrel.local.
_vpn._udp       SRV 0 0 1194 openvpn
blog            A   192.168.1.254
info            CNAME   blog
jupyter         A   192.168.1.15
mail            A   192.168.2.254
notebook        A   192.168.1.254
ns1             A   192.168.1.254
ns2             A   192.168.1.2
openvpn         A   192.168.1.2
pi              A   192.168.1.15
pi1b            A   192.168.1.2
pi2b            A   192.168.1.15
pi3b            A   192.168.1.7

Caching

Not really necessary to actively manage, however if you want to examine the recursive cache. Here's how.

View cache:

sudo rndc dumpdb -cache && sudo cat /var/cache/bind/named_dump.db |grep XYZ.com

Clear cache:

sudo rndc flush && rndc reload


Additional Info:

https://bind9.readthedocs.io/en/latest/

https://wiki.debian.org/Bind9


Feel like I missed something? Let me know in the comments!