Architecture

BIND9 is an open source DNS software system that is widely used and simple to operate.

The DHCP of the network that will be used for the DNS server will be 172.21.5.0/24, but the DNS will respond to the 3 VLANs.

4 DNSs (Zones) will be used *.devops-db.internal, *.devops-db.info, *.lab.devops-db.info and *.devops-db.com

The Server/IP that will be the DNS point will be a VM with Ubuntu 22.04: 172.21.5.155.

I will show two ways to create DNS with Bind9, the first, with Docker Container, which was the first version I used, with the new server, I started using a VM dedicated to the DNS Server, since it is also my DNS server ( Home).

Creating the container is easy. To make configuration easier, we have to create 3 folders at the root of where docker-compose.yaml is located, these folders will be used as the volume in the container.

      - ./config:/etc/bind
      - ./cache:/var/cache/bind
      - ./records:/var/lib/bind

The image is created and maintained by Canonical and uses Ubuntu as its OS.

https://hub.docker.com/r/ubuntu/bind9

(docker-compose.yaml)

version: "3"

services:
  bind9:
    container_name: srv-dns-devopsdb-01
    image: ubuntu/bind9:latest
    environment:
      - BIND9_USER=root
      - TZ=Europe/Lisbon
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    volumes:
      - ./config:/etc/bind
      - ./cache:/var/cache/bind
      - ./records:/var/lib/bind
    restart: unless-stopped

Now, there are two basic configurations:

The first file is for setting the external DNS, internal acl and the zone (DNS).

In zone, you define the DNS and the file in which the zones are created.

(named.conf)

acl internal {
    172.21.5.0/24;
    172.25.1.0/24;
};

options {
    forwarders {
        1.1.1.1;
        8.8.8.8;
    };
    allow-query { internal; };
};

zone "devops-db.internal" IN {
    type master;
    file "/etc/bind/devops-db.internal";
};
zone "lab.devops-db.com" IN {
    type master;
    file "/etc/bind/devops-db.com";
};
zone "lab.devops-db.info" IN {
    type master;
    file "/etc/bind/lab.devops-db.info";
};
zone "devops-db.info" IN {
    type master;
    file "/etc/bind/devops-db.info";
};
include "/etc/bind/rndc.key";

controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

logging {
        channel information {
                file "/var/log/bind.log" versions 3 size 500K;
                severity debug 10;
                print-time              yes;
                print-severity          yes;
                print-category          yes;
                };
        channel query {
                file "/var/log/bind-query.log" versions 5 size 10M;
                severity debug 10;
                print-time              yes;
                print-severity          yes;
                print-category          yes;
                };
        category default {information;};
};

An important point: DNS Zone files must have the same name as the zone, for example for devops-db.internal DNS, the file must then have the name devops-db.internal. This will be necessary, later on, in the automated maintenance of DNS using Python, Blueprints and Jenkins.

To start a new DNS Zones file, you can use the examples on GitHub or use a generator: https://nimmneun.com/toolbox/bind-zone-file-generator/

When automation comes into action, the files will no longer be formatted as in the example, but they will function in the same way.

Config files: devops-db/bind9/config at master · faustobranco/devops-db

Installation

In the same folder as the docker-compose.yaml file, start the container.

docker-compose up -d
Creating srv-dns-devopsdb-01 ... done

Log:

docker container logs -f srv-dns-devopsdb-01

The generation of the /etc/bind/rndc.key key, referenced in the named.conf file (include) is important for maintenance tasks, such as reloading or restarting the DNS. Any changes to the Zone file must be reloaded immediately afterwards in order to take effect.

Go to the container:

docker exec -it -u root --privileged srv-dns-devopsdb-01 /bin/bash

Inside the container, generate the key, example:

rndc-confgen
# Start of rndc.conf
key "rndc-key" {
        algorithm hmac-sha256;
        secret "hjrtbrSY0WREyv5SHHPwfkuqCcO4TI3Fj6GZeimIQQg=";
};
options {
        default-key "rndc-key";
        default-server 127.0.0.1;
        default-port 953;
};
# End of rndc.conf

