MaruOpsInfrastructure and AI notes

About (Korean)Contact (Korean)

Build a DNS Server on Rocky Linux 9 with BIND: Forward and Reverse Zones

Server rack with multiple network cables connected

Reference photo · Server rack with multiple network cables connected · Photo: Kim Scarborough / Source / CC BY-SA 2.0 · Resized for listings; illustrative photo, not the tested environment

An internal DNS service lets clients reach a server by a name such as node1.lab.com. Address changes can then be recorded in the DNS zone rather than remembered on each client. Configure BIND’s forward and reverse zones and verify the answers before switching the clients’ resolver settings.

Install BIND on Rocky Linux 9 to create an internal DNS server managing names and addresses for lab.com. The guide connects forward lookups, reverse lookups and the client resolver configuration.

On this page

Lab environment and scope of domain use

itemexample valueUse
internal network192.168.10.0/24Bands to allow DNS lookups
DNS serverns1.lab.com / 192.168.10.10Rocky Linux 9, BIND
time serverntp.lab.com / 192.168.10.20Link to separate chronyd article
clientnode1.lab.com / 192.168.10.30Host to test inquiry/connection
aliaswww.lab.comCNAME pointing to node1.lab.com

The above address is a practice home. Communication between the server and client must be enabled, and the static IP of the DNS server must already be set. If you are preparing a static IP first, please refer to Rocky Linux 9 Static IP Settings article first. The command runs under an account with sudo privileges.

lab.com is not a reserved example domain. The requested name is only used within the isolated lab network. For your operational network, use a subdomain of the domain you manage. As long as this server has the lab.com zone, it will mask the same name on the public Internet as an internal record and will not automatically ask the public DNS again for the lab.com subname that is not internal. Reserved example domains can be found in the IANA guide .

1. Install BIND and save existing settings

BIND is DNS server software, and in Rocky Linux, the service name is named. First install the package and back up your settings. We will proceed based on the new lab server, not the existing DNS server.

sudo dnf install -y bind bind-utils
rpm -q bind bind-utils
sudo cp -a /etc/named.conf /etc/named.conf.before-lab

bind-utils provides diagnostic tools including dig and nslookup. If a backup already exists, use a different name to retain the earlier copy. Keep SELinux enforcing and use the ordinary named service rather than named-chroot. The configuration follows the RHEL 9 BIND guide.

2. Specify receiving address and allowable viewing band

Open the file with sudo vi /etc/named.conf. Add the ACL below before the existing options. ACL is a list of addresses that will allow access.

acl "lab_clients" {
    127.0.0.1;
    192.168.10.0/24;
};

Find and modify the following items within the existing options { ... };, and add only the missing items. options Do not create another block or duplicate the same item. Below is the part to be modified and is not the entire contents of the file.

listen-on port 53 { 127.0.0.1; 192.168.10.10; };
listen-on-v6 port 53 { none; };
allow-query { lab_clients; };
recursion yes;
allow-recursion { lab_clients; };
allow-query-cache { lab_clients; };
allow-transfer { none; };

This example is for an IPv4 internal network. listen-on must be the address the server actually has. Leave directory "/var/named";, DNSSEC verification settings, default zone, and include in the default file as is. Recursive lookup is a function where the server asks a question to another DNS to find an answer, and is only allowed in the internal band. Zone transfer is a function that replicates an entire zone to another DNS server, and is blocked in this lab as it does not configure a secondary DNS.

To find external names using basic recursive lookup, TCP/UDP 53 communication must be possible from the DNS server to the Internet’s DNS server. If you only allow company-specified parent DNS, specify the physical address as forwarders, and optionally use forward only;. For a closed network that does not require external inquiry, only the internal zone can be provided by changing options to recursion no;.

3. Forward/reverse zone registration

A zone is a namespace managed by this DNS server. Create /etc/named.lab.zones with the following contents: If there are existing files in this path, archive them first and merge the contents.

sudo tee /etc/named.lab.zones > /dev/null <<'EOF'
zone "lab.com" IN {
    type master;
    file "lab.com.zone";
    allow-update { none; };
};

zone "10.168.192.in-addr.arpa" IN {
    type master;
    file "192.168.10.rev";
    allow-update { none; };
};
EOF

