Mail Server Setup: Postfix and Dovecot
Complete guide on Postfix MTA, Dovecot IMAP/POP3, SSL/TLS configuration, virtual domain support, spam filtering, and Docker Mail Server setup.
Complete guide to configuring SPF records, DKIM signing, DMARC policies, DNS records, and testing tools to improve email deliverability and security.
Email deliverability and trustworthiness depend on proper DNS configuration. SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail), and DMARC (Domain-based Message Authentication, Reporting & Conformance) protocols prevent your emails from landing in spam folders and protect against domain spoofing.
In this guide, we will configure SPF, DKIM, and DMARC records step by step to secure your email sending infrastructure on your REXE server.
SPF is a DNS record that defines which servers are authorized to send emails on behalf of your domain. The receiving mail server checks whether the incoming email originates from an IP address specified in the SPF record.
Add it as a TXT record in your DNS management panel:
@ IN TXT "v=spf1 ip4:SERVER_IP_ADDRESS -all"
If you use multiple servers:
@ IN TXT "v=spf1 ip4:IP_ADDRESS_1 ip4:IP_ADDRESS_2 include:_spf.google.com -all"
| Mechanism | Description |
|---|---|
ip4: | Specific IPv4 address or CIDR block |
ip6: | Specific IPv6 address or CIDR block |
include: | Include another domain's SPF record |
a | Allow the IP in the domain's A record |
mx | Allow the servers in the domain's MX record |
all | Policy for all other sources |
+all → Pass (allow all — NOT RECOMMENDED)
~all → SoftFail (mark unauthorized but don't reject)
-all → Fail (reject unauthorized — RECOMMENDED)
?all → Neutral (no check)
Always use -all or at least ~all in your SPF record. Using +all leaves your domain open to spoofing.
# Query SPF record with dig
dig TXT example.com +short
# Query with nslookup
nslookup -type=TXT example.com
Online tools:
DKIM is a protocol that adds a digital signature to outgoing emails, verifying that the message has not been altered during transit. The sending server signs with a private key, and the receiving server verifies using the public key in DNS.
Create a 2048-bit RSA key pair with OpenSSL:
# Generate private key
openssl genrsa -out dkim_private.pem 2048
# Extract public key
openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem
# Convert public key to DNS format
cat dkim_public.pem | grep -v '^-' | tr -d '\n'
Install OpenDKIM:
sudo apt update
sudo apt install opendkim opendkim-tools -y
Generate keys:
sudo mkdir -p /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s default -v
sudo chown -R opendkim:opendkim /etc/opendkim
OpenDKIM configuration file (/etc/opendkim.conf):
AutoRestart Yes
AutoRestartRate 10/1h
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
Mode sv
SubDomains no
OversignHeaders From
KeyTable refile:/etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
ExternalIgnoreList /etc/opendkim/trusted.hosts
InternalHosts /etc/opendkim/trusted.hosts
Socket inet:8891@localhost
Key table file (/etc/opendkim/key.table):
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default.private
Signing table file (/etc/opendkim/signing.table):
*@example.com default._domainkey.example.com
Trusted hosts file (/etc/opendkim/trusted.hosts):
127.0.0.1
localhost
example.com
Add the generated public key as a TXT record in DNS:
default._domainkey IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhki...(PUBLIC_KEY)..."
DKIM keys should be 2048-bit. 1024-bit keys are no longer considered secure.
Add to Postfix configuration (/etc/postfix/main.cf):
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
Restart services:
sudo systemctl restart opendkim
sudo systemctl restart postfix
# Query DKIM record from DNS
dig TXT default._domainkey.example.com +short
# OpenDKIM test tool
opendkim-testkey -d example.com -s default -vvv
DMARC combines SPF and DKIM results, giving domain owners the ability to set email authentication policies and receive reports. The receiving server acts according to the DMARC policy for emails that fail SPF or DKIM verification.
Add as a TXT record in DNS:
_dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1; adkim=r; aspf=r; pct=100"
| Policy | Description | Usage |
|---|---|---|
p=none | Report only, no action | First stage — monitoring |
p=quarantine | Send to spam folder | Medium protection |
p=reject | Reject the email entirely | Full protection |
| Tag | Description | Example |
|---|---|---|
v | Version (required) | v=DMARC1 |
p | Policy (required) | p=reject |
rua | Aggregate report address | rua=mailto:report@domain.com |
ruf | Forensic report address | ruf=mailto:forensic@domain.com |
fo | Failure reporting option | fo=1 (on every failure) |
adkim | DKIM alignment mode | r (relaxed) or s (strict) |
aspf | SPF alignment mode | r (relaxed) or s (strict) |
pct | Policy application percentage | pct=100 |
sp | Subdomain policy | sp=reject |
Implementing DMARC gradually is the safest approach:
# Stage 1: Monitoring (2-4 weeks)
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1"
# Stage 2: Quarantine (2-4 weeks)
_dmarc IN TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@example.com"
# Stage 3: Increase quarantine
_dmarc IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@example.com"
# Stage 4: Full protection
_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; ruf=mailto:dmarc-forensic@example.com"
You can use free tools like dmarcian.com, postmarkapp.com/dmarc, or easydmarc.com to analyze DMARC reports.
Check all email security records at once:
# SPF check
dig TXT example.com +short | grep spf
# DKIM check
dig TXT default._domainkey.example.com +short
# DMARC check
dig TXT _dmarc.example.com +short
# MX record check
dig MX example.com +short
Send a test email from the command line:
# Detailed test with swaks
sudo apt install swaks -y
swaks --to test@gmail.com --from info@example.com --server localhost --tls
Check the headers of the sent email:
Authentication-Results: mx.google.com;
dkim=pass header.d=example.com;
spf=pass (google.com: domain of info@example.com designates SERVER_IP as permitted sender);
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
| Error | Cause | Solution |
|---|---|---|
| SPF PermError | More than 10 DNS lookups | Reduce include count, consolidate IP blocks |
| DKIM fail | Key mismatch | Public key in DNS must match private key on server |
| DMARC fail | SPF and DKIM alignment error | From header domain must match SPF/DKIM domain |
| Softfail | Using ~all in SPF record | Replace with -all |
| Body hash mismatch | Email modified in transit | Set canonicalization to relaxed/relaxed |
The SPF, DKIM, and DMARC trio forms the foundation of email security. Properly configuring these three protocols improves email deliverability, prevents domain spoofing, and protects your brand reputation. Implement DMARC gradually, analyze reports, and ensure all legitimate sending sources are compatible with SPF and DKIM before moving to full protection.
Technically yes, but emails sent from domains without SPF records will most likely end up in spam or be rejected. Major providers like Gmail and Outlook enforce SPF checks.
A minimum of 2048-bit RSA key should be used. 1024-bit keys are no longer considered secure. Some providers support 4096-bit keys, but 2048-bit is the most common choice due to DNS TXT record size limitations.
Not recommended. Start with p=none for monitoring, analyze reports, ensure all legitimate sending sources are compatible with SPF and DKIM, then gradually move to quarantine and reject.
The SPF standard allows a maximum of 10 DNS lookups. Each include, a, and mx mechanism counts as one lookup. Exceeding this limit results in an SPF PermError. You can reduce lookup count by specifying IP addresses directly.
Verify that SPF, DKIM, and DMARC records are correctly configured. Ensure the Reverse DNS (PTR) record matches the server hostname. Check if your IP address is blacklisted at mxtoolbox.com/blacklists.aspx. Avoid spam trigger words in email content.
Complete guide on Postfix MTA, Dovecot IMAP/POP3, SSL/TLS configuration, virtual domain support, spam filtering, and Docker Mail Server setup.
Blacklist checking, delisting requests, Spamhaus/Barracuda/SORBS procedures, and IP reputation management guide.