From the output, copy only the key part “rndc-key” and create a file rndc.key in ./conf/ on your host (Docker) or in /etc/bind/ inside the container.

(

key "rndc-key" {
        algorithm hmac-sha256;
        secret "hjrtbrSY0WREyv5SHHPwfkuqCcO4TI3Fj6GZeimIQQg=";
};

Tests

Before changing the network settings of the hosts to add the new DNS Server, check that the settings are working:

Test1: nslookup on the external domain youtube.com , informing the DNS server:

nslookup youtube.com 172.21.5.72

The expected result should be something like:

Server:         172.21.5.72
Address:        172.21.5.72#53
Non-authoritative answer:
Name:   youtube.com
Address: 142.250.200.110

With the initial zones configuration file, there is a DNS srv-consul-01 pointing to 172.21.5.152.

At this point, let’s really validate that the internal domain is working:

nslookup srv-consul-01.devops-db.internal 172.21.5.72

The return should be:

Server:         172.21.5.72
Address:        172.21.5.72#53
Name:   srv-consul-01.devops-db.internal
Address: 172.21.5.152

From now on, you can change the network settings / DNS Server of the hosts to 172.21.5.72 , so all search and resolution will be automatic.

Maintenance

Any change, addition or removal of DNS must be made in the devops-db-internal.zone, devops-db-com.zone and devops-db-local.zone file, then the container must be restarted, or a command run inside the DNS container:

$ rndc reload
server reload successful

Or

docker exec -it -u root --privileged srv-dns-devopsdb-01 rndc reload

Before starting to configure Bind9, I will leave here the Vagranfile file and the first steps I used to update and configure the VM.

Vagrant.configure("2") do |config|
  config.vm.define "srv-infrastructure-dns-master-01", autostart: true do |dns|
    dns.vm.box = "bento/ubuntu-22.04"
    dns.vm.hostname = 'srv-infrastructure-dns-master-01'

    dns.vm.network "public_network", use_dhcp_assigned_default_route: true, bridge: "enp7s0", ip: "172.21.5.155"
    dns.vm.synced_folder "/work/", "/work"
    dns.vm.provider :virtualbox do |v|
        v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        v.customize ["modifyvm", :id, "--memory", 1024]
        v.customize ["modifyvm", :id, "--name", "srv-infrastructure-dns-master-01"]
    end
  end
end

apt update
apt install -y python3 wget gnupg2 net-tools gpg lsb-release vim libcap2-bin curl python3-pip less iputils-ping ssh software-properties-common dnsutils jq ldap-utils telnet

sudo sed -i 's/\#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config
sudo systemctl restart sshd.service

Installation

Installation is very simple, the bind9 package is enough and does not need other dependencies, what is worth installing is the dnsutils package, which has important tools for DNS administration, testing, etc.

sudo apt -y install bind9 dnsutils

Config files

(https://github.com/faustobranco/devops-db/tree/master/bind9/config)

The zone files are in the link above, and the most important are named.conf and rndc.key.

The first step before configuration is to generate a key for the rndc (Remote Name Daemon Control) utility package.

The generation of the /etc/bind/rndc.key key, referenced in the named.conf file (include) is important for maintenance tasks, such as reloading or restarting the DNS. Any changes to the Zone file must be reloaded immediately afterwards in order to take effect.

rndc-confgen
# Start of rndc.conf
key "rndc-key" {
        algorithm hmac-sha256;
        secret "hjrtbrSY0WREyv5SHHPwfkuqCcO4TI3Fj6GZeimIQQg=";
};
options {
        default-key "rndc-key";
        default-server 127.0.0.1;
        default-port 953;
};
# End of rndc.conf

From the output, copy only the key part “rndc-key” and create the file /etc/bind/rndc.key

key "rndc-key" {
        algorithm hmac-sha256;
        secret "hjrtbrSY0WREyv5SHHPwfkuqCcO4TI3Fj6GZeimIQQg=";
};

In addition to the /etc/bind/rndc.key file, the same key is in the /var/run/named/session.key file, edit it and change it to the same rndc key created above.

Now, there are two basic configurations:

The first file is for setting the external DNS, internal acl and the zone (DNS).

In zone, you define the DNS and the file in which the zones are created.

(named.conf)

acl internal {
    172.21.5.0/24;
    172.25.1.0/24;
};

options {
    forwarders {
        1.1.1.1;
        8.8.8.8;
    };
    allow-query { internal; };
};

zone "devops-db.internal" IN {
    type master;
    file "/etc/bind/devops-db.internal";
};
zone "lab.devops-db.com" IN {
    type master;
    file "/etc/bind/devops-db.com";
};
zone "lab.devops-db.info" IN {
    type master;
    file "/etc/bind/lab.devops-db.info";
};
zone "devops-db.info" IN {
    type master;
    file "/etc/bind/devops-db.info";
};
include "/etc/bind/rndc.key";

controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

logging {
        channel information {
                file "/var/log/bind.log" versions 3 size 500K;
                severity debug 10;
                print-time              yes;
                print-severity          yes;
                print-category          yes;
                };
        channel query {
                file "/var/log/bind-query.log" versions 5 size 10M;
                severity debug 10;
                print-time              yes;
                print-severity          yes;
                print-category          yes;
                };
        category default {information;};
};

An important point: DNS Zone files must have the same name as the zone, for example for devops-db.internal DNS, the file must then have the name devops-db.internal. This will be necessary, later on, in the automated maintenance of DNS using Python, Blueprints and Jenkins.

To start a new DNS Zones file, you can use the examples on GitHub or use a generator: https://nimmneun.com/toolbox/bind-zone-file-generator/

When automation comes into action, the files will no longer be formatted as in the example, but they will function in the same way.

Config files: devops-db/bind9/config at master · faustobranco/devops-db

Environment Setting

Bind9 (named) installed by package (apt for example) uses user bind, unlike docker which uses root. Check at:

cat /lib/systemd/system/named.service
[...]
[Service]
Type=forking
EnvironmentFile=-/etc/default/named
ExecStart=/usr/sbin/named $OPTIONS
[...]


cat /etc/default/named
[...]
OPTIONS="-u bind"

This means we need to configure some folder permissions and properties. If you don’t want to complicate matters, change OPTIONS="-u bind" to OPTIONS="-u root".

mkdir -p /var/log/bind/

chown -R bind:bind /var/log/bind/
chown -R bind:bind /var/log/named/
chown bind:bind /etc/bind/rndc.key
chown bind:bind /var/lib/bind
chown bind:bind /var/cache/bind

Now, you should be able to start Bind9:

sudo systemctl restart named

sudo systemctl enable named

Tests

Before changing the network settings of the hosts to add the new DNS Server, check that the settings are working:

Test1: nslookup on the external domain youtube.com , informing the DNS server:

nslookup youtube.com 172.21.5.155

The expected result should be something like:

Server:         172.21.5.155
Address:        172.21.5.155#53
Non-authoritative answer:
Name:   youtube.com
Address: 142.250.200.110

With the initial zones configuration file, there is a DNS srv-consul-01 pointing to 172.21.5.152.

At this point, let’s really validate that the internal domain is working:

nslookup srv-consul-01.devops-db.internal 172.21.5.155

The return should be:

Server:         172.21.5.155
Address:        172.21.5.155#53
Name:   srv-consul-01.devops-db.internal
Address: 172.21.5.152

From now on, you can change the network settings / DNS Server of the hosts to 172.21.5.155 , so all search and resolution will be automatic.

Maintenance

Any change, addition or removal of DNS must be made in the devops-db-internal.zone, devops-db-com.zone and devops-db-local.zone file, then the container must be restarted, or a command run inside the DNS container:

$ rndc reload
server reload successful

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.