How to Configure Wildcard DNS Catch-All in BIND for Mass Domain Management


1 views

When managing hundreds of domains with dynamic additions, creating individual zone files becomes impractical. The current BIND configuration using a root zone (".") with wildcard records works for basic redirection but exhibits unexpected behavior for NS record resolution.

// Current problematic configuration (named.conf extract)
zone "." {
    type master;
    file "ext.zone";
};

The wildcard record *. IN A 192.0.2.6 catches all queries, including the NS server IP lookups. This happens because:

  1. Wildcard records have lower precedence than explicit records
  2. The current zone configuration treats all queries at the root level
  3. Additional section processing follows different resolution rules

Instead of using the root zone, create a wildcard zone that better matches your requirements:

// Revised named.conf configuration
zone "*" {
    type master;
    file "wildcard.zone";
};

zone "ns1.example.com" {
    type master;
    file "ns1.zone";
};

zone "ns2.example.com" {
    type master;
    file "ns2.zone";
};

The wildcard zone file should contain:

// wildcard.zone
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
    2023081501 ; Serial
    3600       ; Refresh
    900        ; Retry
    604800     ; Expire
    86400      ; Minimum
)

@ IN NS ns1.example.com.
@ IN NS ns2.example.com.

* IN A 192.0.2.6

For NS servers, create separate zone files:

// ns1.zone
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
    2023081501
    3600
    900
    604800
    86400
)

@ IN A 192.0.2.4

After reloading BIND, test with:

dig @localhost example.com
dig @localhost ns1.example.com
dig @localhost random.test.example

Expected results:

  • Any domain except NS servers should return 192.0.2.6
  • NS server queries should return their specific IPs
  • Authority section should show correct NS records

For more complex scenarios, consider using RPZ:

// named.conf RPZ configuration
options {
    response-policy {
        zone "wildcard-rpz";
    };
};

zone "wildcard-rpz" {
    type master;
    file "wildcard-rpz.zone";
};

RPZ zone file:

// wildcard-rpz.zone
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
    2023081501
    3600
    900
    604800
    86400
)

; Exclude NS servers from wildcard
ns1.example.com CNAME .
ns2.example.com CNAME .

; Catch-all wildcard
* A 192.0.2.6

When handling large numbers of domains:

  • Enable minimal-responses in options to reduce payload size
  • Consider using views for different client groups
  • Monitor query cache performance with rndc stats




When managing hundreds of domains with constant additions, creating individual zone files becomes impractical. A wildcard DNS configuration in BIND seems ideal, but as discovered, there are nuances in handling NS records and specific A records differently.



The existing setup uses a catch-all zone for the root domain (".") with these key components:


zone "." {
        type master;
        file "ext.zone";
};


The zone file contains:

$TTL    3600
@       IN      SOA     . root.nsdomain.com. (
                              1         ; Serial
                         3600         ; Refresh
                          300         ; Retry
                         3600         ; Expire
                         300 )        ; Negative Cache TTL


        IN      NS      ns1.example.com
        IN      NS      ns2.example.com

ns1     IN      A       192.0.2.4
ns2     IN      A       192.0.2.5

*.      IN      A       192.0.2.6




While this configuration mostly works, we observe incorrect A record resolution for ns1 and ns2 in the additional section. This occurs because the wildcard (*) record is catching ALL requests, including those for our nameservers.



We need to modify the zone file to ensure explicit records take precedence over wildcards. Here's the corrected version:


$TTL    3600
@       IN      SOA     . root.nsdomain.com. (
                              1         ; Serial
                         3600         ; Refresh
                          300         ; Retry
                         3600         ; Expire
                         300 )        ; Negative Cache TTL


        IN      NS      ns1.example.com.
        IN      NS      ns2.example.com.

; Explicit records for nameservers
ns1.example.com.   IN      A       192.0.2.4
ns2.example.com.   IN      A       192.0.2.5

; Wildcard catch-all
*.      IN      A       192.0.2.6
.       IN      A       192.0.2.6  ; For empty/naked domain requests




1. Fully qualified domain names (FQDNs) for NS records with trailing dots
2. Explicit A records for nameservers before the wildcard
3. Additional root domain A record for completeness



After reloading BIND, test with:


dig @localhost ns1.example.com
dig @localhost ns2.example.com
dig @localhost random.test.domain


You should now see:
- Correct A records (192.0.2.4/5) for nameserver queries
- The wildcard IP (192.0.2.6) for all other domains
- Proper NS records in authority section



For more complex scenarios, consider Response Policy Zones (RPZ):

zone "rpz" {
    type master;
    file "db.rpz";
    allow-query { none; };
};

options {
    response-policy { zone "rpz"; };
};


The RPZ file could then implement more sophisticated wildcard behaviors.



With this catch-all approach:
- Monitor query load as all requests hit this zone
- Consider setting lower TTLs during implementation
- Ensure adequate server resources for expected query volume