Wildcards and DKIM and DMARC, oh my!

W

If you’re an ESP with small customers you may have looked at the recent Google / Yahoo requirements around DMARC-style alignment for authentication and panicked a bit.

Don’t impersonate Gmail From: headers. Gmail will begin using a DMARC quarantine enforcement policy, and impersonating Gmail From: headers might impact your email delivery.



For direct mail, the domain in the sender’s From: header must be aligned with either the SPF domain or the DKIM domain. This is required to pass DMARC alignment.

So everyone who’s using their gmail address to send bulk mail is going to have to stop doing that within the next few months if they still want their mail to be delivered.

For any ESP customer that already has, or can be convinced to buy, a domain for their web presence maybe they can be persuaded to switch to using that – though even if they can, onboarding 100,000 technically naive users in three months seems like it could be a nightmare, even if you already have excellent onboarding automation in place and plenty of spare customer support bandwidth.

But what about all the other users, who don’t have a domain already or who can’t manage to bring that domain to their ESP for authentication – they may not even have access to their DNS zone, it may all be managed by their web host?

As an ESP we could just send all those customers emails from our own domain, or a dedicated domain just for those customers (halp-i-haz-no-domain.com is available for registration; you’re welcome). But that’s obviously a terrible idea from a domain reputation issue, quite apart from our customers losing any vestige of branding.

How about subdomain-per-customer? All our users probably have a login username already, it’s probably unique and branded. So our ESP, SausageMail, can set up subdomains of wurst.com for each customer. If we default that to <username>.wurst.com we can deploy that without any cooperation from each customer, and we can offer to change the string we use there if they want to.

Tasty sausages, and for no narratively justified reason, a leek.
Tasty sausages from our butcher

What do we need for each customer subdomain? We want to use it in the RFC 5322 From: header, and we want either DKIM or SPF to align with it. That means that we’d like an MX record for it, whether it points at a mailserver that forwards it to the customer, or an autoresponder or a blackhole. It’d be nice to have DMARC p=none set up for it too.

For DMARC-style alignment there’s no need for the authentication domain to match the domain in the 5322 From: exactly – it just needs to share a common organizational domain. That’ll typically mean that the authentication domain will be the parent domain (wurst.com) or a sibling subdomain to that in the 5322 From: (e.g. authentication.wurst.com). That means that we can avoid using a per-customer domain in the return path for SPF authentication, and avoid having to publish a customer-specific DKIM public key.

That’s great, because while wildcard MX records are simple and widely supported (they’re the main thing wildcard DNS records have been used for historically) wildcard TXT records risk tickling obscure bugs (e.g. wildcard TXT records mean that if an ISP asks for a DKIM public key they’ll get that key, and also DMARC records and vice-versa).

For the DMARC policy record itself we can take advantage of the way a DMARC record set for the organizational domain (wurst.com) will apply to all subdomains by default.

So you could do this:

*.wurst.com                 MX 10 reply-handler.sausagemail.com
bounces.wurst.com           MX 10 bounce-handler.sausagemail.com
bounces.wurst.com           TXT "v=spf1 include:_spf.sausagemail.com"
a._domainkey.pool.wurst.com TXT "v=DKIM1 p=..."
b._domainkey.pool.wurst.com TXT "v=DKIM1 p=..."
_dmarc.wurst.com            TXT "v=DMARC1 p=none ..."

(This isn’t a validly formatted zone file – it’s missing trailing periods, TTLs and classes – so don’t just paste it into your nameserver.)

Because of how DNS wildcards work MX queries for bounces.wurst.com will point at your bounce handler, while MX queries for anything_else.wurst.com will point at your reply handler.

Then for every mail you send for this sort of customer you use a From: header that looks like this …

From: "Customer's Pretty Name" <userid@userid.wurst.com>

… and you DKIM sign it using d=pool.wurst.com and you use bounces.wurst.com as the return path. Every mail will be sent from a valid, customer-specific, email address. It will have valid SPF authentication, and be validly DKIM signed. Both DKIM and SPF authentication domains will align with the 5322 From: header. And it’ll have a valid DMARC p=none.

If your existing customer authentication infrastructure is based on CNAMEs rather than TXT records (and it probably is) then you can set up DNS more like this:

*.wurst.com                 MX 10 reply-handler.sausagemail.com
bounces.wurst.com           MX 10 bounce-handler.sausagemail.com
bounces.wurst.com           TXT "v=spf1 include:_spf.sausagemail.com"
ssg1._domainkey.pool.wurst.com CNAME k1._domainkey.sausagemail.com
ssg2._domainkey.pool.wurst.com CNAME k2._domainkey.sausagemail.com
_dmarc.wurst.com               TXT "v=DMARC1 p=none ..."

Is this perfect? No. You’re sharing the same authentication domain across all of these customers which means that they will, to some degree, share domain reputation as well as their IP reputation. Not entirely, as large providers are very good at distinguishing mailstreams from different customer even if they share authentication domains. In a perfect world you’d use giant generated zone files, or a “stunt” DNS server to use customer_id.wurst.com as the authentication domain. But this isn’t a perfect world, and using a shared authentication domain for these customers is probably good enough, and will allow them to comply with mailbox provider requirements – and to do so in a way that seems to follow the spirit of the requirements, not just the letter.

I wrote about the better approach, using a stunt DNS server to synthesize all the DNS records needed, here.

This isn’t that scary to do, and can probably be implemented with only slight changes to your existing infrastructure. You’ve got about three months to go.

About the author

1 comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • I’ve been using wildcard records for a while and can report that they work surprisingly well, even when DKIM and DMARC records overlap. As far as I can tell, the libraries people use do a good job of skipping irrelevant records.

By steve

Recent Posts

Archives

Follow Us