Email Authentication and Security
A Practical Guide for Administrators — March 2026
This guide documents the lessons learned configuring complete email authentication (SPF, DKIM, DMARC) and spam/security hardening across multiple production domains on Koozali SME Server v10. It is a complement to the SME documentation. Many of these issues are either specific to SME v10, or involve SME-specific behaviors that differ from generic qmail or qpsmtpd guidance.
The guide covers: getting DKIM to actually sign mail (a common stumbling block), achieving Forward Confirmed Reverse DNS alignment, hardening bounce behavior, tuning spam filtering, and understanding the limits of authentication against modern social-engineering attacks.
Commands assume root access on an SME v10 server. GoDaddy is the registrar for the domains used as examples here; other registrars may have different interfaces or requirements for DNS record management.
Part 1: SPF Configuration
SPF (Sender Policy Framework) tells receiving servers which hosts are authorized to send mail for your domain. On SME v10, there are two IPs that typically need to be in scope: the server's own IP and the relay/smarthost your ISP or data center provides.
The Relay IP Problem
A common misconfiguration is publishing only the server's primary IP in the SPF record, omitting the relay. If your host routes outbound mail through a smarthost, some or all outbound messages will originate from that relay's IP — and receiving servers will see an SPF fail for your domain.
Include both the server IP and the relay in your SPF record. If your hosting provider has allocated you a subnet, use that rather than individual IP addresses to future-proof the record:
; Preferred — subnet covers all current and future IPs at this provider v=spf1 mx ip4:206.214.166.0/24 ~all ; Also acceptable — explicit IPs if the subnet approach is not appropriate v=spf1 mx ip4:203.0.113.10 ip4:203.0.113.6 ~all
Common Pitfalls
- The deprecated
ptrmechanism (v=spf1 ptr ...) should not be used. It is slow, unreliable, and ignored by many receivers. - Using
-all(hard fail) is aggressive and appropriate only after you are confident your SPF record is complete.~all(soft fail) is the safer setting during configuration and testing. - Each domain hosted on the server needs its own SPF record published in DNS. A record on the primary domain does not cover other hosted domains.
Part 2: DKIM on SME v10
DKIM (DomainKeys Identified Mail) signs outbound messages cryptographically, allowing receivers to verify that a message was sent by an authorized server and was not modified in transit. Getting DKIM working on SME v10 requires three things to be correct simultaneously: keys in the right location, the DKIMSigning property enabled, and a signal-event to regenerate the configuration. Missing any one of them produces the same frustrating result: dkim: skip, DKIM not configured for [domain] in your logs.
The Default Key Fallback
SME v10 also recognizes a server-wide default key at:
/home/e-smith/dkim_keys/default/
This key is used as a fallback for any domain that does not have its own per-domain key directory under /home/e-smith/dkim_keys/. If you are bringing up DKIM for the first time and want immediate coverage for all domains on the server before per-domain keys are configured, placing a key here will sign mail for all of them.
Most server will work great with this default key, you will only need to enable the signing of dkim
db configuration setprop qpsmtpd DKIMSigning enabled signal-event email-update
then you could get the important information you need to add to your DNS provider interface for SPF, DKIM and DMARC doing:
#qpsmtpd-dns
Here are sample DNS entries you should add in your public DNS.
There are two DKIM key copies.
Depending on your provider you might be able to copy these as is.
The first has a complete DKIM key with no "" breaks.
The second has the DKIM entry broken into 255 character chunks
with quotes for providers who cannot support long strings.
You may need to separate these with either a space, a newline or
a backslash escaped newline between the "" depending on your
dns provider.
You should either change the reporting email address for DMARC
or create the needed pseudonym 'dmarc-feedback'.
DKIM complete
=============
default._domainkey IN TXT v=DKIM1;p=YOURPUBLICKEYWILLPRINTHERE;t=y
DKIM in 255 character chunks
============================
default._domainkey IN TXT "v=DKIM1;p=YOURPUBLICKEYWILLPRINTHERE;t=y"
DMARC records
=============
@ IN SPF "v=spf1 mx a -all"
@ IN TXT "v=spf1 mx a -all"
_dmarc IN TXT "v=DMARC1; p=none; adkim=s; aspf=r; rua=mailto:dmarc-feedback@YOURDOMAIN.YOURTLD; pct=100"
Remark the t=y for test mode enabled. This will allow you to test that everything is ok, before enforce really the rejection of emails that are not signed, then change to t=n.
Per-domain keys are still the recommended architecture — they allow independent rotation and revocation per domain, and make auditing straightforward. The default key is best understood as a fallback or a starting point, not a long-term substitute on complex multiple domains installation.
The Authoritative Key Location
The SME v10 documentation contains conflicting references. Some wiki pages reference ~smtpd/config/dkim/[1] and others reference /etc/qpsmtpd/dkim/ need ref.. Neither of these is the correct location for v10.
The canonical key location for Koozali SME v10 is:
/home/e-smith/dkim_keys/[domain]/
Under that directory, SME expects two files:
/home/e-smith/dkim_keys/example.com/selector # contains the selector string, e.g. feb2026 /home/e-smith/dkim_keys/example.com/default # the private key (PEM format)
After signal-event email-update, SME's template system automatically creates symlinks from /var/service/qpsmtpd/config/dkim/ pointing to these source files.
Generating Keys
Use openssl to generate a 2048-bit RSA keypair. Create a separate keypair for each domain — per-domain keys allow rotation, revocation, and traceability independent of other domains on the same server.
# Create the directory for this domain mkdir -p /home/e-smith/dkim_keys/example.com # Generate the private key openssl genrsa -out /home/e-smith/dkim_keys/example.com/default 2048 # Extract the public key openssl rsa -in /home/e-smith/dkim_keys/example.com/default -pubout \ -out /home/e-smith/dkim_keys/example.com/default.pub # Write the selector string echo "feb2026" > /home/e-smith/dkim_keys/example.com/selector # Set correct ownership and permissions chown -R qpsmtpd:qpsmtpd /home/e-smith/dkim_keys/example.com chmod 400 /home/e-smith/dkim_keys/example.com/default
The same procedure applies to create the server-wide default key. Use /home/e-smith/dkim_keys/default/ as the directory and publish the resulting public key for all domains that will rely on it.
Enabling DKIM Signing
The DKIMSigning property must be explicitly set in the qpsmtpd configuration. This is separate from having keys in place and is a common omission:
db configuration setprop qpsmtpd DKIMSigning enabled signal-event email-update
After signal-event completes, verify that symlinks were created:
ls -la /var/service/qpsmtpd/config/dkim/ # Should show symlinks pointing to /home/e-smith/dkim_keys/[domain]/
Publishing the DNS Record
The public key is published as a TXT record under the selector._domainkey subdomain. Extract the raw public key bytes (stripping PEM headers and whitespace) and format it as follows:
; DNS TXT record name: feb2026._domainkey.example.com ; DNS TXT record value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...[base64 key]...IDAQAB
To get all the needed field easily formated for your DNS provider (there are 2 different expected output depending on the provider), you can use this command
qpsmtpd-dns exampledomain.com
Or you can try manually to extract the public key in the correct format:
openssl rsa -in /home/e-smith/dkim_keys/example.com/default \ -pubout -outform DER 2>/dev/null | openssl base64 -A
Verifying DKIM Signing
Send a test message and check the qpsmtpd log. A successful signing entry looks like:
dkim: pass, we signed the message
If you see dkim: skip, DKIM not configured for [domain], work through this checklist:
- Keys are in
/home/e-smith/dkim_keys/[domain]/(not/etc/qpsmtpd/dkim/) - Ownership is
qpsmtpd:qpsmtpdon all key files - Private key permissions are
400 - The
selectorfile exists and contains only the selector string (no trailing newline issues) DKIMSigningproperty is set toenabled(db configuration show qpsmtpd | grep DKIM)signal-event email-updatehas been run after the above changes- If no per-domain key directory exists, check whether
/home/e-smith/dkim_keys/default/is present and correctly configured
Selector Naming Convention
Use dated selectors (e.g., feb2026) rather than generic names like default or mail. Dated selectors make it straightforward to track when keys were generated, facilitate audits, and simplify rotation — you can publish a new key under a new selector name and migrate gracefully without downtime.
If You Had Keys in the Wrong Location
If you previously generated keys at /etc/qpsmtpd/dkim/ or another location, copy them to the canonical location rather than regenerating. This will avoid having to re-publish DNS records.
# Copy existing keys to canonical location cp -a /etc/qpsmtpd/dkim/example.com /home/e-smith/dkim_keys/ # Fix ownership chown -R qpsmtpd:qpsmtpd /home/e-smith/dkim_keys/example.com # Archive the old location — do not delete until DKIM is confirmed working mv /etc/qpsmtpd/dkim /etc/qpsmtpd/dkim.OLD-backup db configuration setprop qpsmtpd DKIMSigning enabled signal-event email-update
Part 3: DMARC Configuration
DMARC (Domain-based Message Authentication, Reporting & Conformance) ties SPF and DKIM together and tells receiving servers what to do with messages that fail authentication. It also enables reporting so you can see how your domain's mail is being received in the wild.
Basic Policy Record
; Monitoring-only policy — collects reports, takes no enforcement action _dmarc.example.com TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:dmarc@example.com" ; Quarantine policy — failed messages go to spam _dmarc.example.com TXT "v=DMARC1; p=quarantine; adkim=r; aspf=r; rua=mailto:dmarc@example.com" ; Enforcement — failed messages rejected _dmarc.example.com TXT "v=DMARC1; p=reject; adkim=r; aspf=r; rua=mailto:dmarc@example.com"
Alignment Tags
The adkim=r and aspf=r tags specify relaxed alignment, which allows subdomain matches. For example, relaxed DKIM alignment permits a message signed with a key for mail.example.com to satisfy DMARC for example.com. This is the correct setting for most SME installations where the MX hostname is a subdomain of the domain.
Strict alignment (adkim=s, aspf=s) requires an exact match between the authenticated domain and the From: header domain. This is appropriate only if you have complete control over all sending paths.
Reporting
The rua tag specifies where aggregate reports (XML digests of authentication results) are sent. If you are receiving reports for multiple domains, consider using a dedicated mailbox or a third-party DMARC reporting service such as EasyDMARC for parsing and visualization.
If the rua address is on a different domain than the domain being reported on, that external domain must publish a DNS record explicitly permitting the reporting:
; On the reporting domain (reportinghost.com), authorize reports for source.com: source.com._report._dmarc.reportinghost.com TXT "v=DMARC1"
Collect at least 2–4 weeks of monitoring data at p=none before moving to p=quarantine, and a similar amount of time at quarantine before moving to p=reject.
Part 4: Forward-Confirmed Reverse DNS (FCrDNS) Alignment
Many receiving mail servers perform FCrDNS checks: they look up the PTR record for the connecting server's IP, then verify that the resulting hostname resolves back to the same IP via an A record. If this check fails, or if the PTR hostname does not match what the server announces in SMTP HELO/EHLO, the message is more likely to be flagged or rejected.
This is particularly relevant if your server is a VM running in a managed hypervisor environment, such as at a commercial hosting company. In that case, the hosting company controls PTR records — you will need to request the correct value from them.
Three things must agree:
- The PTR record for the server's IP must resolve to its FQDN (e.g.,
nowata.example.com) - That FQDN must have an A record pointing back to the same IP
- The server's HELO/EHLO announcement must match that FQDN
Configuring the HELO Announcement
On SME v10, the server's HELO string is controlled by the HeloHost property of qpsmtpd. Set it to the server's FQDN and run signal-event to apply:
db configuration setprop qpsmtpd HeloHost nowata.example.com signal-event email-update # Verify db configuration show qpsmtpd | grep HeloHost
PTR Record
PTR records are managed by your hosting provider or ISP, not by your own DNS. Contact your provider with the desired PTR value. On servers shared with multiple domains, keep the PTR pointed to the server's own FQDN (the hostname) rather than any of the hosted domain names.
PTR instability — the record reverting to an unexpected value — is a known issue when multiple domains are hosted. Work with your provider to pin the PTR to the primary server hostname and confirm they will not automatically override it.
Diagnosing Mismatches
# Check what your server announces in HELO db configuration show qpsmtpd | grep HeloHost # Check PTR for your server IP dig -x 203.0.113.10 +short # Check A record for the PTR result dig nowata.example.com A +short
Part 5: Bounce Chain Hygiene
qmail's bounce behavior creates a potential for unsigned mail to escape the server, which can trigger DMARC failures and harm your domain's reputation. Two specific issues deserve attention on every SME v10 installation.
Double Bounce Prevention
When a message cannot be delivered, qmail generates a bounce (a "single bounce"). If that bounce itself cannot be delivered, qmail generates a double-bounce — a notification to the envelope sender of the original bounce, which is typically the empty address. By default on SME v10, double-bounces are sent to the postmaster address.
The problem: qmail-send generates these messages internally, bypassing qpsmtpd. This means double-bounces are never DKIM-signed. When they reach a receiving server, they fail DKIM and potentially fail DMARC, generating error reports and damaging reputation.
The correct fix is to route double-bounces to /dev/null:
db configuration setprop qmail DoubleBounceTo devnull signal-event email-update
Junkmail Maildir Ownership
A subtle but impactful issue: if the tmp directory inside a user's junkmail Maildir is owned by root rather than the user, SpamAssassin can deliver messages to the junkmail folder at the SMTP level, but local delivery will silently fail. The message disappears, a delivery failure is generated, and a bounce is produced — which then fails DMARC as described above.
This condition can persist for years after a user account is created without any visible symptoms until spam delivery is attempted. Audit all users:
# Check ownership for all users' junkmail tmp directories
for u in $(ls /home/e-smith/files/users/); do
dir="/home/e-smith/files/users/$u/Maildir/.junkmail/tmp"
if [ -d "$dir" ]; then
owner=$(stat -c "%U" "$dir")
if [ "$owner" != "$u" ]; then
echo "WRONG OWNER: $dir owned by $owner"
fi
fi
done
# Fix a specific user
chown username:username /home/e-smith/files/users/username/Maildir/.junkmail/tmp
Part 6: SpamAssassin Tuning
SME v10 ships with SpamAssassin integrated into the mail pipeline. The thresholds, Bayes state, and local rule configuration are all managed through the SME database and template system.
TagLevel and RejectLevel
TagLevel is the score at which messages are tagged as spam (X-Spam-Status header added). RejectLevel is the score at which messages are rejected at the SMTP level. View and adjust these via the database:
# View current settings db configuration show spamassassin # Adjust thresholds (example values) db configuration setprop spamassassin TagLevel 3.3 db configuration setprop spamassassin RejectLevel 12 signal-event email-update
A TagLevel of 3.3 is moderately aggressive — messages scoring above this will be flagged but not rejected. A high RejectLevel (10–15) is appropriate when SpamAssassin's Bayes corpus is well-trained, since false positives are rare and you want to avoid losing legitimate mail. Watch the X-Spam-Status headers of messages you receive to calibrate.
Envelope-Stage Blocking with badmailfrom
SpamAssassin operates on message content after the full message is received. For known-bad senders, it is more efficient to reject at the envelope MAIL FROM stage, before the message body is even transferred. SME exposes this through the badmailfrom mechanism, manageable via Server Manager under Email > Blacklist.
Add the envelope domain (not just the From: header address) of known spam/phishing sources:
# Via Server Manager: Email > Blacklist > Add # Or directly via the database: db accounts set @quickbooks-online.info badmailfrom Blacklisted yes signal-event email-update
This is particularly effective for recurring phishing campaigns from specific lookalike domains — the connection is terminated before SpamAssassin ever runs.
Bayes Corpus
SpamAssassin's Bayesian classifier learns from mail you have identified as spam or ham. A well-trained corpus (20,000+ spam tokens, 50,000+ ham tokens) significantly improves accuracy. Check the current state:
sa-learn --dump magic # Look for: nspam, nham, ntokens
If the Bayes database is available, SpamAssassin will assign BAYES_* scores to messages. A message with BAYES_80 or higher is a strong spam indicator even if other rule scores are low.
Local Rules
SpamAssassin supports custom rule files for site-specific matching. On SME v10, do not edit /etc/mail/spamassassin/local.cf directly — it is generated by the template system and will be overwritten. Consult the Koozali community for the sanctioned location for local rule files that survive signal-event expansions before deploying custom rules.
When writing custom rules, use meta-rules to require multiple conditions to be true simultaneously, reducing false positives:
# Example: flag messages mentioning cryptocurrency amounts AND phone numbers
body CRYPTO_AMOUNT /\$[0-9,]{4,}.*(?:bitcoin|crypto|BTC|ETH)/i
body CALLBACK_NUMBER /(?:call|contact|reach).*\+?[0-9][\s.-]?\(?[0-9]{3}\)?/i
meta CRYPTO_CALLBACK (CRYPTO_AMOUNT && CALLBACK_NUMBER)
score CRYPTO_CALLBACK 3.5
describe CRYPTO_CALLBACK Crypto scam with callback number
Part 7: ClamAV False Positives
ClamAV ships with heuristic signatures that attempt to detect phishing by analyzing link structures in HTML mail. These signatures can fire on legitimate transactional email from large financial institutions — particularly emails where the visible link text and the underlying URL domain differ, which is common in marketing and notification systems.
The signature Heuristics.Phishing.Email.SpoofedDomain is a frequent offender against alerts from banks and payment processors whose notifications are generated by third-party email platforms.
Diagnosing False Positives
# Check the qpsmtpd log for ClamAV rejections # Look for: clamav: virus found: Heuristics.Phishing.Email.SpoofedDomain # Scan a specific message to confirm clamscan --debug /path/to/saved/message.eml 2>&1 | grep -i phishing
Whitelisting
ClamAV supports signature-level whitelists. Before editing any ClamAV configuration, verify the correct whitelist file location for your SME installation to ensure the change survives package updates and signal-event runs:
# One common whitelist location (verify for your installation) # /etc/clamav/local.ign2 # Add the false-positive signature name echo "Heuristics.Phishing.Email.SpoofedDomain" >> /etc/clamav/local.ign2 # Reload ClamAV service clamd restart
Part 8: Authentication Bypass and Social Engineering
Passing SPF, DKIM, and DMARC is a necessary condition but is not sufficient for a message being legitimate. Sophisticated attackers have learned to send through infrastructure that authenticates cleanly — compromised legitimate accounts, legitimate marketing platforms, and cloud services that permit arbitrary content in automated messages.
Abuse of Legitimate Platforms
Several attack patterns exploit legitimate services to achieve clean authentication:
- Microsoft Teams Events / Dynamics 365: Attackers can create event registrations or calendar invites using free or trial accounts, embedding scam content in the event title or body. The confirmation emails arrive from Microsoft's own mail infrastructure with valid DKIM/SPF/DMARC.
- Firebase / Google Cloud: Attackers use Firebase applications to send bulk mail that authenticates under
firebaseapp.comor a related Google domain. The fact that DKIM passes forfirebaseapp.comis not evidence of legitimacy. - Compromised business accounts: A legitimate company's mail infrastructure, once compromised, can be used to send BEC (Business Email Compromise) attacks that pass all authentication checks.
Business Email Compromise (BEC)
BEC attacks often impersonate executives or trusted vendors and request wire transfers, gift card purchases, or changes to payment instructions. The technical signature is: authentication passes on a legitimate-looking domain, but the Reply-To header redirects responses to an attacker-controlled address.
Instruct staff, especially accounting personnel, to:
- Verify any payment instruction changes by phone using a number on record, not one provided in the email
- Be suspicious of urgency and requests for secrecy
- Check the Reply-To header, not just the From: display name, before replying
- Treat any request to bypass normal approval processes as a red flag regardless of the apparent sender
Custom SpamAssassin Rules
Content analysis can catch patterns that authentication cannot. Social-engineering scams typically combine several elements that rarely appear together in legitimate mail: large sums of money, urgency language, and callback phone numbers. Meta-rules that require multiple signals simultaneously can achieve reasonable detection rates without unacceptable false positives. See Part 6 for an example rule structure.
Before deploying custom rules, test them against your existing Bayes corpus and a representative sample of your legitimate mail to verify the false positive rate.
Part 9: WordPress PHPMailer Abuse
If your SME server hosts WordPress sites with contact forms, those forms can become spam relay vectors. PHPMailer — the library used by WordPress core and most form plugins — sends mail as the server's mail user, meaning spam sent through a contact form may bypass your inbound spam filters entirely and be sent as if it originated from your server.
Attack Pattern
Attackers use automated scripts to submit contact forms. The form plugin processes the submission and passes it to PHPMailer, which sends it to whatever address the form target specifies — or, in some plugins, the attacker can manipulate form fields to inject additional recipients or override headers.
Indicators of compromise:
- Unexpected outbound mail volume visible in qmail logs
- Bounce messages for addresses you did not send to
- Apache access logs showing high-rate POST requests to
/wp-admin/admin-post.php,/?wpcf7-f[id], or similar form handler endpoints from unfamiliar IPs
Mitigation
- Deploy CAPTCHA on all public contact forms. Cloudflare Turnstile integrates natively with Contact Form 7 via its official module and adds negligible friction for real users.
- Enable rate limiting on form submission endpoints at the web server or Wordfence level.
- Block confirmed attacker IPs at the server firewall or via Wordfence IP blocking.
- If
xmlrpc.phpis not required, disable it — it is a common brute-force target. - Ensure Wordfence WAF is in Enforced mode (not Learning mode) on all WordPress installations.
# Apache: block xmlrpc.php globally if not needed <Files xmlrpc.php> Order Deny,Allow Deny from all </Files>
Part 10: Testing Your Configuration
End-to-End Authentication: mail-tester.com
mail-tester.com provides a disposable address you can send a test message to, then view a scored report covering SPF, DKIM, DMARC, PTR/FCrDNS, blacklist status, and several content factors. It is the most practical single test for outbound authentication.
- Go to mail-tester.com and copy the unique test address
- Send a message from the domain under test using normal server mail (not a test utility — use your actual MUA or a service that sends through the server)
- Return to mail-tester.com and click Check your score
- Review any items that did not achieve full marks
A score of 10/10 is achievable with correct SPF, DKIM, DMARC, PTR alignment, and clean content. Scores of 9/10 or lower with DMARC at p=none reflect the monitoring-only policy rather than a failure.
Verifying DKIM in Logs
# Watch qpsmtpd log output in real time (SME v10 uses multilog, not tai64nlocal) # Adjust path as needed for your installation tail -f /var/log/qpsmtpd/current # In the output, look for lines like: # dkim: pass, we signed the message # dkim: skip, DKIM not configured for example.com <-- problem
Verifying DKIM in Received Headers
Ask a recipient to forward you the raw headers of a message, or use the message source view in a webmail client. A successfully signed message will include a DKIM-Signature header and the receiving server will add an Authentication-Results header indicating pass:
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=feb2026 header.b=AbCdEfGh;
spf=pass (google.com: domain of user@example.com designates 203.0.113.10 as permitted sender)
smtp.mailfrom=user@example.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=example.com
DMARC Reporting
Once aggregate reports are flowing, review them regularly — especially in the first few weeks after changing policy. EasyDMARC and similar services provide human-readable dashboards. Key things to look for:
- Any source IP sending mail for your domain that is not in your SPF record
- Any legitimate sending path where DKIM is failing (indicates a misconfigured third-party sender)
- Volume from sources you do not recognize at all (may indicate domain abuse or compromised credentials)
Part11: The Mailstats Contrib
The mailstats contrib interrogates the logs every night and emails admin, or a specified chosen email address, a table of the breakdown of all the emails received during the day into hourly buckets, categorised by how the SMEServer mail system deals with them. Examples are Webmail, Spam, RBL, etc. This provides the administrator an overview of how many emails are being dealt with daily, plus an indication of how many of them are created as "Non conformant" or Ham, etc. It shows overall counts, plus percentages. The data is held for a period in a local MySQL table, and could be used in further analysis. It also gives details of viruses found, Black list hits, counts for each recipient, junk mail folder contents and also a number of other useful counts.
See here for more details.
Summary Checklist
Use this as a per-domain verification checklist when bringing a new domain into full authentication.
| ✓ | Item | Reference |
|---|---|---|
| ☐ | SPF record published with server IP and relay IP | Part 1 |
| ☐ | No deprecated ptr mechanism in SPF |
Part 1 |
| ☐ | DKIM keys in /home/e-smith/dkim_keys/[domain]/ (or default/ fallback configured) |
Part 2 |
| ☐ | DKIMSigning enabled in qpsmtpd config |
Part 2 |
| ☐ | signal-event email-update run after key setup |
Part 2 |
| ☐ | Symlinks present in /var/service/qpsmtpd/config/dkim/ |
Part 2 |
| ☐ | DKIM DNS record published with correct selector | Part 2 |
| ☐ | DMARC record published (start with p=none) |
Part 3 |
| ☐ | DMARC rua address configured for aggregate reports |
Part 3 |
| ☐ | PTR record matches server FQDN (request from hosting provider) | Part 4 |
| ☐ | HeloHost matches server FQDN and PTR |
Part 4 |
| ☐ | FQDN A record resolves to server IP | Part 4 |
| ☐ | DoubleBounceTo devnull configured |
Part 5 |
| ☐ | Junkmail tmp directory ownership verified for all users |
Part 5 |
| ☐ | SpamAssassin TagLevel and RejectLevel set appropriately |
Part 6 |
| ☐ | End-to-end test with mail-tester.com completed | Part 10 |
| ☐ | DMARC reports reviewed and sources accounted for | Part 10 |
SME v10 Quick Reference
Database Commands
# View full qpsmtpd configuration db configuration show qpsmtpd # Set DKIM signing db configuration setprop qpsmtpd DKIMSigning enabled # Set HELO hostname db configuration setprop qpsmtpd HeloHost mail.example.com # Set SpamAssassin thresholds db configuration setprop spamassassin TagLevel 3.3 db configuration setprop spamassassin RejectLevel 12 # Set double-bounce handling db configuration setprop qmail DoubleBounceTo devnull # Apply all changes signal-event email-update
Key File Locations
/home/e-smith/dkim_keys/[domain]/ # DKIM keys — per-domain (canonical location) /home/e-smith/dkim_keys/default/ # DKIM keys — server-wide fallback /var/service/qpsmtpd/config/dkim/ # Symlinks (created by template system — do not edit) /etc/mail/spamassassin/local.cf # SpamAssassin config (generated — do not edit directly) /var/service/qpsmtpd/config/plugins # qpsmtpd plugin configuration
Log Locations
/var/log/qpsmtpd/current # qpsmtpd (inbound SMTP) log (multilog format) /var/log/qmail/current # qmail-send log
Template System Reminder
SME's template system regenerates configuration files during signal-event runs. Any configuration file in /etc/ or /var/service/ that is managed by a template will be overwritten. To make persistent changes, use db configuration setprop or provide e-smith template fragments. Consult the Koozali wiki and developer community for the correct template locations for any configuration not covered by db properties.