How to Set Up Postfix with DKIM, SPF, and DMARC on Ubuntu 24.04

Postfix DKIM SPF DMARC Mail Server Tutorial
Ask AI to extract steps & commands from this tutorial:

If you've ever sent an email from your own server and watched it land in someone's spam folder — or worse, get rejected outright — the cause is almost always the same thing: nothing on the receiving end can verify the mail actually came from you. Mailbox providers like Gmail and Outlook don't take a server's word for it anymore. They check.

This tutorial sets up the three checks that matter — SPF, DKIM, and DMARC — on a Postfix mail server running on Ubuntu 24.04, so outbound mail from your dedicated server authenticates cleanly instead of getting flagged as suspicious.

Why This Matters More on a Dedicated Server

On shared hosting or a mass-market email service, deliverability is somebody else's problem — you're sending from an IP with an existing reputation that thousands of other accounts have already shaped, for better or worse. On a dedicated server, the reputation of your outbound IP is entirely yours.

That's an advantage once it's established — nobody else's bad behaviour can drag your sender score down — but it also means there's no existing trust to borrow on day one. A new IP sending unauthenticated mail looks exactly like what spam looks like, even when it isn't. SPF, DKIM, and DMARC are how you build that trust deliberately instead of hoping for the best.

What Each One Actually Does

It's worth understanding the division of labour before configuring anything, since each protects against a different problem:

  • SPF (Sender Policy Framework) is a DNS record that lists which mail servers are allowed to send mail for your domain. It answers: "is this server permitted to send as me?"

  • DKIM (DomainKeys Identified Mail) cryptographically signs each outgoing message with a private key, with the matching public key published in DNS. It answers: "was this message altered in transit, and did it really come from a server holding my private key?"

  • DMARC (Domain-based Message Authentication, Reporting and Conformance) is the policy layer that tells receiving servers what to do when SPF or DKIM checks fail — and where to send reports about it. It answers: "if authentication fails, what should happen, and who should know?"

All three work together. DMARC in particular depends on SPF and/or DKIM passing — it has nothing to enforce on its own.

Prerequisites

  • A dedicated server running Ubuntu 24.04 LTS, with a domain you control DNS for.

  • Postfix already installed and able to send mail (apt install postfix if not).

  • A clean reverse DNS (PTR) record pointing your server's IP back to your mail hostname (e.g. mail.yourdomain.com). Ask your hosting provider to set this if you can't do it yourself. DKIM and SPF won't compensate for a missing or mismatched PTR record.

Step 1: Set Up SPF

SPF is the simplest of the three: it's just a DNS TXT record, no software required.

Add a TXT record at your domain's root:

text

yourdomain.com.   IN TXT   "v=spf1 mx -all"
                            

This authorizes your domain's MX servers to send mail and tells receivers to reject (-all) anything from elsewhere claiming to be you. If you also send through additional services (Google Workspace, a CRM), add their include: mechanism:

text

yourdomain.com.   IN TXT   "v=spf1 mx ip4:203.0.113.10 include:_spf.google.com -all"
                            

While testing, it's safer to use ~all (softfail) instead of -all (hardfail). Softfail tells receivers to flag a failure but generally still deliver the message:

text

yourdomain.com.   IN TXT   "v=spf1 mx ~all"
                            

Switch to -all once you've confirmed legitimate mail is passing. Never use +all — that authorizes literally anyone to send mail claiming to be your domain. Verify it after DNS propagates:

bash

dig +short TXT yourdomain.com
                            

Step 2: Choose and Install a DKIM Signer

Postfix has no DKIM signing built in — it needs a separate service (a "milter") that intercepts outgoing mail and signs it before it leaves.

This tutorial uses OpenDKIM, since it remains the more commonly deployed option for a single-domain signing setup. Install it:

bash

sudo apt update
sudo apt install -y opendkim opendkim-tools
                            

Step 3: Generate a DKIM Key Pair