lab.com is the forward zone. The reverse zone’s 10.168.192.in-addr.arpa is the name of the previous three octets of 192.168.10.0/24 written backwards. This example is based on /24; bands of different sizes should not simply be cut in the same way.

Add the following line only once, in the global location at the bottom of /etc/named.conf: options is not put inside.

include "/etc/named.lab.zones";

The relative path of file is interpreted relative to the default directory "/var/named";. Therefore, save the file in the next step to /var/named/.

4. Create lab.com forward record

Save the contents below in /var/named/lab.com.zone.

sudo tee /var/named/lab.com.zone > /dev/null <<'EOF'
$TTL 3600
@   IN SOA ns1.lab.com. hostmaster.lab.com. (
        2026102301 ; serial
        3600       ; refresh
        900        ; retry
        604800     ; expire
        300        ; negative cache TTL
)
    IN NS    ns1.lab.com.
@   IN A     192.168.10.30
ns1 IN A     192.168.10.10
ntp IN A     192.168.10.20
node1 IN A   192.168.10.30
www IN CNAME node1.lab.com.
EOF

A concatenates a name and an IPv4 address, and CNAME is an alias that points to another name. NS specifies the DNS server for this zone. SOA is the standard information for the zone, and hostmaster.lab.com. is an example value representing the administrator email address hostmaster@lab.com. Replace this with the actual management address when operating.

Add a dot after the complete name, such as ns1.lab.com.. If the dot is removed, the current zone name is added again and can be interpreted as ns1.lab.com.lab.com.. @ is the zone itself, lab.com. www Creating an alias does not mean that the web server will be installed.

2026102301 of serial are initial example values. Afterwards, whenever the zone contents are changed, it increases the existing value. When using date format, the second correction on the same day is raised as 2026102302.

5. Set reverse records and file permissions

This time we concatenate the last octet of the IP address with the hostname.

sudo tee /var/named/192.168.10.rev > /dev/null <<'EOF'
$TTL 3600
@   IN SOA ns1.lab.com. hostmaster.lab.com. (
        2026102301
        3600
        900
        604800
        300
)
    IN NS  ns1.lab.com.
10  IN PTR ns1.lab.com.
20  IN PTR ntp.lab.com.
30  IN PTR node1.lab.com.
EOF

sudo chown root:named /etc/named.lab.zones \
  /var/named/lab.com.zone /var/named/192.168.10.rev
sudo chmod 640 /etc/named.lab.zones \
  /var/named/lab.com.zone /var/named/192.168.10.rev
sudo restorecon -v /etc/named.lab.zones \
  /var/named/lab.com.zone /var/named/192.168.10.rev

PTR is the record that looks up the name from the IP. 30 means 192.168.10.30 in this reverse zone. Since this server only reads files, there is no need to widen write permissions. restorecon recovers the SELinux context of the standard path. Turn off SELinux or do not apply chmod 777 due to permission issues.

6. Apply firewall and services after checking grammar

Before starting the service, both zones and the entire setup are checked.

sudo named-checkzone lab.com /var/named/lab.com.zone
sudo named-checkzone 10.168.192.in-addr.arpa /var/named/192.168.10.rev
sudo named-checkconf -z /etc/named.conf

Check whether OK appears in named-checkzone. named-checkconf -z checks both the configuration syntax and the loading of the main zone file. If there are any errors, correct the file path, semicolon, parenthesis, and dot at the end of the name.

The server running firewalld first checks the zone of the interface receiving client traffic.

sudo firewall-cmd --get-active-zones

The following is a case where the zone is public. If it is a different zone, change it to that name. dns service allows both TCP and UDP 53. TCP can also be used for general DNS lookups, so we don’t just open UDP.

sudo firewall-cmd --permanent --zone=public --add-service=dns
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --query-service=dns

sudo systemctl enable --now named
sudo systemctl restart named
sudo systemctl status named --no-pager
sudo ss -lntup '( sport = :53 )'

Verify that query-service is yes and service is active (running). The receiving address must contain 192.168.10.10:53. If you are using another firewall instead of firewalld, the policy allows it, and DNS access is also restricted by the BIND ACL specified earlier.

7. Test inquiry by directly specifying the server

First, run it on the DNS server itself. Next, run the same command on the client to check the network path. The client also needs bind-utils.

