263 Enterprise Mail: MX, SPF, DKIM & DMARC Setup
Configure 263 Enterprise Mail on a custom domain: mxw.263.net at priority 5, mx.263.net at 10, the spf.263.net include, DKIM generated in the admin console, and DMARC reporting.
Aliyun Mail & DirectMail: DKIM, SPF & DMARC Setup
Step-by-step Aliyun DirectMail sender domain verification: the six DNS records, the SPF include values, region-based DKIM selectors and DMARC publishing.
Alibaba Mail (Alimail) SPF, DKIM & DMARC Setup Guide
Configure Alibaba Mail / Aliyun Enterprise Mail on your own domain: mx1-mx3.qiye.aliyun.com, the spf.qiye.aliyun.com include, default._domainkey DKIM and a DMARC record.
Zimbra SPF, DKIM & DMARC: Self-Hosted Setup
Zimbra is the most common open-source collaboration stack still running its own mail transfer agent, which means authentication here is not a control panel exercise — it is a shell exercise. The good news is that Zimbra ships every tool you need; the bad news is that the selector it generates is a UUID that nobody can remember, and the verification step that actually proves correctness is skipped by almost every guide.
This assumes you have shell access as the zimbra user and that your public DNS is already serving MX and A records for the mail host.
Step 1: SPF
For a single-server deployment where the MX also sends:
v=spf1 mx -all
That authorises every host listed in your MX records. It is compact and it survives an IP change as long as you keep the MX current. The moment a second sender exists — a website on another IP, an application relay, a monitoring service — be explicit instead:
v=spf1 mx ip4:203.0.113.10 ip6:2001:db8::10 -all
If outbound mail leaves through a smarthost rather than directly, mx is wrong and include: the relay's domain, or list its IPs. A common pattern for residential or cloud hosts whose PTR does not match: relay through the provider's SMTP and authorise only that.
Keep -all only if you are certain nothing else sends. During a migration from another platform, start at ~all: hard fail on a domain with an unaudited sender silently discards customer mail, and because the rejection happens at the recipient, your logs show a successful queue.
Step 2: Generate DKIM
Zimbra's key tool is zmdkimkeyutil, run as the zimbra user:
su - zimbra
/opt/zimbra/libexec/zmdkimkeyutil -a -d example.com
The output contains a selector (a UUID such as 25D766CE-CEAC-11E7-B087-020B6DB9DD9A) and the public signature. Since ZCS 8.7 the key is 2048-bit by default.
Publish the record at SELECTOR._domainkey.example.com as a TXT value:
25D766CE-CEAC-11E7-B087-020B6DB9DD9A._domainkey.example.com. IN TXT (
"v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
)
That multi-string form is valid DNS: resolvers concatenate the quoted chunks. Most web panels want a single unquoted string instead — paste the whole value into one field and let the panel handle splitting. What you must not do is paste only the first chunk.
Other operations you will need eventually:
/opt/zimbra/libexec/zmdkimkeyutil -u -d example.com # rotate the key
/opt/zimbra/libexec/zmdkimkeyutil -q -d example.com # print current selector and key
/opt/zimbra/libexec/zmdkimkeyutil -r -d example.com # remove DKIM data
Step 3: Verify the key, not just the record
This is the step most guides skip, and the one that catches a mismatch between the private key in LDAP and the public key in DNS:
dig TXT 25D766CE-CEAC-11E7-B087-020B6DB9DD9A._domainkey.example.com +short @ns1.example.com
/opt/zimbra/common/sbin/opendkim-testkey -d example.com -s 25D766CE-CEAC-11E7-B087-020B6DB9DD9A -x /opt/zimbra/conf/opendkim.conf
No output from opendkim-testkey means success — an exit code of 0 with silence is the pass condition. An error about opendkim.conf at line 0 means the opendkim service is not enabled:
zmprov ms $(zmhostname) +zimbraServiceEnabled opendkim
/opt/zimbra/libexec/configrewrite opendkim
Then run the test again. On ZCS 8.6 and earlier the binary lives under /opt/zimbra/opendkim/sbin/.
Step 4: Key rotation without a gap
Rotation is where self-hosted DKIM goes wrong. The sequence that keeps mail verifiable throughout:
- Generate a new key (
-a) — this creates a second selector. - Publish the new selector's TXT record and wait for propagation.
- Switch Zimbra to sign with the new selector (handled by
-u, or by updating the domain's DKIM setting). - Leave the old record in DNS for at least a week — mail signed with the old key may still be in flight or in transit through greylisting queues.
- Remove the old selector only after that window.
Deleting the old record immediately invalidates every message still queued, which is a subtle way to see sporadic DKIM failures on newsletters and delayed mail.
Step 5: DMARC
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1"
Create the mailbox you point rua at, with a retention rule. Aggregate reports arrive as XML attachments (often gzipped) once per day per reporting domain; on a domain of any age that is hundreds of files a month. Feed them to the DMARC Report Analyzer rather than reading them by hand.
Zimbra has no built-in DMARC report ingestion, so this is a manual loop. Run p=none for two to four weeks, confirm every legitimate source aligns, then p=quarantine, then p=reject.
One Zimbra-specific caveat: if the server hosts multiple domains, each needs its own DKIM key, SPF record and DMARC record. A virtual domain that inherits another's SPF will fail alignment for its own From domain.
Step 6: Test from outside
Send to a Gmail account and read the original. Then send from Gmail to each of your Zimbra domains and check that inbound validation does not flag your own mail.
Authentication-Results: mx.google.com;
spf=pass smtp.mailfrom=example.com;
dkim=pass header.d=example.com header.s=25D766CE...;
dmarc=pass header.from=example.com
The header.s= value must match a selector you actually published. If it shows a UUID you removed during rotation, that is your gap.
Common mistakes
- Publishing only the first chunk of a multi-string TXT value.
- Never running
opendkim-testkey, so a key mismatch stays invisible until mail is rejected elsewhere. - Deleting the old selector the moment you rotate.
- Using
mxin SPF when mail leaves through a smarthost. - Forgetting virtual domains. Each one needs its own three records.
Frequently asked questions
Can I choose a readable selector instead of a UUID?
zmdkimkeyutil generates the selector for you and the value is a UUID; renaming it means renaming the LDAP attribute and the DNS record in step, which is possible but not worth it. Readable selectors matter for readability, not for deliverability.
Does Zimbra sign outbound mail for every domain automatically?
Once DKIM data exists for a domain in LDAP and the opendkim service is enabled, yes. A domain with no DKIM data is not signed, and nothing warns you — check with zmdkimkeyutil -q -d for each hosted domain.
Is a 2048-bit key always better?
Yes for security, with one caveat: a 2048-bit key produces a ~400-character TXT value. If you are hand-editing BIND zone files, remember the 255-character string limit and split accordingly, or the record will be silently malformed.
Related Tools
Need Help?
Our tools are designed to be intuitive, but if you need assistance, we're here to help.
About Our Tools
Professional-grade email and DNS diagnostic tools trusted by IT professionals worldwide.
