Troubleshooting BIND9 Forwarders: When Internal DNS Resolves but External Queries Fail


11 views

When your BIND9 server correctly resolves internal domain records (like something.example.com) but fails to forward external queries (e.g., google.ca), this typically indicates a forwarding configuration issue despite having properly defined forwarders like Google DNS (8.8.8.8/8.8.4.4) in named.conf.options.

Before diving into configuration changes, run these diagnostic commands:

# Check if BIND is running
sudo systemctl status named

# Test recursive resolution
dig +trace google.ca @localhost

# Check query logs (add logging channel first if needed)
sudo tail -f /var/log/named/queries.log

The configuration snippet shows potential issues:

options {
    directory "/etc/bind/";
    allow-query-cache { none; };  // This might be too restrictive
    allow-query { any; };
    recursion yes;

    forwarders {
        8.8.8.8;
        8.8.4.4;
    };
};

1. Enable Query Logging

logging {
    channel query_log {
        file "/var/log/named/queries.log";
        severity debug 3;
    };
    category queries { query_log; };
};

2. Adjust Cache and Forwarding Settings

options {
    // ... existing options ...
    allow-query-cache { any; };  // Changed from 'none'
    forward only;  // Explicit forwarding mode
    forwarders {
        8.8.8.8 port 53;
        8.8.4.4 port 53;
    };
    dnssec-validation no;  // Temporary test
};

If basic fixes don't work, test with specific query types:

# Test recursive query
dig +recurse google.ca @127.0.0.1

# Test forwarding directly
dig @8.8.8.8 google.ca

# Check firewall rules
sudo iptables -L -n -v | grep 53

Here's a verified working configuration:

options {
    directory "/etc/bind";
    recursion yes;
    allow-recursion { any; };
    allow-query-cache { any; };
    allow-query { any; };
    forward only;
    forwarders {
        1.1.1.1;  // Cloudflare
        9.9.9.9;  // Quad9
    };
    dnssec-enable yes;
    dnssec-validation auto;
};

include "/etc/bind/named.conf.local";

Consider these nuclear options:

  • Verify /etc/resolv.conf points to 127.0.0.1
  • Check for multiple BIND instances running
  • Test with minimal configuration
  • Inspect SELinux/AppArmor policies

When BIND9 forwarders aren't functioning properly while local zone resolution works, it typically indicates one of these scenarios:

  • Forwarders configuration syntax error
  • Network connectivity issues to upstream DNS
  • Recursion being blocked by firewall rules
  • Incorrect permissions in named.conf

First, verify your configuration with these commands:

# Check syntax without restarting BIND
named-checkconf /etc/bind/named.conf

# Test recursion manually
dig +trace @localhost google.com

Then examine query logs by adding this to your options block:

logging {
    channel query.log {
        file "/var/log/named/query.log";
        severity debug 3;
    };
    category queries { query.log; };
};

Try this more robust configuration that handles multiple failure scenarios:

options {
    directory "/var/cache/bind";
    allow-query { any; };
    recursion yes;
    
    forward first;
    forwarders {
        8.8.8.8;
        8.8.4.4;
        1.1.1.1;  // Cloudflare DNS
    };
    
    // Timeout settings
    max-cache-ttl 3600;
    max-ncache-ttl 3600;
    max-recursion-queries 100;
    max-recursion-depth 50;
};

Ensure your server can reach the forwarders:

# Test connectivity to forwarders
ping -c 4 8.8.8.8
nc -zv 8.8.8.8 53
tcpdump -i eth0 port 53

For detailed analysis, enable extended logging:

# Add to named.conf.options
options {
    // Existing options...
    dnssec-validation auto;
    querylog yes;
    statistics-file "/var/log/named/stats.log";
};

Then monitor in real-time:

tail -f /var/log/named/query.log
rndc stats && cat /var/log/named/stats.log

Consider using root hints as fallback:

options {
    // Existing options...
    forward first;
    forwarders { 8.8.8.8; };
    dual-stack-servers { "2001:4860:4860::8888"; };
    dnssec-enable yes;
    dnssec-lookaside auto;
};

Remember to reload after changes:

systemctl reload bind9
# Or for older systems:
rndc reload