dig @192.168.10.10 ns1.lab.com A
dig @192.168.10.10 node1.lab.com A +short
dig @192.168.10.10 www.lab.com CNAME +short
dig @192.168.10.10 -x 192.168.10.30 +short
dig @192.168.10.10 lab.com SOA +short
dig @192.168.10.10 node1.lab.com A +tcp +short

Below are the values expected from the above settings. It is not a table of actual logarithms, but a standard to compare your results with.

Check forexpected value
ns1.lab.com AStatus NOERROR, response IP 192.168.10.10, authority response flag aa
node1.lab.com A192.168.10.30
www.lab.com CNAMEnode1.lab.com.
192.168.10.30 PTRnode1.lab.com.
lab.com SOAIncludes serial number set with ns1.lab.com.
TCP lookup192.168.10.30

If the environment uses Internet recursive lookup, also check dig @192.168.10.10 rockylinux.org A. If the internal name works but the external name fails, it is quicker to check the upper DNS/Internet path, server time, and DNSSEC verification log rather than recreating the internal zone.

8. Set it as the client’s primary DNS

Change the client settings after the directly specified dig @... is successful. Check the NetworkManager connection name in Rocky Linux 9 with the command below.

nmcli -t -f NAME,DEVICE connection show --active

The following example is where the connection name is ens160. Replace the value in the first line with the actual connection name you saw above. Make a note of the DNS/DHCP override settings before changing them, and if you have multiple NICs, select exactly which connection will provide DNS.

LAB_CONNECTION='ens160'
nmcli -f ipv4.dns,ipv4.dns-search,ipv4.ignore-auto-dns,ipv6.ignore-auto-dns \
  connection show "$LAB_CONNECTION"

sudo nmcli connection modify "$LAB_CONNECTION" \
  ipv4.dns "192.168.10.10" \
  ipv4.dns-search "lab.com" \
  ipv4.ignore-auto-dns yes \
  ipv6.ignore-auto-dns yes
sudo nmcli device reapply ens160

The last ens160 is device name, which may be different from the connection name. Replace it with your actual device name. Items that are not applicable with reapply can be reactivated with nmcli connection up "$LAB_CONNECTION" while console access is available. Since the SSH connection may be lost, there is no rush to re-enable it while only remote access is available.

nmcli device show ens160
cat /etc/resolv.conf
dig node1.lab.com A
getent hosts node1.lab.com
getent hosts node1

Verify that SERVER of dig is internal DNS. getent also reflects /etc/hosts, etc., so if you registered the same name in the past, try to distinguish them. Search domain lab.com is used to find the short name node1. The reason IPv6 automatic DNS is also ignored is to prevent other DNS from interfering with internal name queries. Check the DNS of any other active connections or VPNs as well.

If you put a public DNS that does not know your internal zone as a secondary address, internal name lookups may fail erratically. If redundancy is required, prepare a second DNS serving the same internal zone. If you manually modify /etc/resolv.conf, NetworkManager can rewrite it, so it is managed in the connection profile.

Change records and check for errors

After modifying the record, upload the serial of the zone and perform the inspection again. When the service is running, the configuration is read back with the following command:

sudo named-checkconf -z /etc/named.conf
sudo rndc reload
sudo journalctl -u named -n 60 --no-pager

Clients with TTL remaining or intermediate DNS may retain the previous value. At this time, compare the results of the search by specifying the server directly and the results of the general search.

symptomsWhere to check first
connection timed outServer IP/path, receiving address, firewall zone, TCP/UDP 53
REFUSEDIs the requested client IP included in lab_clients?
SERVFAILZone load errors and logs, DNSSEC/higher path/server time for external queries
NXDOMAINWhether a record exists for the searched name, the zone name, and the dot at the end of the name
@서버IP succeeds, normal query failsClient DNS, other NIC·VPN, /etc/hosts and cache

Now, if the reverse lookup matches node1.lab.com, you can start managing your internal name. Next, to configure ntp.lab.com as a real time server, please refer to chronyd Local Time Server Configuration article .

Confirmation range: Official document confirmed on October 23, 2026. We verified the example’s zone syntax and forward, reverse, CNAME, and TCP lookups in a Rocky Linux 9 container. Application of the entire VM in firewalld·NetworkManager·systemd and SELinux enforcing states requires separate confirmation. The representative image is a reference photo of a typical server rack and is not a photo of this lab environment.

reference document