Standard DNS wildcard implementations (RFC 4592) only handle single-level subdomains. A typical setup like:
*.example.com. IN A 192.0.2.1
will resolve foo.example.com
but fail for bar.foo.example.com
. This becomes problematic when building SaaS platforms or multi-tenant systems requiring dynamic subdomains.
Here are three approaches to achieve this:
1. BIND9 View Configuration
For authoritative DNS servers using BIND9:
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
allow-update { none; };
// First-level wildcard
match-clients { any; };
match-destinations { any; };
view "firstlevel" {
match-clients { any; };
recursion no;
zone "." { type hint; file "/etc/bind/db.root"; };
include "/etc/bind/named.conf.default-zones";
};
// Multi-level wildcard view
view "multilevel" {
match-clients { any; };
recursion no;
zone "example.com" {
type master;
file "/etc/bind/db.example.com.wildcard";
};
};
};
2. PowerDNS Generic Mapping
For PowerDNS with Generic MySQL backend:
-- SQL schema for wildcard records
INSERT INTO records (domain_id, name, type, content, ttl)
VALUES (
(SELECT id FROM domains WHERE name='example.com'),
'%.example.com',
'A',
'192.0.2.1',
300
);
3. Cloud Provider Specific Solutions
For AWS Route 53:
{
"Comment": "Multi-level wildcard",
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "*.example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{ "Value": "192.0.2.1" }]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "*.*.example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{ "Value": "192.0.2.1" }]
}
}]
}
Verify with dig commands:
dig +short test.example.com
dig +short abc.def.example.com
dig +short x.y.z.example.com
- Some DNS providers limit wildcard levels
- SSL certificate challenges may require explicit SAN entries
- Caching resolvers might behave unexpectedly
While single-level wildcard DNS entries (*.example.com
) are common in BIND and other DNS servers, multi-level wildcards require special handling. The standard approach only captures first-level subdomains like foo.example.com
but fails for bar.foo.example.com
.
Here are three implementation approaches for multi-level wildcards:
1. BIND Configuration with Regex
zone "example.com" { type master; file "/etc/bind/db.example.com"; allow-transfer { none; }; }; // In db.example.com: $ORIGIN example.com. @ IN SOA ns1.example.com. hostmaster.example.com. ( 2023081501 ; Serial 3h ; Refresh 1h ; Retry 1w ; Expire 1h ) ; Minimum TTL *.* IN A 192.0.2.1 ; This captures two-level wildcards like a.b.example.com
2. PowerDNS with LUA Records
PowerDNS offers more flexible wildcard handling through LUA scripting:
-- pdns.lua.conf function wildcardresolve(qname, qtype) if string.find(qname, ".*%.example%.com$") then return { { qname=qname, qtype="A", content="192.0.2.1", ttl=300 } } end end
3. Cloud Provider Specific Solutions
Major cloud DNS services handle this differently:
- AWS Route53: Supports multi-level wildcards natively with
*.*.example.com
- Cloudflare: Uses Page Rules with
*.example.com/*
patterns - Google Cloud DNS: Requires individual record creation via API
For a SaaS application needing dynamic tenant subdomains at any depth:
// BIND 9.16+ configuration: $TTL 300 @ IN SOA ns1.example.com. admin.example.com. ( 2023081501 ; serial 3600 ; refresh 900 ; retry 604800 ; expire 300 ) ; minimum ; Base wildcard * IN A 192.0.2.1 ; Multi-level capture (requires BIND 9.10+) *.sites IN A 192.0.2.1 *.*.users IN A 192.0.2.2
Verify your setup with these diagnostic commands:
dig any.thing.example.com nslookup test.demo.example.com host -t A multi.level.test.example.com
Deep wildcard DNS resolution impacts:
- DNS query response times increase ~15-20ms per additional level
- DNSSEC validation becomes more complex
- Caching behavior varies across resolvers
Important security measures for multi-level wildcards:
; Prevent DNS hijacking *.example.com. IN CAA 0 issue "letsencrypt.org" *.example.com. IN TXT "v=spf1 -all" ; Rate limiting for dynamic subdomains options { rate-limit { responses-per-second 10; }; }