Loading...
Home
Explore
Contact
Sign in
Linux, Server Administration & Control Panels

Set Up SPF, DKIM & DMARC on Virtualmin, CyberPanel, Ubuntu

Stop failed email delivery and spoofing by publishing correct SPF, DKIM, and DMARC on Virtualmin, CyberPanel, or plain Ubuntu. Practical Australian server steps, diagnostics, and when to book Fixwebnode.

Fixwebnode Support
Fixwebnode Support
10 min read 25 views
Set Up SPF, DKIM & DMARC on Virtualmin, CyberPanel, Ubuntu

If mail from your domain lands in spam, fails authentication, or gets rejected by Gmail and Microsoft 365, your SPF, DKIM, and DMARC records are incomplete or wrong. This guide walks Australian site owners and small-business sysadmins through publishing those three DNS records on Virtualmin, CyberPanel, and a plain Ubuntu Linux mail stack so receiving servers know which hosts may send for your domain, every message is cryptographically signed, and unauthorised senders are rejected or quarantined.

Fixwebnode provides remote Linux and Ubuntu server support for exactly this class of mail-authentication work across Australia—panel configuration, key generation, DNS publication, and live verification—without marketplace bidding.

Why SPF, DKIM, and DMARC matter on your mail server

SPF lists the IP addresses and includes allowed to send mail for your domain. DKIM attaches a cryptographic signature to each message so the body and headers cannot be altered in transit. DMARC tells receivers what to do when SPF or DKIM fails (none, quarantine, or reject) and where to send aggregate reports. Together they cut spoofing, improve inbox placement, and satisfy bulk-sender requirements from major providers. On Virtualmin and CyberPanel the panels can generate keys and suggest records; on bare Ubuntu you wire OpenDKIM and Postfix yourself, then publish TXT records at your DNS host.

Why do SPF, DKIM, or DMARC fail on Virtualmin, CyberPanel, or Ubuntu in Australia?

Most failures come from a missing or overly strict SPF include, a DKIM selector that does not match the signing key on the server, or a DMARC policy published before alignment is clean. Fix the DNS and signing path first; only then tighten policy from p=none to quarantine or reject.

SymptomQuick checkWhen to call Fixwebnode
Gmail "failed SPF" / soft faildig TXT example.com +short and compare sending IPMultiple includes, forwarding, or mixed panels
DKIM body hash mismatchSelector TXT vs OpenDKIM/Virtualmin keyKey rotation or multi-domain signing broken
DMARC aggregate shows failrua mailbox + alignment (aspf/adkim)Policy move to reject or report parsing needed

Common issues with SPF, DKIM, and DMARC setup

  • SPF too long or wrong include chain — messages soft-fail because the sending IP (panel, relay, or ESP) is not covered, or the record exceeds the 10-DNS-lookup limit.
  • DKIM selector published but server signs with another name — receivers see no matching public key; Virtualmin/CyberPanel default selectors often differ from a hand-edited OpenDKIM setup.
  • DMARC p=reject before SPF/DKIM align — legitimate mail is rejected; reports show spf=fail or dkim=fail on your own domains.
  • IPv6 or secondary MX not in SPF — dual-stack Ubuntu hosts send on AAAA while SPF only lists A records.
  • Panel DNS cache vs registrar DNS — records edited in Virtualmin BIND never reach the public nameservers still pointed at the registrar.

Issue 1 — SPF soft-fail or permerror (missing IP or too many lookups)

Symptom: headers show Received-SPF: softfail or permerror; Gmail/Outlook junk the message.

Step 1 — Find the real sending IP

dig +short TXT example.com
curl -4 ifconfig.me
curl -6 ifconfig.me
postfix check
postconf -n | grep -E 'myhostname|inet_protocols|smtp_bind'

Note both IPv4 and IPv6 if the host is dual-stack.

Step 2 — Build a single SPF string under 255 octets and ≤10 lookups

v=spf1 ip4:203.0.113.10 ip6:2001:db8::10 include:_spf.google.com -all

Prefer ip4:/ip6: for your own server over nested includes. Use ~all only while testing; move to -all once clean.

Step 3 — Publish and verify

dig TXT example.com +short
dig TXT example.com @8.8.8.8 +short

Wait for TTL; send a test to a Gmail account and open "Show original".

When to call Fixwebnode: flattened SPF still permerrors, or you juggle several ESPs and need a safe include redesign without breaking billing mail.

Issue 2 — DKIM signature present but verification fails

Symptom: dkim=fail (body hash did not verify) or no key for signature.

