How do I set up authentication (SPF, DKIM) at the MTA level?
Still have a question, spotted an error, or have a better explanation or a source we should cite?
If you're running your own MTA, authentication isn't optional. Without it, mailbox providers have no way to verify your mail is legitimate, and your deliverability will suffer for it. The good news is that SPF and DKIM are both well-understood, and the setup is more approachable than it looks.
Here's the key thing to understand first: SPF lives entirely in DNS. DKIM touches both DNS and the MTA. They're solving different problems, and you configure them in different places.
Setting up SPF
SPF tells receiving servers which IP addresses are allowed to send mail on behalf of your domain. You don't touch the MTA at all for this. You just add a TXT record to your domain's DNS.
A basic SPF record looks like this:
v=spf1 ip4:192.0.2.1 -all
That says only the IP 192.0.2.1 is authorized to send for your domain. The -all at the end is a hard fail, meaning anything else gets rejected. If you're sending through multiple sources, you can chain them with include: statements, but keep the total lookup count under 10 or you'll hit an SPF permerror.
Your MTA's job here is simply to send from an IP that's listed in that record. That's it.
Setting up DKIM with Postfix and OpenDKIM
DKIM works by having your MTA cryptographically sign outgoing messages with a private key. The matching public key lives in your DNS, and receiving servers use it to verify the signature wasn't tampered with in transit.
So the most common setup is Postfix paired with OpenDKIM as a milter (a mail filter that intercepts messages before they leave).
- Generate your key pair. Run
opendkim-genkey -s mail -d yourdomain.com. This creates a private key and a DNS record file. The-s mailis your selector, basically a label that lets you rotate keys later without breaking things. - Publish the public key in DNS. Add a TXT record at
mail._domainkey.yourdomain.comwith the contents from the generated file. It'll look something likev=DKIM1; k=rsa; p=MIGf... - Configure OpenDKIM. Point it to your private key file, set the selector and signing domain in the config. Make sure the socket matches what Postfix expects.
- Connect Postfix to OpenDKIM via milter. Add this to your Postfix
main.cf:smtpd_milters = inet:localhost:8891andnon_smtpd_milters = inet:localhost:8891. The second line covers messages injected locally, not just inbound SMTP connections. - Restart both services and send a test message to check the signature.
Using an MTA with native DKIM signing
If you're on PowerMTA (now Bird) or KumoMTA, you can skip the milter layer entirely. Both handle DKIM natively. You configure the signing key and selector directly in the MTA config, and it takes care of signing without needing an external process. It's cleaner, with fewer moving parts to break.
Testing your setup
And once you've made your DNS changes, give them 30 to 60 minutes to propagate. Then send a test message to Mailtrap or use our free Email Header Analyzer to confirm the DKIM signature is present and passing. You're looking for dkim=pass in the authentication results header.
Don't skip the test. A misconfigured DKIM selector or a broken milter connection can silently fail, meaning messages go out unsigned and you won't know until your deliverability tanks.
Once SPF and DKIM are solid, the next natural step is adding DMARC to tie them together and tell receivers what to do when authentication fails. And if you're configuring your MTA more broadly, you might also want to look at TLS encryption for outbound sending as your next step.
Contributors
Who worked on this answer
Every name links to their profile. Every company links to their site. Real people, real accountability.