| name | linux-mail-server |
| description | Use when operating or diagnosing Postfix, Exim, Dovecot, SMTP submission, mail queues, TLS, or SPF/DKIM/DMARC on a Linux mail host. Use linux-network-admin for general reachability and linux-dns-server when the task is authoritative zone operation. |
| license | MIT |
| metadata | {"portable":true,"compatible_with":["claude-code","codex"],"author":"Peter Bamuhigire","author_url":"techguypeter.com","author_contact":"+256784464178"} |
Linux Mail Server
Distro support
Postfix and Dovecot run on both families and their config layout
(/etc/postfix/main.cf, /etc/dovecot/) is largely identical;
postconf, postmap, postqueue, newaliases behave the same. The
differences are a few package names, the mail log path, and SELinux. Body uses
Debian/Ubuntu; the RHEL family (Fedora, RHEL, CentOS Stream, Rocky, Alma,
Oracle) equivalents are in the matrix.
| Concept | Debian/Ubuntu | RHEL family |
|---|
| Postfix package / unit | postfix | postfix (same) |
| Default MTA | sometimes exim4 | postfix |
| Dovecot | dovecot-core, dovecot-imapd | dovecot |
| DKIM | opendkim (main) | opendkim (EPEL) |
| Mail log | /var/log/mail.log | /var/log/maillog |
| Config paths | /etc/postfix, /etc/dovecot | same |
| Tools | postconf, postmap, postqueue, newaliases | identical |
RHEL-family gotchas: opendkim (and some milters) come from EPEL
(ensure_epel) on RHEL/Rocky/Alma, but ship in main on Fedora. SELinux governs
Postfix/Dovecot — non-default mail-spool or maildir paths need the right
contexts (restorecon, semanage fcontext) and some integrations need
booleans. Mail logs are in /var/log/maillog (cross-ref linux-log-management).
Deep SELinux coverage is in linux-server-hardening / Phase 2.
In sk-* scripts use the common.sh primitives (pkg_install, ensure_epel,
svc_name) instead of hardcoding the family. See
linux-bash-scripting and
docs/multi-distro/plan.md.
Use when
- Managing Postfix, Exim, Dovecot, queue behavior, or SMTP testing.
- Debugging delivery failures, spam-folder placement, or TLS/authentication issues.
- Updating SPF, DKIM, or DMARC-related server-side behavior.
Do not use when
- The task is general DNS hosting unrelated to mail service; use
linux-dns-server.
- The task is generic network reachability without a mail-specific angle; use
linux-network-admin.
Required inputs
| Artefact | Source | Required? | If absent |
|---|
| Mail role, software, domain/hostname, and current configuration | Mail host and service owner | required | Return discovery commands; do not edit a guessed topology. |
| Symptom, timestamps, queue IDs, sender/recipient domain, and relevant redacted logs | Incident report and host | required for diagnosis | Mark the affected transport stage not assessed. |
| DNS/TLS/relay ownership and approved test recipient | Domain and service owners | required for change/test | Stop before publishing records or sending mail. |
Workflow
- Identify whether the issue is configuration, queueing, transport, or authentication.
- Inspect current config, queue state, and relevant logs.
- Apply the matching workflow below for reputation, submission, queue, or domain changes.
- Re-test SMTP flow and authentication to confirm the result.
- Stop if relay scope, DNS/TLS ownership, queue impact, test-recipient authority, or rollback is unresolved.
- Recover by restoring the prior validated config/records, reloading the service, and retesting a controlled message before resuming the queue.
Quality standards
- Verify with real SMTP tests and queue inspection, not assumption.
- Keep authentication records and mail config aligned.
- Separate transport problems from reputation and policy problems.
Anti-patterns
- Treating spam placement as only connectivity. Fix: inspect SPF, DKIM, DMARC, reverse DNS, TLS, reputation, and message evidence separately.
- Flushing/deleting a queue before diagnosis. Fix: sample queue IDs, reasons, age, destination patterns, and logs first.
- Enabling an open relay or broad trusted network. Fix: restrict relay to authenticated/explicit clients and test rejection externally.
- Publishing mail-authentication records without alignment tests. Fix: validate selectors, policy, envelope/header domains, and authoritative DNS.
- Logging or sharing message bodies/credentials unnecessarily. Fix: use queue IDs, headers, and redacted protocol traces.
Outputs
| Artefact | Consumer | Acceptance condition |
|---|
| Mail-path diagnosis or configuration change | Mail operator | Locates failure at submission, queue, DNS, transport, policy, mailbox, or reputation layer with evidence. |
| Authentication/TLS evidence | Domain owner | SPF/DKIM/DMARC alignment and certificate/hostname checks are observed, or explicitly unassessed. |
| Delivery verification | Service owner | Approved test mail receives expected SMTP codes and reaches the intended mailbox without creating an open relay. |
References
Evidence Produced
| Artefact | Acceptance condition |
|---|
| Mail-operation evidence | Includes redacted config, queue samples, log timeline, SMTP transcript, DNS/authentication/TLS results, authorised headers, and rollback. |
Capability contract
Diagnosis defaults to read-only. Mail configuration, queue mutation, DNS publication, certificate changes, service reloads, or sending external test mail require explicit authority. Never expose mailbox credentials, private keys, or message content beyond approved evidence.
Degraded mode
Without host, DNS, or recipient access, assess only available layers and label the rest not assessed. A successful TCP connection is not a delivery or reputation pass.
Decision rules
| Choice | Action | Failure or risk avoided |
|---|
| Queue deferral cluster | Inspect enhanced status/log cause before retry | Amplifying a persistent failure. |
| Authentication passes but spam persists | Examine reputation/content/provider feedback | Rewriting healthy transport config. |
| Submission auth failure | Test SASL/TLS listener and policy | Weakening relay controls. |
Worked example
For a growing Postfix queue to one provider, sample deferred queue IDs, correlate enhanced status codes and logs, verify DNS/TLS/authentication, correct the evidenced cause, reload only after config validation, retry a small sample, and record delivery before releasing the remainder.
This skill is self-contained. Every command below is a standard mail
tool (postfix, postqueue, postconf, swaks, openssl, dig) present on
both Debian/Ubuntu and the RHEL family; body examples use Debian/Ubuntu
syntax, with RHEL-family differences in the Distro support matrix above.
The sk-* scripts in the Optional fast path section
are convenience wrappers — never required.
This skill covers running and debugging mail on a Debian/Ubuntu or RHEL-family server:
Postfix (default), Exim (alternative), Dovecot for IMAP, and the three
pillars of email authentication — SPF, DKIM, DMARC.
It does not own:
- Firewall rules for SMTP ports —
linux-firewall-ssl.
- DNS records themselves (MX, SPF, DKIM, DMARC live at the DNS host) —
but this skill validates them.
- Mail clients — out of scope.
Informed by Linux Network Administrator's Guide (Sendmail/Exim chapters,
translated to Postfix) and modern email authentication practice.
When to use
- Setting up a server to send mail (transactional, notifications, relay).
- Diagnosing "my email goes to spam."
- Checking a mail queue for stuck messages.
- Testing SMTP from the command line (EHLO, STARTTLS, auth, RCPT).
- Validating SPF, DKIM, DMARC records for a domain.
- Inspecting a remote MX's reachability and TLS.
When NOT to use
- Setting up cloud email (SES, SendGrid, Postmark) — those are API-based.
- Managing DNS records at a registrar — use the registrar's UI or API.
Standing rules
- Never run a mail server without SPF + DKIM + DMARC. Unauthenticated
mail is treated as spam by every modern receiver.
- Never relay mail for third parties without authentication. Open
relays are abuse vectors.
mynetworks in main.cf must be
127.0.0.0/8 only by default.
- Always enable TLS for submission (port 587). STARTTLS only, reject
plain auth.
- Always validate config before reload.
postfix check for Postfix,
exim -bV for Exim.
- The queue is the first thing to check on delivery problems.
- Log everything to
/var/log/mail.log (syslog) and
journalctl -u postfix — both exist on modern Ubuntu.
- Reverse DNS (PTR) of the sending IP must match the HELO name.
Mismatched PTR is the single biggest reason mail is flagged as spam.
Quick reference — manual commands
Postfix config and status
sudo postfix check
postconf -n
sudo postfix reload
sudo systemctl restart postfix
sudo systemctl status postfix --no-pager
sudo journalctl -u postfix -n 50 --no-pager
sudo tail -f /var/log/mail.log
Queue inspection
sudo postqueue -p
sudo mailq
sudo postqueue -p | grep -c '^[A-F0-9]'
sudo postcat -q <queue-id>
sudo postqueue -f
sudo postsuper -d <queue-id>
sudo postsuper -d ALL
SMTP testing from the command line
sudo apt install swaks
swaks --server mail.example.com \
--port 587 \
--from sender@example.com \
--to recipient@example.org \
--auth LOGIN \
--auth-user sender@example.com \
--tls \
--header "Subject: test $(date)" \
--body "test body"
swaks --server mail.example.com --port 587 --quit-after STARTTLS
openssl s_client -starttls smtp -connect mail.example.com:587 -crlf
Email authentication checks
dig +short TXT example.com | grep spf1
dig +short TXT default._domainkey.example.com
dig +short TXT _dmarc.example.com
dig +short MX example.com
dig +short -x $(curl -s https://api.ipify.org)
Full email-auth deep dive (record syntax, DKIM key generation via
opendkim-genkey, DMARC reporting, example DNS zone snippet) — see
references/email-authentication.md.
Typical workflows
Workflow: "Our emails are going to spam"
Walk references/debugging-delivery.md.
Condensed:
sudo postqueue -p
sudo postcat -q <queue-id> | tail -20
dig +short TXT example.com | grep spf1
dig +short TXT default._domainkey.example.com
dig +short TXT _dmarc.example.com
dig +short -x $(postconf -h inet_interfaces | awk '{print $1}')
postconf -h myhostname
swaks --server mail.example.com --port 587 --quit-after STARTTLS
Workflow: "Is port 587 submission working?"
swaks --server mail.example.com \
--port 587 \
--auth LOGIN \
--auth-user bot@example.com \
--tls
Reports each step (connection, STARTTLS, AUTH, MAIL FROM, RCPT TO, DATA).
Workflow: "The queue is growing"
sudo postqueue -p | tail -5
sudo postqueue -p | head -30
sudo postcat -q <queue-id>
Workflow: "Add a new domain to an existing Postfix"
sudo nano /etc/postfix/main.cf
sudo nano /etc/postfix/virtual_alias_maps
sudo postmap /etc/postfix/virtual_alias_maps
sudo postfix check
sudo postfix reload
Troubleshooting / gotchas
- PTR record mismatch is the #1 spam trigger. If your server's IP
reverse-resolves to
vps-12345.provider.net but Postfix HELOs as
mail.example.com, receivers downgrade you immediately. Fix the PTR
at the VPS provider.
postfix reload doesn't reload everything. Changes to master.cf
require sudo systemctl restart postfix. postfix reload only
re-reads main.cf.
- TLS fails on port 465 but works on 587. Port 465 is implicit TLS
(SMTPS), 587 is STARTTLS. They need separate service stanzas in
master.cf — enable both.
- DKIM signs but receivers fail DMARC. Check alignment: the signing
domain (
d=) must match the From: header domain (relaxed alignment)
or exactly (strict). A DKIM-signed bounce that uses the mail server's
hostname as d= won't align with the sender's domain.
- Postfix is silently deferring. Look in
/var/log/mail.log — the
rejection reason is there. The queue only shows the summary.
- Dovecot and Postfix disagree about a user. Postfix's
virtual_mailbox_maps must match Dovecot's passdb / userdb. Use
a single source of truth (MySQL, LDAP, or a flat file) and point both
at it.
References
references/postfix-reference.md —
full Postfix reference: main.cf parameters, master.cf, queue
management, 3 complete config examples.
references/email-authentication.md —
SPF, DKIM (with opendkim), DMARC deep dive with DNS record examples.
references/debugging-delivery.md —
decision tree for delivery problems.
- Book: Linux Network Administrator's Guide (Kirch & Dawson) — mail
chapters (Sendmail/Exim, translated to Postfix).
- Book: Ubuntu Server Guide (Canonical) — Postfix and Dovecot.
- Man pages:
postfix(1), postconf(5), master(5), postqueue(1),
postcat(1), swaks(1).
Optional fast path (when sk-* scripts are installed)
Running sudo install-skills-bin linux-mail-server installs:
| Task | Fast-path script |
|---|
| MX records for domain + reachability + TLS + PTR match | sudo sk-mx-check --domain <d> |
| Audit SPF, DKIM, DMARC records for a domain | sudo sk-spf-dkim-dmarc --domain <d> |
| Postfix/Exim queue inspection grouped by recipient | sudo sk-mail-queue |
| Full SMTP conversation tester (wraps swaks) | sudo sk-smtp-test --host <h> --port 587 --tls |
These are optional wrappers around dig, swaks, postqueue, and
openssl s_client.
Scripts
This skill installs the following scripts to /usr/local/bin/. To install:
sudo install-skills-bin linux-mail-server
| Script | Source | Core? | Purpose |
|---|
| sk-mx-check | scripts/sk-mx-check.sh | no | MX records for a domain, preference order, reachability, reverse DNS, TLS cert of each MX. |
| sk-spf-dkim-dmarc | scripts/sk-spf-dkim-dmarc.sh | no | Audit SPF, DKIM, and DMARC records for a domain; report missing or misaligned. |
| sk-mail-queue | scripts/sk-mail-queue.sh | no | Postfix/Exim queue inspection: depth, oldest, stuck, by recipient domain. |
| sk-smtp-test | scripts/sk-smtp-test.sh | no | Full SMTP handshake tester (EHLO / STARTTLS / AUTH / MAIL FROM / RCPT TO / DATA), reports each step. |