Step 1 — Confirm what selector the MTA actually uses

sudo grep -r Selector /etc/opendkim.conf /etc/opendkim/ 2>/dev/null
sudo postconf -n | grep -i milter
sudo tail -n 50 /var/log/mail.log | grep -i dkim

On Virtualmin, open the domain → Email Settings → DNS Records / DKIM and note the selector (often the domain or a short tag like default or x).

Step 2 — Publish the exact public key TXT

dig TXT default._domainkey.example.com +short
# CyberPanel / OpenDKIM example key check
sudo cat /etc/opendkim/keys/example.com/default.txt

The host name must be <selector>._domainkey.<domain>. Value starts with v=DKIM1; k=rsa; p=.... Split long keys into quoted 255-char chunks if your DNS UI requires it.

Step 3 — Restart signing and retest

sudo systemctl restart opendkim
sudo systemctl restart postfix
# Virtualmin: regenerate DKIM for the domain in the UI, then apply config
echo 'Test body' | mail -s 'DKIM test' you@gmail.com

When to call Fixwebnode: multi-domain key tables are inconsistent, milters are out of order, or CyberPanel and manual OpenDKIM both try to sign the same mail.

Issue 3 — DMARC reports show fail after you published p=reject

Symptom: rua reports list your own newsletters or ticket mail as failed; customers bounce.

Step 1 — Start with monitoring only

v=DMARC1; p=none; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1; adkim=r; aspf=r

Publish as _dmarc.example.com TXT.

Step 2 — Confirm alignment

dig TXT _dmarc.example.com +short
# After a few days, inspect XML reports or use a simple rua inbox

SPF must pass on the envelope domain (or aligned org domain). DKIM must pass on a domain aligned with the From: header. Relaxed alignment (adkim=r; aspf=r) is usually enough for small business mail.

Step 3 — Tighten only when fail rate is near zero

v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@example.com; adkim=r; aspf=r

Raise pct and move to p=reject in stages.

When to call Fixwebnode: you need report automation, subdomain policies, or BIMI readiness after reject is stable.

How to set up SPF, DKIM, and DMARC on Virtualmin

Prerequisites: Virtualmin with mail enabled, domain already receiving mail, DNS either hosted in Virtualmin BIND or at an external registrar you can edit.

Step 1 — Enable DKIM globally

sudo virtualmin enable-dkim
# or UI: Email Messages → DomainKeys Identified Mail → enable, choose selector

Step 2 — Per-domain signing and suggested DNS

In Virtualmin: select domain → Server Configuration → DNS Records (or Email Settings). Enable DKIM for the domain. Copy the SPF and DKIM TXT suggestions Virtualmin shows. If BIND is authoritative and nameservers point here, apply and wait for propagation. If nameservers stay at the registrar, paste the same TXT values there.

Step 3 — SPF for local IP plus any relay

# Example after noting server IP
v=spf1 ip4:YOUR.IPv4 ip6:YOUR.IPv6 a mx ~all

Replace ~all with -all after tests pass.

Step 4 — DMARC

Add TXT _dmarc.yourdomain with p=none first as above. Verify:

dig TXT yourdomain.com +short
dig TXT default._domainkey.yourdomain.com +short
dig TXT _dmarc.yourdomain.com +short

How to set up SPF, DKIM, and DMARC on CyberPanel

CyberPanel (OpenLiteSpeed + Postfix stack) exposes email and DNS under each website.

Step 1 — Create or select the mail domain in CyberPanel → Email → Email Domains. Ensure the hostname resolves and Postfix is running:

sudo systemctl status postfix
sudo systemctl status opendkim || sudo systemctl status lspd

Step 2 — Generate DKIM in the panel

Website → DNS / Email → DKIM. Create keys; CyberPanel prints the selector and public TXT. Publish at your DNS provider (CyberPanel PowerDNS if you use it, otherwise registrar).

Step 3 — SPF and DMARC TXT

# SPF
v=spf1 ip4:SERVER_IPv4 ip6:SERVER_IPv6 mx -all
# DMARC (monitor first)
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=r; aspf=r

Step 4 — Verify signing path

sudo tail -f /var/log/mail.log
# Send test; look for DKIM-Signature header and opendkim "pass" lines

How to set up SPF, DKIM, and DMARC on plain Ubuntu (Postfix + OpenDKIM)

Assumes Ubuntu 22.04/24.04, Postfix already sending, root or sudo access.

Step 1 — Install OpenDKIM

sudo apt update
sudo apt install -y opendkim opendkim-tools
sudo mkdir -p /etc/opendkim/keys
sudo chown -R opendkim:opendkim /etc/opendkim

