DMARC, SPF and DNS wildcards
My domain configuration has one domain and three subdomains, one of which is identical to the mail server's hostname:
- example.com
- sales.example.com
- internal.example.com
- mail.example.com
I initially configured MX, SPF, DKIM and DMARC DNS records for all four domains, which works well.
But according to some DMARC tutorials, setting a DMARC policy for the base domain (with an sp tag) should cover all subdomains. When I rely on a single DMARC policy (for example.com), though, my mail provider's DMARC results refer to an undefined DMARC policy for subdomain mails. Why is the base domain's DMARC policy not used in this case?
I also tried to simplify the MX and SPF entries using wildcards:
*.example.com 3600 IN MX 10 mail.example.com
*.example.com 3600 IN TXT "v=spf1 mx -all"
but this leads to SPF fails. Why is that? Shouldn't the entries quoted above handle my existing subdomains?
Top Answer/Comment:
Two different mechanisms are biting you, one for DMARC and one for the wildcards, so let me take them separately.
Why the base domain's sp= isn't covering your subdomains
DMARC policy discovery is a two-step lookup, not inheritance (RFC 7489 section 6.6.3). For a message whose From domain is sales.example.com, a receiver:
- Looks up
_dmarc.sales.example.com. If a record exists there, that record is used, and its sp tag (if any) is ignored, because sp only has meaning on the organizational domain.
- Only if there is no record at the subdomain does the receiver fall back to the organizational domain,
_dmarc.example.com, and apply its sp= to the subdomain.
You said you initially published DMARC records for all four names. That is the catch: as long as _dmarc.sales.example.com and the others still exist, they win, and example.com's sp= is never consulted for those subdomains. For the single-policy setup to actually take over, you have to delete the per-subdomain _dmarc TXT records so the fallback to the org-domain policy can happen.
The "undefined policy for subdomain" you see in the results almost always means one of two things: a leftover or half-removed _dmarc.<subdomain> record is still answering, or the mail's actual From domain isn't the one you expect. Check the header_from field in an aggregate (rua) report to see the exact domain being evaluated, then confirm that dig txt _dmarc.<that-domain> returns nothing while dig txt _dmarc.example.com returns your policy with sp=.
One detail worth knowing: the fallback jumps straight from the subdomain to the organizational domain. For a.b.example.com it checks _dmarc.a.b.example.com and then _dmarc.example.com, never _dmarc.b.example.com. With single-level subdomains that doesn't bite you, but it surprises people with deeper names.
Why the wildcard SPF fails
This is the DNS wildcard-matching rule, and it is exactly why RFC 7208 section 3.5 tells you not to do this.
A DNS wildcard only synthesizes an answer for a name that does not otherwise exist in the zone (RFC 1034 section 4.3.3). sales.example.com, internal.example.com, and mail.example.com already exist, because they carry MX and A records. So a TXT query for sales.example.com is answered by the sales.example.com node itself, which has no TXT record, and returns nothing. The *.example.com wildcard is never even consulted for it. Your wildcard SPF only applies to subdomains that do not exist at all, which is the opposite of what you wanted, and it is why SPF comes back with no record and fails.
RFC 7208 section 3.5 discourages wildcard SPF for a second reason too: if the wildcard did apply, every arbitrary non-existent subdomain would inherit a sending policy, which is rarely what you mean and tends to help a spoofer rather than stop one.
So the clean setup is the one you started with: explicit records per subdomain. If maintaining four near-identical SPF records annoys you, publish one canonical record and point the others at it with the redirect modifier instead of a wildcard, for example v=spf1 redirect=_spf.example.com on each subdomain with the real record living at _spf.example.com.
상단 광고의 [X] 버튼을 누르면 내용이 보입니다