DNS in CentOS
Introduction
You can find general infor about DNS in this article:
« Domain Name System »
BIND - Berkeley Internet Name Domain. Most popular DNS in the world.
Prepation
Before installing bind, update the system and make sure that you have epel-release installed
sudo yum update
sudo yum upgrade
yum list epel-release
Loaded plugins: fastestmirror, langpacks Determining fastest mirrors * base: mirror.hosthink.net * epel: www.nic.funet.fi * extras: mirror.hosthink.net * updates: mirror.hosthink.net Installed Packages epel-release.noarch
Installed means that I have epel-release installed
If you see Available instead of Installed, then install with the command
sudo yum install epel-release
Install BIND
You can check for bind by running
yum list bind
Loaded plugins: fastestmirror, langpacks Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast Determining fastest mirrors * base: mirror.hosthink.net * epel: mirror.yandex.ru * extras: mirror.hosthink.net * updates: mirror.hosthink.net Available Packages bind.x86_64 32:9.11.4-26.P2.el7_9.5 updates
Available means that the package is not installed but is available for installation.
To install bind and bind-utils (needed, for example, for dig), you can use the command
sudo yum install -y bind bind-utils
Loaded plugins: fastestmirror, langpacks You need to be root to perform this command. [andrei@localhost ~]$ sudo yum install -y bind bind-utils Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile epel/x86_64/metalink | 29 kB 00:00 * base: mirror.hosthink.net * epel: mirror.yandex.ru * extras: mirror.hosthink.net * updates: mirror.hosthink.net base | 3.6 kB 00:00 epel | 4.7 kB 00:00 extras | 2.9 kB 00:00 updates | 2.9 kB 00:00 (1/4): epel/x86_64/updateinfo | 1.0 MB 00:01 (2/4): extras/7/x86_64/primary_db | 243 kB 00:01 (3/4): epel/x86_64/primary_db | 7.0 MB 00:03 (4/4): updates/7/x86_64/primary_db | 11 MB 00:05 Resolving Dependencies --> Running transaction check ---> Package bind.x86_64 32:9.11.4-26.P2.el7_9.7 will be installed --> Processing Dependency: bind-libs-lite(x86-64) = 32:9.11.4-26.P2.el7_9.7 for package: 32:bind-9.11.4-26.P2.el7_9.7.x86_64 --> Processing Dependency: bind-libs(x86-64) = 32:9.11.4-26.P2.el7_9.7 for package: 32:bind-9.11.4-26.P2.el7_9.7.x86_64 ---> Package bind-utils.x86_64 32:9.11.4-26.P2.el7_9.5 will be updated ---> Package bind-utils.x86_64 32:9.11.4-26.P2.el7_9.7 will be an update --> Running transaction check ---> Package bind-libs.x86_64 32:9.11.4-26.P2.el7_9.5 will be updated ---> Package bind-libs.x86_64 32:9.11.4-26.P2.el7_9.7 will be an update --> Processing Dependency: bind-license = 32:9.11.4-26.P2.el7_9.7 for package: 32:bind-libs-9.11.4-26.P2.el7_9.7.x86_64 ---> Package bind-libs-lite.x86_64 32:9.11.4-26.P2.el7_9.5 will be updated ---> Package bind-libs-lite.x86_64 32:9.11.4-26.P2.el7_9.7 will be an update --> Running transaction check ---> Package bind-license.noarch 32:9.11.4-26.P2.el7_9.5 will be updated ---> Package bind-license.noarch 32:9.11.4-26.P2.el7_9.7 will be an update --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: bind x86_64 32:9.11.4-26.P2.el7_9.7 updates 2.3 M Updating: bind-utils x86_64 32:9.11.4-26.P2.el7_9.7 updates 261 k Updating for dependencies: bind-libs x86_64 32:9.11.4-26.P2.el7_9.7 updates 157 k bind-libs-lite x86_64 32:9.11.4-26.P2.el7_9.7 updates 1.1 M bind-license noarch 32:9.11.4-26.P2.el7_9.7 updates 91 k Transaction Summary ================================================================================ Install 1 Package Upgrade 1 Package (+3 Dependent packages) Total download size: 3.9 M Downloading packages: No Presto metadata available for updates (1/5): bind-libs-9.11.4-26.P2.el7_9.7.x86_64.rpm | 157 kB 00:00 (2/5): bind-9.11.4-26.P2.el7_9.7.x86_64.rpm | 2.3 MB 00:02 (3/5): bind-libs-lite-9.11.4-26.P2.el7_9.7.x86_64.rpm | 1.1 MB 00:01 (4/5): bind-license-9.11.4-26.P2.el7_9.7.noarch.rpm | 91 kB 00:00 (5/5): bind-utils-9.11.4-26.P2.el7_9.7.x86_64.rpm | 261 kB 00:00 -------------------------------------------------------------------------------- Total 1.8 MB/s | 3.9 MB 00:02 Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : 32:bind-license-9.11.4-26.P2.el7_9.7.noarch 1/9 Updating : 32:bind-libs-lite-9.11.4-26.P2.el7_9.7.x86_64 2/9 Updating : 32:bind-libs-9.11.4-26.P2.el7_9.7.x86_64 3/9 Installing : 32:bind-9.11.4-26.P2.el7_9.7.x86_64 4/9 Updating : 32:bind-utils-9.11.4-26.P2.el7_9.7.x86_64 5/9 Cleanup : 32:bind-utils-9.11.4-26.P2.el7_9.5.x86_64 6/9 Cleanup : 32:bind-libs-9.11.4-26.P2.el7_9.5.x86_64 7/9 Cleanup : 32:bind-libs-lite-9.11.4-26.P2.el7_9.5.x86_64 8/9 Cleanup : 32:bind-license-9.11.4-26.P2.el7_9.5.noarch 9/9 Verifying : 32:bind-9.11.4-26.P2.el7_9.7.x86_64 1/9 Verifying : 32:bind-libs-9.11.4-26.P2.el7_9.7.x86_64 2/9 Verifying : 32:bind-utils-9.11.4-26.P2.el7_9.7.x86_64 3/9 Verifying : 32:bind-libs-lite-9.11.4-26.P2.el7_9.7.x86_64 4/9 Verifying : 32:bind-license-9.11.4-26.P2.el7_9.7.noarch 5/9 Verifying : 32:bind-libs-9.11.4-26.P2.el7_9.5.x86_64 6/9 Verifying : 32:bind-libs-lite-9.11.4-26.P2.el7_9.5.x86_64 7/9 Verifying : 32:bind-utils-9.11.4-26.P2.el7_9.5.x86_64 8/9 Verifying : 32:bind-license-9.11.4-26.P2.el7_9.5.noarch 9/9 Installed: bind.x86_64 32:9.11.4-26.P2.el7_9.7 Updated: bind-utils.x86_64 32:9.11.4-26.P2.el7_9.7 Dependency Updated: bind-libs.x86_64 32:9.11.4-26.P2.el7_9.7 bind-libs-lite.x86_64 32:9.11.4-26.P2.el7_9.7 bind-license.noarch 32:9.11.4-26.P2.el7_9.7 Complete!
The package we installed is called bind but the service is called named
Therefore, to start the service at system startup, you need to run
sudo systemctl enable named
Created symlink from /etc/systemd/system/multi-user.target.wants/named.service to /usr/lib/systemd/system/named.service.
While it is not running, the status will be inactive (dead)
systemctl status named
● named.service - Berkeley Internet Name Domain (DNS) Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled) Active: inactive (dead)
Start named
sudo systemctl start named
Restart named
sudo systemctl restart named
named status
sudo systemctl status -l named
● named.service - Berkeley Internet Name Domain (DNS) Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2026-08-04 09:04:33; EEST; 1s ago Process: 3143 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS) Process: 3141 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS) Main PID: 3145 (named) Tasks: 4 CGroup: /system.slice/named.service └─3145 /usr/sbin/named -u named -c /etc/named.conf Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:500:2f::f#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './NS/IN': 2001:500:2f::f#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:500:12::d0d#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './NS/IN': 2001:500:12::d0d#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:503:c27::2:30#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:500:12::d0d#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:500:9f::42#53 Aug 04 09:04:33 localhost.localdomain named[3145]: network unreachable resolving './DNSKEY/IN': 2001:500:a8::e#53 Aug 04 09:04:33 localhost.localdomain named[3145]: resolver priming query complete Aug 04 09:04:33 localhost.localdomain named[3145]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Check iptables
sudo iptables -L
On a clean system, there will most likely be no rules
Chain INPUT (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination
If firewall is already enabled you need to open port 53
Check netstat
netstat can show which ports are being listened to
netstat -ltn
If named is off
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN
If named is on
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 ::1:53 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:953 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN
Port 53 listens for DNS lookupup
Port 953 is used to monitor the DNSNS server
You can explore the full list of TCP/UDP ports
here
dig: exec DNS request
On external server
To exec dig install bind-utils
dig www.aredel.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> www.aredel.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23334 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4000 ;; QUESTION SECTION: ;www.aredel.com. IN A ;; ANSWER SECTION: www.aredel.com. 600 IN A 87.236.16.208 ;; Query time: 37 msec ;; SERVER: 10.10.10.1#53(10.10.10.1) ;; WHEN: Mon Sep 13 12:16:40 EEST 2021 ;; MSG SIZE rcvd: 67
On local DNS server
If bind is installed and running, you can dig on it.
[root@dns-server ~]# dig www.aredel.com @127.0.0.1
If named is disabled or bind is not installed, you will not be able to dig on the local host.
Get, for example ;; connection timed out; no servers could be reached
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> www.aredel.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4712 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.aredel.com. IN A ;; ANSWER SECTION: www.aredel.com. 600 IN A 87.236.16.208 ;; AUTHORITY SECTION: ANDREYOLEGOVICH.ru. 345600 IN NS ns1.beget.pro. ANDREYOLEGOVICH.ru. 345600 IN NS ns2.beget.com. ANDREYOLEGOVICH.ru. 345600 IN NS ns1.beget.RU. ANDREYOLEGOVICH.ru. 345600 IN NS ns2.beget.RU. ANDREYOLEGOVICH.ru. 345600 IN NS ns1.beget.com. ANDREYOLEGOVICH.ru. 345600 IN NS ns2.beget.pro. ;; ADDITIONAL SECTION: ns2.BEGET.ru. 345600 IN A 185.50.27.12 ns1.BEGET.ru. 345600 IN A 5.101.159.11 ;; Query time: 298 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Tue Aug 04 09:04:33 EEST 2026 ;; MSG SIZE rcvd: 263
Please note that the response now contains the AUTHORITY SECTION.
From it, you can find out that the domain
aredel.com
is located in the area of responsibility
ns1.beget.pro.
and five more beget servers.
For more information, see the article DNS
Personally, I recommend the services to everyone
beget.com.
As you can see, I use them myself.
dig mail.google.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> mail.google.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5444 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;mail.google.com. IN A ;; ANSWER SECTION: mail.google.com. 61158 IN CNAME googlemail.l.google.com. googlemail.l.google.com. 258 IN A 216.58.207.197 ;; Query time: 2 msec ;; SERVER: 192.168.0.1#53(192.168.0.1) ;; WHEN: Sat Sep 11 22:04:54 EEST 2021 ;; MSG SIZE rcvd: 87
DNS servers types: caching and forwarding
A caching DNS server works by executing all DNS queries performed by your system and then storing or caching the results in memory.
The redirecting DNS server sends a request to another server and waits for it to do the work for it.
You can learn more about the features of caching and forwarding servers in the article «DNS server types»
named.conf - file with named settings
File with settigns is called named.conf and is located in
/etc
Configure caching DNS server
Let's make some small changes to the configuration file
vi /etc/named.conf
// // named.conf // // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS // server as a caching only nameserver (as a localhost DNS resolver only). // // See /usr/share/doc/bind*/sample/ for example named configuration files. // // See the BIND Administrator's Reference Manual (ARM) for details about the // configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html options { listen-on port 53 { 127.0.0.1; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; recursing-file "/var/named/data/named.recursing"; secroots-file "/var/named/data/named.secroots"; allow-query { localhost; }; /* - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. - If you are building a RECURSIVE (caching) DNS server, you need to enable recursion. - If your recursive DNS server has a public IP address, you MUST enable access control to limit queries to your legitimate users. Failing to do so will cause your server to become part of large scale DNS amplification attacks. Implementing BCP38 within your network would greatly reduce such attack surface */ recursion yes; dnssec-enable yes; dnssec-validation yes; /* Path to ISC DLV key */ bindkeys-file "/etc/named.root.key"; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key";
Let's make changes
options { listen-on port 53 { any; }; listen-on-v6 port 53 { none; };
Checking the configuration
[root@dns-server ~]# named-checkconf
[root@dns-server ~]# named-checkconf -v
9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7
systemctl restart named
[root@dns-server ~]# netstat -ltn
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.56.149:53 0.0.0.0:* LISTEN tcp 0 0 10.0.2.49:53 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:953 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN
Port 53 is no longer being listened to on IPv6. The number of IPv4 addresses on which port 53 is now being listened to has increased - compare with What happened before if you don't remember.
query
You can allow requests to the server by specifying the desired host or network in allow-query
options { listen-on port 53 { any; }; listen-on-v6 port 53 { none; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; recursing-file "/var/named/data/named.recursing"; secroots-file "/var/named/data/named.secroots"; allow-query { localhost; 192.168.56.0/24 };
Use a DNS server from a local network
In this example, there are two hosts on the network:
dns-server.andrei.com
with IP address
192.168.56.149
host113.andrei.com
with IP address
192.168.56.113
I remind you that the following changes have been made to named.conf
options { listen-on port 53 { any; }; listen-on-v6 port 53 { none; }; … allow-query { localhost; 192.168.56.0/24 };
Open port 53 for tcp and udp on the 192.168.56.149 server
[root@dns-server ~]# firewall-cmd --zone=public --add-port=53/tcp --permanent
[root@dns-server ~]# firewall-cmd --zone=public --add-port=53/udp --permanent
[root@dns-server ~]# firewall-cmd --reload
You can study the full list of ports in the
« Networks »
article
Read more about working with Firewall in the following article:
« CentOS Firewall »
On the host 192.168.56.113, you can now perform dig @192.168.56.149
and if the dns server has the necessary data, it should work.
In this example, the default is set to
recursion yes;
If you have not done this, in order to make requests to unknown names - you need to allow the server to do recursive queries .
[root@host113 ~]# dig www.heihei.ru @192.168.56.149
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> www.heihei.ru @192.168.56.149 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44716 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.heihei.ru. IN A ;; ANSWER SECTION: www.heihei.ru. 598 IN A 87.236.16.208 ;; Query time: 84 msec ;; SERVER: 192.168.56.149#53(192.168.56.149) ;; WHEN: Mon Sep 13 14:30:39 EEST 2021 ;; MSG SIZE rcvd: 58
Configuring the forwarding DNS server
vi /etc/named.conf
Let's leave the config from the previous example and add it to the end of the options block
options { … forwarders { 8.8.8.8; 8.8.4.4; 1.1.1.1; 1.0.0.1; }; forward only;
8.8.8.8; 8.8.4.4; - these are Google public DNS servers
1.1.1.1; 1.0.0.1; - these are Cloudflare public DNS servers
The order of enumeration does not matter - the one from which the response is faster will be used.
forward it can take one of two values: first or only
You can learn more about the first and only options in the article forward