Step 2 — Minimal OpenDKIM config

sudo tee /etc/opendkim.conf <<'EOF'
Syslog yes
SyslogSuccess yes
Canonicalization relaxed/simple
Mode sv
SubDomains no
AutoRestart yes
AutoRestartRate 10/1M
UMask 002
UserID opendkim:opendkim
Socket local:/opendkim/opendkim.sock
PidFile /run/opendkim/opendkim.pid
KeyTable /etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
ExternalIgnoreList refile:/etc/opendkim/trusted.hosts
InternalHosts refile:/etc/opendkim/trusted.hosts
EOF
sudo mkdir -p /opendkim
sudo chown opendkim:opendkim /opendkim

Step 3 — Keys, tables, trust

DOMAIN=example.com
SELECTOR=default
sudo mkdir -p /etc/opendkim/keys/$DOMAIN
sudo opendkim-genkey -b 2048 -d $DOMAIN -D /etc/opendkim/keys/$DOMAIN -s $SELECTOR -v
sudo chown -R opendkim:opendkim /etc/opendkim/keys
sudo chmod 600 /etc/opendkim/keys/$DOMAIN/$SELECTOR.private
echo "$SELECTOR._domainkey.$DOMAIN $DOMAIN:$SELECTOR:/etc/opendkim/keys/$DOMAIN/$SELECTOR.private" | sudo tee /etc/opendkim/key.table
echo "*@$DOMAIN $SELECTOR._domainkey.$DOMAIN" | sudo tee /etc/opendkim/signing.table
printf '127.0.0.1\nlocalhost\n%s\n*.%s\n' "$DOMAIN" "$DOMAIN" | sudo tee /etc/opendkim/trusted.hosts
sudo cat /etc/opendkim/keys/$DOMAIN/$SELECTOR.txt

Publish the printed TXT at default._domainkey.example.com.

Step 4 — Hook Postfix milter

sudo postconf -e 'milter_default_action = accept'
sudo postconf -e 'milter_protocol = 6'
sudo postconf -e 'smtpd_milters = local:/opendkim/opendkim.sock'
sudo postconf -e 'non_smtpd_milters = local:/opendkim/opendkim.sock'
sudo systemctl enable --now opendkim
sudo systemctl restart postfix opendkim

Step 5 — SPF and DMARC at DNS as in the earlier sections, then:

dig TXT example.com +short
dig TXT default._domainkey.example.com +short
dig TXT _dmarc.example.com +short
echo 'ubuntu dkim test' | mail -s 'auth check' your.address@gmail.com

In Gmail "Show original" you want SPF: PASS, DKIM: PASS, DMARC: PASS (once policy and alignment are set).

Remote diagnostics checklist (any panel)

  1. Compare public TXT vs what the panel generated (dig against 8.8.8.8 and against your authoritative NS).
  2. Confirm the outbound IP with curl -4/-6 ifconfig.me matches SPF.
  3. Read /var/log/mail.log (or journalctl -u postfix) for opendkim and SPF-related lines while sending one test.
  4. Check nameserver delegation: if Virtualmin BIND holds records but NS still point at the registrar, public dig will never see panel edits.
  5. After changes, respect TTL; force checks with dig +nocache or a second resolver.

When DIY is enough vs when to book Fixwebnode

DIY is enough when you control one domain, one Ubuntu or panel host, and can publish TXT records and read mail logs. Book a specialist when you have mixed Virtualmin and CyberPanel hosts, outbound relays, Microsoft 365 or Google Workspace side-by-side with local Postfix, repeated permerror on SPF flattening, or you must move DMARC to reject without losing invoices and password resets. Fixwebnode works remotely across Australia for this mail-auth path—see all regions on the service areas page—and can complete key rotation, panel milter wiring, and live header validation with you on a call.

Book remote help for SPF, DKIM, and DMARC

If tests still show fail after the steps above, or you want a clean path from p=none to p=reject on production domains, start a conversation with Fixwebnode. Remote sessions cover Virtualmin, CyberPanel, and Ubuntu Postfix/OpenDKIM end to end. Book via the landing page: Ubuntu Linux server support and bug fixing. Bring your domain name, panel type, and a recent "Show original" header so diagnosis starts immediately.

Share this article
Fixwebnode Support
Fixwebnode Support

Hey there!
I am your assistant for Fixwebnode. Ask about our services, quotes, packages, orders, or how to get support.
While you wait
What’s your name and best email? We’ll reply even if you leave.