1. Home
  2. Docs
  3. The BIND (named) DNS server
  4. The Basic Necessities

The Basic Necessities

The bind DNS server is massive, so we’re only going to cover some basic necessities commonly found for it today.

As previously mentioned, the most common use for the bind DNS server is for forwarding and caching:

Configuring BIND as a caching DNS server
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_networking_infrastructure_services/assembly_setting-up-and-configuring-a-bind-dns-server_networking-infrastructure-services#proc_configuring-bind-as-a-caching-dns-server_assembly_setting-up-and-configuring-a-bind-dns-server

However, in most situations there are 5 typical “Needs” for a DNS server to fulfill:

Need 1: client machines need to be able to resolve each other’s hostnames (resolve local network hostnames within the internal business domain both forward and reverse)

Need 2: client machines need to be able to resolve the internal webserver’s subdomain and/or IP (resolve web application subdomain within the internal business domain both forward and reverse)

Need 3: client machines need to be able to resolve internet domains as well (resolve external internet domains)

Need 4: client machines need DNS caching (cache all DNS query results for faster DNS performance)

Need 5: We’re paranoid, we want our DNS server to run in a chroot (run our DNS server in a chrooted environment)

Let’s set up an example.

  • We have 3 servers on our network, all under the internal domain fakedomain.dev
  • One is our DNS server (rhel92)
  • One is a webserver hosting a custom subdomain used for an internal web application (rhel89)
  • One is just a desktop machine used by the office staff to perform work on the internal web application (rhel88)

You’re going to want to do two things here.

1. Setup caching + forwarding locally on the 2 servers that are -not- the DNS server with something lightweight like dnsmasq or unbound.

Set the forward nameserver to your BIND dns server. In our example our BIND server’s IP is 192.168.0.66

rhel89, rhel88:

# dnf install dnsmasq
# systemctl enable --now dnsmasq
# echo 'nameserver 127.0.0.1' > /etc/resolv.conf
# echo 'options edns0' >> /etc/resolv.conf
# echo 'resolv-file=/etc/resolv.dnsmasq' >> /etc/dnsmasq.conf
# echo 'cache-size=1000' >> /etc/dnsmasq.conf
# echo 'interface=lo' >> /etc/dnsmasq.conf
# echo 'bind-interfaces' >> /etc/dnsmasq.conf
# echo 'nameserver 192.168.0.66' > /etc/resolv.dnsmasq
# systemctl restart dnsmasq

We didn’t use all of the options required for dnsmasq in our example, just a few for basic functionality. It’s advised to follow along here for proper configuration:

How to configure DNS caching server with dnsmasq in RHEL
https://access.redhat.com/solutions/2189401

Alternatively you could just point all of the servers to the DNS server IP, but then you would be missing per-machine DNS caching. Having something like DNS or unbound running on each machine before it forwards to the DNS server allows each machine to have their own personal cache on the client side. The BIND DNS nameserver itself will also have caching itself for the server side.

This resolves “Need 4” in the list. (cache all DNS query results for faster DNS performance)

When each server queries for another server’s hostname, we also need to search under the domain ‘fakedomain.dev’
So we need to add these additional /etc/resolv.conf lines to all machines:

# echo 'search .fakedomain.dev' >> /etc/resolv.conf

All 3 machines should have an /etc/resolv.conf that looks like this:

nameserver 127.0.0.1
options edns0
search fakedomain.dev

And on each server we need to make sure to set the fqdn:

# hostname rhel88.fakedomain.dev
# hostname rhel89.fakedomain.dev
# hostname rhel92.fakedomain.dev

These steps are part of the requirements for “Need 1” and “Need 2“.

2. By default, the BIND DNS server has caching, we just need to configure two things:

  • Configure forwarding external internet queries
  • Configure our internal domain and hostnames (and webserver subdomain)

This will allow our bind dns server to answer queries from the other four systems for both internal and external domains.

On the bind dns server (rhel92):

# dnf install bind bind-chroot bind-utils
# echo 'nameserver 127.0.0.1' > /etc/resolv.conf

And enable dns access in our firewall:

# firewall-cmd --permanent --add-service=dns
# firewall-cmd --reload

First, let’s edit our configuration file to allow caching and forwarding of external internet domain queries:

