How to Install a Local DNS Resolver with Dnsmasq on Rocky Linux
Dnsmasq is a small and lightweight DNS server for your local environment. It can be used to provide a DNS Server, DHCP Server, and a TFTP Server. As for the DNS Server, the Dnsmasq can be used as a forwarder, recursive DNS Server, and DNS caching system. It also loads DNS contents from the /etc/hosts file, which allows you to set up domain names for local hostnames.
Dnsmasq is designed to be lightweight with a small footprint, suitable for low-resource devices such as Routers and Firewalls. Dnsmasq has low system requirements and consumes low resources. It can be run on Linux, BSDs, Android, and macOS.
This tutorial will cover installing and setting up a local DNS Server with Dnsmasq on a Rocky Linux 9 server. You'll install Dnsmasq and set up the local DNS Server with some additional features, such as enabling local domain names, setting up sub-domains via /etc/hosts file, and enabling the DNS cache for faster access. Lastly, you'll enable the DHCP server via Dnsmasq.
You'll also learn how to set up client machines to use the local DNS Server as the primary DNS resolver.
Prerequisites
There are several prerequisites that you must have before you get started. Below are the lists of prerequisites:
- A Rocky Linux 9 server - This example uses the Rocky Linux with hostname 'dnsmasq-rocky' and the IP address '192.168.5.50'.
- A non-root user with sudo/root administrator privileges.
- SELinux is running with 'permissive' mode.
For client machines, you can use any Linux distribution. You can use Debian-based or RHEL-based distributions as for client machines.
Prepare System
On RHEL-based operating systems, the default DNS resolver '/etc/resolv.conf' is generated by the NetworkManager service. Before you install Dnsmasq, you'll set up a static DNS resolver via /etc/resolv.conf file and disable the DNS resolver from the NetworkManager service.
To start, open the NetworkManager config file /etc/NetworkManager/NetworkManager.conf using the below nano editor command.
sudo nano /etc/NetworkManager/NetworkManager.conf
Add the line 'dns=none' within the section '[section]'.
[main]
dns=none
Save the file and exit the editor when you're finished.
Next, open the DNS resolver config file '/etc/resolv.conf' using the nano editor command below.
sudo nano /etc/resolv.conf
Delete all available lines and replace them with the following lines. With this, you'll be using the Cloudflare and Google public DNS as the main DNS server.
nameserver 1.1.1.1
nameserver 8.8.8.8
Save the file and exit when you're done.
Lastly, run the below systemctl command to restart the NetworkManager and apply the changes.
sudo systemctl restart NetworkManager
With these settings finished, your DNS resolver will not be changed by the NetworkManager service and you can add or change the DNS resolver at any time.
In the next steps, you'll start the Dnsmasq installation and configuration on Rocky Linux.
Installing Dnsmasq on Rocky Linux
In this step, you'll install the Dnsmasq package on a Rocky Linux server. Then, you'll start and enable the Dnsmasq service to run upon the system bootup.
By default, the 'dnsmasq' package is available on the Rocky Linux AppStream repository. Run the below dnf command to get information about the 'dnsmasq' package.
sudo dnf info dnsmasq
The Dnsmasq v2.85 is available on Rocky Linux 9 at the time of this writing.
Now run the below command to install Dnsmasq. Input y when prompted for the confirmation, then press ENTER to proceed.
sudo dnf install dnsmasq dnsmasq-utils
The Dnsmasq installation should now be started.
After installing the Dnsmasq, run the below systemctl command to start and enable the 'dnsmasq' service. With the below command executed, the 'dnsmasq' service should now be running and enabled, which will start automatically upon the bootup.
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq
Verify the 'dnsmasq' service via the systemctl command utility below.
sudo systemctl status dnsmasq
You'll receive the output like this - The 'dnsmasq' service is currently running, enabled, and will be run automatically at bootup.
With the Dnsmasq is installed and running, you'll next start the configuration of Dnsmasq to run as a local DNS Server.
Configuring Dnsmasq
In this step, you'll set up the Dnsmasq as the local DNS Server with some enabled features such as cache DNS, and DHCP server, and configure the domain name and sub-domains for local applications. This allows your application to be accessible via the local domain names/sub-domains such as 'db1.howtoforge.local', 'app.howtoforge.local', and many more.
To start, run the below command to copy the default Dnsmasq config file to '/etc/dnsmasq.conf.orig', then open the original Dnsmasq configuration file '/etc/dnsmasq.conf' using the below nano editor command.
sudo cp /etc/dnsmasq.conf{,.orig}
sudo nano /etc/dnsmasq.conf
Add the following lines to the file.
# dnsmasq run on UDP port 53
# with IP address localhost and 192.168.5.50
# and network interface eth1
port=53
listen-address=127.0.0.1,192.168.5.50
interface=eth1
# disable forwarding of non-routed address
# disable forwarding names without the main domain.com
# automatically append the domain part to simple names
# disable dnsmasq to read /etc/resolv.conf file
domain-needed
bogus-priv
expand-hosts
no-resolv
# upstream DNS server for non-local domains
# using Cloudflare and google public DNS
server=1.1.1.1
server=8.8.8.8
# define the domain for dnsmasq
domain=howtoforge.local
address=/howtoforge.local/192.168.5.50
# enable DNS Cache and adjust cache-size
cache-size=10000
# enable dhcp via dnsmasq
# define lease db file
# make the dhcp server as an authoritative
dhcp-range=192.168.5.100,192.168.5.150,12h
dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases
dhcp-authoritative
Save the file and exit the editor when you're finished.
Below is the detailed options that you'll be using for your Dnsmasq installation:
- port: which port you will be using to run the Dnsmasq.
- listen-address: which IP address you'll be using to run the Dnsmasq. You can use multiple IP addresses.
- interface: which interface the Dnsmasq will be bind and running.
- domain-needed: disable forwarding names without the main domain address. You can access like 'mysql1' host unless you give the full with local domain such as 'mysql1.howtoforge.local'.
- bogus-priv: disable forwarding for non-routed addresses.
- expand-hosts: automatically append the local domain part to simple names.
- no-resolv: ignore the '/etc/resolv.conf' file on the server.
- server: define the upstream DNS Server that you'll be using for non-local addresses or domains. This example uses the Public DNS Server by Cloudflare and Google.
- domain: define the domain name for the Dnsmasq server. In this example, the Dnsmasq server will get the local domain howtoforge.local.
- address: define which IP address for the domain name on Dnsmasq. In this example, the domain howtoforge.local will be resolved to the IP address 192.168.5.50.
- cache-size: enabled DNS cache on Dnsmasq. Be sure to adjust the size, which increases the performance and speed.
- dhcp-range: enable the DHCP server via the Dnsmasq. Adjust the IP address pool for your network and lease time.
- dhcp-leasefile: define the file that will be sued to store the DHCP lease.
- dhcp-authoritative: make the DHCP server as authoritative.
Next, open the '/etc/hosts' file using the below nano editor command. You'll now define some sub-domains for applications in your local environment.
sudo nano /etc/hosts
Add the following lines to the file. In this example, you'll create three sub-domains wiki, mysql, and files. Each sub-domain will follow the main domain of the Dnsmasq server 'howtoforge.local' and point to a specific IP address.
The subdomain wiki.howtoforge.local will be pointed to IP address '192.168.5.10', the sub-domain 'mysql.howtoforge.local' is pointed to IP address '192.168.5.25', and the 'files.howtoforge.local' will be pointed to IP address '192.168.5.30'.
192.168.5.10 wiki
192.168.5.25 mysql
192.168.5.30 files
Save the file and exit the editor when you're finished.
Now open the DNS resolver config file '/etc/resolv.conf' using the below nano editor command.
sudo nano /etc/resolv.conf
Add the following lines to the top of the file. Be sure to change the IP address with the Dnsmasq server IP address.
nameserver 127.0.0.1
nameserver 192.168.5.50
Save the file and exit the editor when finished.
Now run the below command to verify the Dnsmasq configuration and ensure that you have the proper configuration. You'll receive the output such as 'dnsmasq: syntax check OK'.
sudo dnsmasq --test
Lastly, run the below systemctl command utility to restart the 'dnsmasq' service and apply the changes.
sudo systemctl restart dnsmasq
At this point, you've finished the configuration of Dnsmasq as the local DNS Server on the Rocky Linux system. You've also configured the domain name for the Dnsmasq server and some sub-domains via the '/etc/hosts' file. Lastly, you've enabled the cache DNS and DHCP server via the Dnsmasq.
In the next steps, you'll verify the Dnsmsq server installation and configuration.
Verify Dnsmasq Installation
With the Dnsmasq configuration is finished, you'll now verify the Dnsmasq service itself. You'll verify the Dnsmasq to ensure it's running on the default port 50 and the service is running. Then, you'll verify the local domain name and sub-domains you created via the 'dns-utils' package.
Run the below command to verify the open port on your system. Then verify the 'dnsmasq' service via the systemctl command utility.
ss -tulpn | grep 53
sudo systemctl status dnsmasq
You'll receive the output like this - The Dnsmasq is running on the default port 53 and the service status is currently running. Also, it's enabled, which will start automatically upon the bootup.
Next, run the below dnf command to install the 'bind-utils' package to your Rocky Linux server. This package provides multiple command-line tools for testing and troubleshooting DNS Server.
sudo dnf install bind-utils
Input y when prompted and press ENTER to proceed.
Now run the below dig command to verify the domain name for the Dnsmasq server 'howtoforge.local'. You should see that the 'howtoforge.local' is pointed to the server IP address '192.168.5.50'.
dig howtoforge.local
Lastly, run the below command to verify the sub-domains that you've defined via the '/etc/hosts' file.
dig wiki.howtoforge.local +short
dig mysql.howtoforge.local +short
dig files.howtoforge.local +short
You'll receive the output similar to this - The sub-domain wiki.howtoforge.local is pointed to the IP address 192.168.5.10, the sub-domain mysql.howtoforge.local is pointed to the IP address 192.168.5.25, and lastly the sub-domain files.howtoforge.local is pointed to the server IP address 192.168.5.30.
With these results in place, you've finished the configuration of Dnsmasq as the local DNS Server. In the next steps, you'll secure the DNS port via the Firewalld.
Setting up Firewalld
In this step, you'll set up the firewalld to open the DNS service port and add the internal networks IP addresses to the firewalld as the main source that allowed to access the DNS service port.
Run the below firewall-cmd command to add the DNS service to the firewalld. Then, add the internal network IP addresses as the source.
sudo firewall-cmd --add-service=dns
sudo firewall-cmd --add-source=192.168.5.0/24
Next, run the below command to save the temporary rules that you have created and reload the firewalld to apply the changes.
sudo firewall-cmd --runtime-to-permanent
sudo firewall-cmd --reload
Verify the firewalld via the following command. You should see that the DNS service is added to the firewalld and the source IP address of the network is also added to the firewalld.
sudo firewall-cmd --list-all
Output:
Setting up Client (Debian-based or RHEL-based)
In this step, you'll learn how to set up both Debian-based and RHEL-based distributions to use the local DNS Server that you've created via Dnsmasq.
For RHEL-Based Distributions
Add a new config file for NetworkManager '/etc/NetworkManager/conf.d/dns-servers.conf' using the below nano editor command.
sudo nano /etc/NetworkManager/conf.d/dns-servers.conf
Add the following lines to the file, and ensure to change the IP address with the Dnsmasq service IP address. With this configuration, you'll set up the default DNS resolver for the client by using the Dnsmasq server IP address. This will automatically write the DNS resolver configuration '/etc/resolv.conf'.
[global-dns-domain-*]
servers=192.168.5.50
Save the file and exit the editor when finished.
Next, run the below systemctl command to restart the NetworkManager service and apply the changes.
sudo systemctl restart NetworkManager
You can show the '/etc/resolv.conf' file to verify the settings. You should see the default name server is the local Dnsmasq server IP address 192.168.5.50.
cat /etc/resolv.conf
Next, run the below dnf command to install the 'bind-utils' package to your system.
sudo dnf install bind-utils
For Debian-Based Distributions
If you're using the Debian-based operating system, you can set up the DNS resolver manually and disable the 'systemd-resolved' service on your system - especially for the Ubuntu system.
Run the below command to stop and disable the systemd-resolved service.
sudo systemctl disable --now systemd-resolved
Now run the below command to remove the symlink file of the DNS resolver configuration '/etc/resolv.conf'. Then, create a new resolver config file '/etc/resolv.conf' via the nano editor command below.
unlink /etc/resolv.conf
sudo nano /etc/resolv.conf
Add the following line to the file and change the IP address with your Dnsmasq server IP address.
nameserver 192.168.5.50
Save the file and exit the editor when finished.
Next, run the below apt command to install the 'dnsutils' package to your system.
sudo apt install dnsutils
Once the 'bind-utils' or 'dns-utils' is installed, you can verify your Dnsmasq's configuration via the dig command.
Verify the domain name of the Dnsmasq server 'howtoforge.local' via the dig command below. You should see that the domain 'howtoforge.local' is pointed to the Dnsmasq server IP address 192.168.5.50.
dig howtoforge.local
Next, verify the sub-domains that you've configured via the '/etc/hosts' file using the below command. You should see that each sub-domain is pointed to the specific IP address that you've configured on the '/etc/hosts' file.
dig wiki.howtoforge.local +short
dig mysql.howtoforge.local +short
dig files.howtoforge.local +short
You'll receive the output like this - The sub-domain wiki.hwdomain.io is pointed to the IP address 192.168.5.10, the sub-domain mysql.howtoforge.local is pointed to the IP address 192.168.5.25, and lastly, the sub-domain files.howtoforge.local is pointed to the server IP address 192.168.5.30.
With this, the local domain name and sub-domains is configured successfully. Now, how about public domain names such as Github.com, etc?
Run the below command to verify internet domain names from your client machine. This will ensure that you can connect to the internet, even with the local DNS resolved on the Dnsmasq server.
dig github.com
You'll receive the output similar to this - The dig query to github.com is connected via the local DNS Server that runs on the IP address 192.168.5.50 with the default port 53.
Lastly, verify the DNS cache settings via the dig command below. This will show you the executed query's stats, including the 'Query time' to the target domain name.
dig +noall +stats duckduckgo.com
dig +noall +stats duckduckgo.com
You'll then receive the output similar to this - The first query you get is the 'Query time' in 63ms. But for the second and third queries, the Query Time is 2ms, which means your queries to the same domain name is cached via the Dnsmasq local DNS Server.
Conclusion
In this tutorial, you have created your own local DNS Server with Dnsmasq. You've set up your own DNS Server for your local environment with the Dnmasq on a Rocky Linux 9 server. Also, this included the configuration of Dnsmasq with local domain names and sub-domains, enabled the DNS cache to get faster, and also enabled the DHCP Server via the Dnsmasq.
Lastly, you've also added and configured client machines (Debian-based and RHEL-based distributions) to use the local DNS Server that you've created. Within this, you've also learned how to troubleshoot the DNS Server with the dig command and how to set up a DNS resolver on a Linux system.