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
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.
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.
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