Configuring BIND as a caching DNS server
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_networking_infrastructure_services/assembly_setting-up-and-configuring-a-bind-dns-server_networking-infrastructure-services#proc_configuring-bind-as-a-caching-dns-server_assembly_setting-up-and-configuring-a-bind-dns-server

Note in the example below ‘….’ is just to show skipping of unrelated configurations. They are not part of the configuration file.

# vim /etc/named.conf

options {
....
        listen-on port 53 { 127.0.0.1;192.168.0.66; };
        allow-query { localhost; 192.168.0/24; };
        allow-recursion { localhost; 192.168.0/24; };
        forwarders { 8.8.8.8;8.8.4.4; }; # forward unknown domains to google dns servers
....
}

This tells our nameserver:

  • Listen on localhost and on IP 192.168.0.66
  • Allow queries and recursion only from localhost and any IP address in the 192.168.0.* range.
  • Forward unknown queries to google

So, with this we should be able to resolve something like www.redhat.com from all 3 machines:

rhel88, rhel89 dnsmasq caching -> bind dns server:

[root@rhel88 ~]# nslookup redhat.com
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   redhat.com
Address: 52.200.142.250
Name:   redhat.com
Address: 34.235.198.240

[root@rhel89 ~]# nslookup redhat.com
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   redhat.com
Address: 52.200.142.250
Name:   redhat.com
Address: 34.235.198.240

and our bind server rhel92 directly:

[root@rhel92 ~]# nslookup redhat.com
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   redhat.com
Address: 34.235.198.240
Name:   redhat.com
Address: 52.200.142.250

Great! This resolves “Need 3” in the list. (resolve external internet domains)

3. Now, we need them to be able to resolve eachother’s hostnames within fakedomain.dev

The RHEL admin manual tells you how to create records for new zones:

4.6.2. Setting up a forward zone on a BIND primary server
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/assembly_setting-up-and-configuring-a-bind-dns-server_deploying-different-types-of-servers#proc_setting-up-a-forward-zone-on-a-bind-primary-server_assembly_configuring-zones-on-a-bind-dns-server

Once again, let’s open up /etc/named.conf.

This time we’re going to go to the bottom and add another zone:

# vim /etc/named.conf
zone "fakedomain.dev" {
    type master;
    file "fakedomain.dev.zone";
};

Save and close the file. Next we need to create ‘fakedomain.dev.zone’ and fill it with records. Again — continue following the ‘4.6.2. Setting up a forward zone on a BIND primary server’ directions, step 3:

Create the /var/named/fakedomain.dev.zone file, for example, with the following content:

$TTL 8h
@ IN SOA ns1.fakedomain.dev. fakedomain.dev. (
                          2022070601 ; serial number
                          1d         ; refresh period
                          3h         ; retry period
                          3d         ; expire time
                          3h )       ; minimum TTL

                  IN NS   ns1.fakedomain.dev.

ns1                  IN A    192.168.0.66
rhel92               IN A    192.168.0.66

We have to add the ns1 entry for our nameserver because as noted in the admin manual to be functional, a zone requires at least one name server (NS) record.
We also add the A record so that our DNS server IP resolves to it’s hostname (rhel92.fakedomain.dev)

After that, reload named:

# systemctl reload named

And NOW — verify our hostname lookup works locally on the bind server:

[root@rhel92 ~]# nslookup rhel92
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel92.fakedomain.dev
Address: 192.168.0.66

Now we need to map the other two servers and the subdomain for our webapp to our records:

Once again open the zone file, and add our entries:

# vim /var/named/fakedomain.dev.zone
.....
$TTL 8h
@ IN SOA ns1.fakedomain.dev. fakedomain.dev. (
                          2022070601 ; serial number
                          1d         ; refresh period
                          3h         ; retry period
                          3d         ; expire time
                          3h )       ; minimum TTL

                  IN NS   ns1.fakedomain.dev.

ns1                  IN A    192.168.0.66
rhel92               IN A    192.168.0.66
rhel89               IN A    192.168.0.63
webapp               IN A    192.168.0.63
rhel88               IN A    192.168.0.67
.....

Remember, our rhel89 system is a webserver, which hosts a custom webapp within our organization’s subdomain, this is why both the ‘rhel89.fakedomain.dev’ and ‘webapp.fakedomain.dev’ both point to the same IP.

Save and close the file, reload the service:

# systemctl reload named

And now, magically all of our systems should be able to resolve any of those addresses:

rhel92:

[root@rhel92 ~]# nslookup rhel88
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel88.fakedomain.dev
Address: 192.168.0.67

