BIND’s wildcard DNS records let you respond to any DNS query for a domain that doesn’t have a specific record defined.
Let’s say you have example.com and you want any subdomain that doesn’t exist to point to your main web server. You’d typically have records like:
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2023102701 ; serial
3600 ; refresh
1800 ; retry
604800 ; expire
86400 ) ; minimum TTL
;
@ IN NS ns1.example.com.
@ IN A 192.0.2.1
www IN A 192.0.2.1
mail IN A 192.0.2.2
If someone queries for nonexistent.example.com, BIND will typically return NXDOMAIN (Non-Existent Domain). But if you add a wildcard, it can answer that query.
Here’s how you add a wildcard record. In your BIND zone file for example.com, you add a line starting with an asterisk:
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2023102701 ; serial
3600 ; refresh
1800 ; retry
604800 ; expire
86400 ) ; minimum TTL
;
@ IN NS ns1.example.com.
@ IN A 192.0.2.1
www IN A 192.0.2.1
mail IN A 192.0.2.2
* IN A 192.0.2.1
Now, if someone queries for anything.example.com, BIND will find the * record and use its data, 192.0.2.1, as the answer. This is incredibly useful for catching typos, or for dynamically generating subdomains that all point to the same place.
The key mechanism at play is how BIND resolves queries. When a query comes in for a specific name, BIND first looks for an exact match in the zone file. If it finds one, it returns that record. If it doesn’t find an exact match, it then looks for a wildcard record (*). If a wildcard record exists, BIND uses that as the answer. This wildcard record applies to all labels within that domain, except for the root domain itself (example.com).
Consider the query for mail.example.com. BIND checks for mail.example.com, finds it, and returns 192.0.2.2.
Now, consider a query for blog.example.com. BIND checks for blog.example.com, doesn’t find it. Then it checks for the wildcard *.example.com, finds it, and returns 192.0.2.1.
You can also have wildcard records for other record types. For example, to direct all MX queries for non-existent subdomains to a specific mail server:
* IN MX 10 mail.example.com.
This means that if nonexistent.example.com were queried for MX records, BIND would return 10 mail.example.com.. However, it’s important to note that wildcards do not match the root domain itself. A query for example.com will not be answered by *.example.com.
Wildcard records are evaluated after specific records. So, if you have both www.example.com and *.example.com, a query for www.example.com will resolve to its specific record, not the wildcard. The wildcard is only used when no specific record exists for the requested name.
The order of evaluation is crucial:
- Exact match (e.g.,
www.example.com) - Wildcard match (e.g.,
*.example.com) NXDOMAIN(if no exact or wildcard match is found)
This behavior allows you to set up a default response for a vast number of potential subdomains without having to create individual records for each one.
The one thing that often trips people up is the interaction between wildcards and empty labels. If you have a wildcard *.example.com, it will match foo.example.com and bar.foo.example.com. However, it will not match example.com itself, nor will it match foo.bar.example.com if bar.example.com doesn’t exist. The wildcard only applies to the first label to the left of the domain name.
After setting up a wildcard record, remember to reload your BIND configuration. On most systems, this is done with:
sudo systemctl reload named
or
sudo rndc reload
You can test your wildcard record using dig:
dig nonexistent-subdomain.example.com A +short
If everything is configured correctly, this command should output 192.0.2.1.
The next thing you’ll likely encounter is how to handle wildcard CNAME records, which have some important caveats.