Overview
In this guide, you will:
- Install and configure Unbound as your recursive DNS server.
- Ensure Unbound bypasses any external resolvers and directly queries root servers.
- Set up a secure and optimized Unbound configuration.
- Configure the system to use your new DNS server exclusively.
- Automate daily updates of the latest root hints.
Prerequisites
- Rocky Linux 9 installed on your server.
- Root or sudo privileges.
- Basic familiarity with editing configuration files and using the command line.
- An understanding of DNS concepts, particularly root hints and recursive queries.
1. Install Unbound
Install Unbound using the system’s package manager:
dnf install -y unbound
2. Configure Unbound for Direct Root Queries
Edit the main configuration file:
nano /etc/unbound/unbound.conf
Paste the following configuration:
server:
# Listen on all IPv4 and IPv6 interfaces
interface: 0.0.0.0
interface: ::0
# Allow queries from any IP address
access-control: 0.0.0.0/0 allow
access-control: ::0/0 allow
# Logging and security settings
verbosity: 1
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: yes
# DNS query handling
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
prefetch: yes
serve-expired: yes
unwanted-reply-threshold: 10000
do-not-query-localhost: no
# Performance and caching settings
num-threads: 4
rrset-cache-size: 200m
cache-max-ttl: 86400
cache-min-ttl: 3600
# Specify location of root hints file
root-hints: "/etc/unbound/root.hints"
Note: Do not include any
forward-zone
directives, as this forces Unbound to query the root servers directly.
3. Download the Latest Root Hints
Download the current root hints from IANA:
curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache chown unbound:unbound /etc/unbound/root.hints chmod 644 /etc/unbound/root.hints
4. Disable Hetzner’s Default DNS Resolvers
To prevent your system from using Hetzner’s resolvers, configure your resolver settings:
- Edit
/etc/resolv.conf
:echo "nameserver 127.0.0.1" > /etc/resolv.conf
- Lock the File: Prevent DHCP or NetworkManager from overwriting it:
chattr +i /etc/resolv.conf
- If Using NetworkManager: Disable automatic DNS updates:
nmcli connection modify eth0 ipv4.ignore-auto-dns yes systemctl restart NetworkManager
Tip: Replace
eth0
with the actual network interface name if different.
5. Configure Firewall
Ensure that DNS queries on port 53 are allowed:
firewall-cmd --permanent --add-service=dns<br>firewall-cmd --reload
6. Enable and Start Unbound
Enable Unbound to start on boot and start the service immediately:
systemctl enable --now unbound<br>systemctl restart unbound
7. Test Your DNS Server
Verify that Unbound is working correctly by running:
dig @127.0.0.1 example.com
dig +trace @127.0.0.1 example.com
dig +dnssec @127.0.0.1 example.com
Check the output to ensure responses are coming directly from root servers and that DNSSEC validations pass.
8. Automate Daily Root Hints Refresh
To keep your root hints current, create a script that updates the hints daily and restarts Unbound.
a. Create the Update Script
Create a new script file:
nano /usr/local/bin/update-root-hints.sh
Insert the following content:
#!/bin/bash
ROOT_HINTS="/etc/unbound/root.hints"
TMP_FILE="/tmp/root.hints"
# Download the latest root hints silently
curl -s -o "$TMP_FILE" https://www.internic.net/domain/named.cache
# Check if the download was successful (file is not empty)
if [[ -s "$TMP_FILE" ]]; then
mv "$TMP_FILE" "$ROOT_HINTS"
chown unbound:unbound "$ROOT_HINTS"
chmod 644 "$ROOT_HINTS"
# Restart Unbound to apply the new root hints
systemctl restart unbound
echo "$(date) - Root hints updated successfully" >> /var/log/root-hints-update.log
else
echo "$(date) - Failed to update root hints" >> /var/log/root-hints-update.log
fi
Save and exit.
b. Make the Script Executable
chmod +x /usr/local/bin/update-root-hints.sh
c. Set Up a Daily Cron Job
Edit the crontab for the root user:
crontab -e
Add the following line to run the script every day at 3 AM:
0 3 * * * /usr/local/bin/update-root-hints.sh
Save and exit.
d. Verify the Cron Job
List your cron jobs to confirm:
crontab -l
You can also manually run the script to test:
/usr/local/bin/update-root-hints.sh
Then check the log file:
cat /var/log/root-hints-update.log
Conclusion
You now have a fully independent and optimized recursive DNS server on Rocky Linux 9 that:
- Uses Unbound to directly query root servers.
- Avoids reliance on Hetzner’s resolvers.
- Has robust performance and security configurations.
- Automatically updates its root hints daily.
Feel free to further tweak performance settings (like num-threads
or cache sizes) based on your hardware and usage patterns. Enjoy your perfectly built DNS server!