How to Configure BIND as a DNS Forwarder on Linux
Install BIND9, configure it to forward queries to upstream resolvers, and verify the setup with dig commands.
This tutorial walks you through installing BIND9 and configuring it to act as a dedicated DNS forwarder. The steps target Ubuntu 24.04 and Debian 12 using BIND9 version 9.18.24 or later. You will configure the software to forward all unresolved queries to upstream resolvers like Google or Cloudflare.
Prerequisites
- A Linux server running Ubuntu 24.04, Debian 12, or a compatible distribution.
- Root or sudo access to install packages and modify configuration files.
- Network connectivity to upstream DNS resolvers (e.g., 8.8.8.8, 1.1.1.1).
- At least 256 MB of RAM available for the BIND service.
Step 1: Install BIND9
Update your package index and install the BIND9 package along with its utilities. This installs the bind9, bind9-dnsutils, and bind9-host packages necessary for configuration and testing.
apt update
apt install bind9 bind9-dnsutils bind9-host -y
After installation, verify the version to ensure compatibility with your upstream resolvers.
named -v
You should see output similar to this:
BIND 9.18.24-1~deb12u1
Step 2: Create the BIND Configuration Directory
Bind stores configuration files in /etc/bind. Create the directory structure for the main configuration file and zone files if they do not exist.
mkdir -p /etc/bind
Edit the main configuration file using a text editor like nano or vi.
nano /etc/bind/named.conf
Step 3: Configure the Forwarding Options
Open the main configuration file and replace its contents with a configuration that defines a forward-only zone. This setup tells BIND to forward queries it cannot resolve locally to your chosen upstream resolvers.
options {
directory "/var/cache/bind";
recursion yes;
forward only;
forwarders {
8.8.8.8;
8.8.4.4;
};
allow-query { any; };
};
Save the file and exit the editor. The forward only directive ensures that BIND does not attempt to resolve queries itself but instead passes them to the forwarders list.
Step 4: Configure the Zones File
Create a minimal zone file for your local domain to prevent BIND from trying to resolve internal hostnames. This keeps the forwarder focused on external queries.
nano /etc/bind/db.local
Add the following content to define a local zone:
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2024010101 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
@ IN NS ns1.example.com.
ns1 IN A 127.0.0.1
@ IN A 127.0.0.1
Save the file. This file is referenced in named.conf under the zone "local" IN { type master; file "db.local"; } block. If you do not define a zone block for local, BIND will attempt to resolve local names, which defeats the purpose of a pure forwarder. Add the zone block to named.conf if it is missing:
zone "local" IN {
type master;
file "/etc/bind/db.local";
};
Step 5: Restart the BIND Service
Apply the changes by restarting the BIND service. Use the systemctl command to reload the configuration and start the daemon.
systemctl restart bind9
Check the status to ensure the service is running without errors.
systemctl status bind9
Verify the installation
Test the forwarder by using the dig command to query a domain name. The query should be resolved by the upstream resolvers listed in your configuration.
dig @127.0.0.1 google.com +short
You should see an IP address returned, such as:
142.250.185.46
This confirms that BIND is successfully forwarding queries to Google's DNS servers.
Troubleshooting
Error: "zone local/IN: no zone file found"
This occurs if the db.local file is missing or the path is incorrect. Ensure the file exists at /etc/bind/db.local and that the named.conf points to the correct path.
ls -l /etc/bind/db.local
Error: "resolver: no servers were found"
This indicates that the forwarders directive is missing or contains invalid IPs. Check named.conf to ensure the forwarders block is present and contains valid public DNS addresses.
grep -A 5 "forwarders" /etc/bind/named.conf
Error: "zone local/IN: no zone file found"
If the zone file exists but BIND still complains, check file permissions. The bind user must read the file.
chown bind:bind /etc/bind/db.local
chmod 644 /etc/bind/db.local
Firewall blocking port 53
Ensure that port 53 (UDP and TCP) is open on your server. If you use ufw, run the following command to allow DNS traffic.
ufw allow 53/tcp
ufw allow 53/udp
Reload the firewall rules to apply the changes.
ufw reload
If the firewall blocks external queries, the forwarder will fail to resolve external domains. Verify connectivity by pinging an upstream resolver.
ping -c 4 8.8.8.8
If the ping fails, your server cannot reach the internet, and the forwarder will not function correctly.