[root@rhel92 ~]# nslookup rhel89
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel89.fakedomain.dev
Address: 192.168.0.63

[root@rhel92 ~]# nslookup webapp
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   webapp.fakedomain.dev
Address: 192.168.0.63

rhel89:

[root@rhel89 ~]# nslookup rhel92
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel92.fakedomain.dev
Address: 192.168.0.66

[root@rhel89 ~]# nslookup rhel89
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel89.fakedomain.dev
Address: 192.168.0.63

[root@rhel89 ~]# nslookup webapp
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   webapp.fakedomain.dev
Address: 192.168.0.63

rhel88:

[root@rhel88 ~]# nslookup rhel92
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel92.fakedomain.dev
Address: 192.168.0.66

[root@rhel88 ~]# nslookup rhel89
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rhel89.fakedomain.dev
Address: 192.168.0.63

[root@rhel88 ~]# nslookup webapp
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   webapp.fakedomain.dev
Address: 192.168.0.63

That handles forward lookups for “Need 1” and “Need 2” but we still need reverse lookups for looking up domains based on IP address.

Again, RHEL admin manual has you covered:

4.6.3. Setting up a reverse zone on a BIND primary server
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/assembly_setting-up-and-configuring-a-bind-dns-server_deploying-different-types-of-servers#proc_setting-up-a-reverse-zone-on-a-bind-primary-server_assembly_configuring-zones-on-a-bind-dns-server

Open /etc/named.conf again and:

# vim /etc/named.conf
....
zone "0.168.192.in-addr.arpa" {
    type master;
    file "0.168.192.in-addr.arpa.zone";
};
....

Save and close the file.

This will add a reverse lookup entry for addresses starting with 192.168.0.*.

Now just like our forward zone, we need to make a zone record file for our reverse lookups:

# vim /var/named/0.168.192.in-addr.arpa.zone
....
$TTL 8h
@ IN SOA ns1.fakedomain.dev. fakedomain.dev. (
                          2022070601 ; serial number
                          1d         ; refresh period
                          3h         ; retry period
                          3d         ; expire time
                          3h )       ; minimum TTL

                  IN NS   ns1.fakedomain.dev.

66                IN PTR  ns1.fakedomain.dev.
66                IN PTR  rhel92.fakedomain.dev.
63                IN PTR  rhel89.fakedomain.dev.
63                IN PTR  webapp.fakedomain.dev.
67                IN PTR  rhel88.fakedomain.dev.
....

Again, save and reload named.service:

# systemctl reload named.service

Voila, now any of our servers can do reverse lookups via IP:

[root@rhel92 ~]# nslookup 192.168.0.63
63.0.168.192.in-addr.arpa       name = webapp.fakedomain.dev.
63.0.168.192.in-addr.arpa       name = rhel89.fakedomain.dev.

[root@rhel92 ~]# nslookup 192.168.0.67
67.0.168.192.in-addr.arpa       name = rhel88.fakedomain.dev.

[root@rhel92 ~]# nslookup 192.168.0.66
66.0.168.192.in-addr.arpa       name = ns1.fakedomain.dev.
66.0.168.192.in-addr.arpa       name = rhel92.fakedomain.dev.

These are now covered:
Need 1: (resolve local network hostnames within the internal business domain both forward and reverse)
Need 2: (resolve web application subdomain within the internal business domain both forward and reverse)

4. Ok, we’ve walked through and completed Needs 1,2,3 and 4, now we’re on the final “Need 5“. We need bind to run in a chroot environment. This is simple.

Shut down and disable named.service:

[root@rhel92 ~]# systemctl stop named
[root@rhel92 ~]# systemctl disable named

Start and enable named-chroot.service:

[root@rhel92 ~]# systemctl enable --now named-chroot.service

Finally, our last requirement has now been fulfilled:
Need 5: (run our DNS server in a chrooted environment)

IMPORTANT THING TO REMEMBER:

With named-chroot.service a chroot is created at /var/named/chroot/

Inside this chroot is the new ‘var/named’ directory. Our zone records from the standard named instance get copied here upon the first startup AND/OR reload of the named-chroot service.

Some customers will have different copies in /var/named/ from /var/named/chroot/var/named/ so it’s important to determine if they are using named-chroot or not and get copies from BOTH directories.


Was this article helpful to you? Yes No

How can we help?