1Gbps Dedicated Servers
Unmetered Dedicated Servers
AMD Dedicated Servers
Gaming Dedicated Servers
10Gbps Dedicated Servers
GPU Servers
Intel Dedicated Servers
DDOS Protected Dedicated Servers
About Us
Contact Us
Blogs
Tutorials
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.
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.
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.
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).
apt install postfix
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.
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:
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:
-all
include:
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:
~all
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:
+all
dig +short TXT yourdomain.com
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:
sudo apt update sudo apt install -y opendkim opendkim-tools
Create a key directory and generate a 2048-bit key (1024-bit keys are deprecated and shouldn't be used):
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).
-s mail
mail.private
mail.txt
Edit /etc/opendkim.conf:
/etc/opendkim.conf
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:
sv
/etc/opendkim/TrustedHosts
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:
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
Append to /etc/postfix/main.cf:
/etc/postfix/main.cf
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:
sudo systemctl restart opendkim sudo systemctl restart postfix
Print the public key generated in Step 3:
sudo cat /etc/opendkim/keys/yourdomain.com/mail.txt
It outputs something like:
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:
mail._domainkey.yourdomain.com
dig +short TXT mail._domainkey.yourdomain.com sudo opendkim-testkey -d yourdomain.com -s mail -vvv
DMARC is, again, just a DNS TXT record — but at a specific subdomain:
_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.
p=none
rua=
After reviewing reports for a couple of weeks and confirming all your legitimate sending sources pass, tighten the policy in stages:
"v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100"
Then, once you're confident nothing legitimate is being caught:
"v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"
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:
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.
pass
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)
mail2026b
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
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.
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.
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.
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.
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.
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.