Create a key directory and generate a 2048-bit key (1024-bit keys are deprecated and shouldn't be used):

bash

sudo mkdir -p /etc/opendkim/keys/yourdomain.com
sudo opendkim-genkey -b 2048 -d yourdomain.com -D /etc/opendkim/keys/yourdomain.com -s mail -v
sudo chown -R opendkim:opendkim /etc/opendkim/keys
                            

The -s mail flag sets the selector — effectively a label for this key, used in the DNS record name. This generates two files: mail.private (the private key) and mail.txt (the public key for DNS).

Step 4: Configure OpenDKIM

Edit /etc/opendkim.conf:

ini

Syslog              yes
SyslogSuccess       yes
LogWhy               yes

Mode                 sv
Canonicalization     relaxed/simple

Domain               yourdomain.com
Selector             mail
KeyFile              /etc/opendkim/keys/yourdomain.com/mail.private

Socket               local:/var/spool/postfix/opendkim/opendkim.sock
PidFile              /var/run/opendkim/opendkim.pid

ExternalIgnoreList    refile:/etc/opendkim/TrustedHosts
InternalHosts         refile:/etc/opendkim/TrustedHosts
                            

Mode sv enables both signing outgoing mail and verifying incoming mail. Create /etc/opendkim/TrustedHosts:

text

127.0.0.1
::1
localhost
yourdomain.com
                            

Create the socket directory Postfix needs to reach OpenDKIM, since Postfix's mail process runs in a chroot:

bash

sudo mkdir -p /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim
sudo chmod 750 /var/spool/postfix/opendkim
sudo usermod -a -G opendkim postfix
                            

Step 5: Connect OpenDKIM to Postfix

Append to /etc/postfix/main.cf:

ini

milter_protocol = 6
milter_default_action = accept
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
                            

Restart both services, OpenDKIM first since Postfix needs it available immediately on startup:

bash

sudo systemctl restart opendkim
sudo systemctl restart postfix
                            

Step 6: Publish the DKIM DNS Record

Print the public key generated in Step 3:

bash

sudo cat /etc/opendkim/keys/yourdomain.com/mail.txt
                            

It outputs something like:

text

mail._domainkey IN TXT ( "v=DKIM1; k=rsa; "
    "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2hL...etc" )
                            

Add this as a TXT record at mail._domainkey.yourdomain.com in your DNS. Set the TTL low (around 300 seconds) for now, so any mistake is cheap to fix while you're testing. Verify once it's propagated:

bash

dig +short TXT mail._domainkey.yourdomain.com
sudo opendkim-testkey -d yourdomain.com -s mail -vvv
                            

Step 7: Publish a DMARC Record

DMARC is, again, just a DNS TXT record — but at a specific subdomain:

text

_dmarc.yourdomain.com.   IN TXT   "v=DMARC1; p=none; rua=mailto:[email protected]; pct=100"
                            

Start with p=none. This is monitor-only mode: receivers don't take any enforcement action, but they do send aggregate reports to the address in rua=, which tells you what's actually happening with your mail before you risk blocking anything legitimate.

After reviewing reports for a couple of weeks and confirming all your legitimate sending sources pass, tighten the policy in stages:

text

"v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100"
                            

Then, once you're confident nothing legitimate is being caught:

text

"v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"
                            

Step 8: Verify Everything Together

Send a test message to a Gmail or Outlook address you control, then check the message's authentication headers (in Gmail: open the message, click the three-dot menu, "Show original"). You're looking for a line resembling:

text

Authentication-Results: mx.google.com;
    dkim=pass header.d=yourdomain.com;
    spf=pass (google.com: domain of [email protected] designates 203.0.113.10 as permitted sender);
    dmarc=pass (p=NONE)
                            

All three showing pass confirms the full chain is working.

A Note on Key Rotation

DKIM keys aren't meant to be set once and forgotten. Plan to rotate the key roughly once a year, or immediately if you suspect the private key has been exposed. The safe sequence is:

  • Generate a new key with a new selector (e.g. mail2026b instead of mail)

  • Publish the new selector's DNS TXT record alongside the old one — don't remove the old one yet

  • Update OpenDKIM's configuration to sign with the new selector

  • Leave the old DNS TXT record live for at least 48–72 hours after switching, since mail already in transit may still get checked against the old key

  • Remove the old selector's DNS record only after that window passes

Frequently Asked Questions

Why is my email going to spam even though I haven't changed anything? +

Deliverability isn't usually broken by a single misconfiguration — it's the absence of SPF, DKIM, or DMARC entirely that mailbox providers now treat as a negative signal by default, even for mail that isn't spam. If none of the three are set up, this guide's steps are usually the fix; if they're already in place, check your reverse DNS (PTR) record next.

Do I need all three — SPF, DKIM, and DMARC — or is one enough? +

DMARC requires at least one of SPF or DKIM to be configured to have anything to enforce, so it can't stand alone. SPF alone is fragile because it breaks when mail is forwarded through an intermediate server. Running all three together is what current best practice — and what large mailbox providers effectively require — actually means.

What's the difference between OpenDKIM and Rspamd, and does it matter which I pick? +

Both sign outgoing mail with DKIM correctly. OpenDKIM is simpler to set up for a single domain doing DKIM and nothing else. Rspamd is more actively maintained and bundles spam filtering with DKIM signing in one service, which is generally the better choice if you're also setting up inbound spam protection. The DNS records you publish are the same either way.

How long does it take for SPF, DKIM, and DMARC changes to take effect? +

DNS propagation is typically a matter of minutes to a few hours, though it can take up to 24–48 hours in less common cases depending on your DNS provider and the TTL set on the record. Setting a short TTL (around 300 seconds) while actively testing makes mistakes faster to correct.

Can I skip the monitoring stage and go straight to a strict DMARC policy? +

It's possible, but risky. p=reject with no prior monitoring period means any sending path you forgot about — a transactional email service, a contact form, a mailing list — starts having its mail silently rejected with no warning. Starting at p=none and reviewing the aggregate reports first is what catches those gaps.

Our Bandwith providers

We are Partners with 15 +

At eServers , we proudly partner with 15+ leading global tech providers to deliver secure, high-performance hosting solutions. These trusted alliances with top hardware, software, and network innovators ensure our clients benefit from modern technology and enterprise-grade reliability.

Hosting Solutions