Lesson 020 · Linux MTA Operations Learning Path

Secure Linux Mail Server Operations

· Published · 8 min read

Labelled Linux mail flow showing mail server security and recovery configuration decision verification failure evidence and safe recovery

A production mail server needs least privilege, relay and abuse controls, patching, secret rotation, backups, restore tests and monitoring across every daemon. This lesson treats mail server security and recovery as one decision point in a longer message path. The configuration is useful only when an operator can show which message entered it, which identity and rule matched, what the next daemon returned, and how a failure is retried or contained.

Prerequisites and inherited lab checkpoint

Lessons 1 through 19 must each have a retained checkpoint and one traceable test message.

For the mail server security and recovery lab, use reserved domain example.test, documentation addresses and disposable messages. Preserve postconf -n, postconf -M, package versions, DNS answers and a queue baseline before changing the lab. Keep console access and do not copy credentials, private keys or customer messages into the evidence record.

Install and prepare the required components

sudo dnf info postfix dovecot policycoreutils-python-utils
sudo dnf install -y postfix dovecot policycoreutils-python-utils
sudo cp -a /etc/postfix /etc/postfix.before-nitwings
rpm -q postfix dovecot policycoreutils-python-utils
  • Confirm package availability and ownership in the enabled RHEL repositories before adding a third-party source. Record the repository, signing key fingerprint, version and support lifecycle.
  • A package install creates files and service identities; it does not establish safe relay, authentication, delivery or filtering behavior.
  • Back up only the files this lesson changes and record modes, owners and SELinux labels so rollback restores more than text.
  • Use systemctl cat, package file lists and local manual pages to identify paths on the installed build instead of assuming a path from another distribution.

Build the mail server security and recovery configuration and understand every boundary

The following lab configuration keeps ownership and failure behavior visible. Replace reserved identities only after the matching DNS, database, socket or filesystem object has been created.

disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 60
smtpd_error_sleep_time = 1s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20
# Keep mynetworks explicit; never include an unreviewed client network.

Validate the effective configuration before reload, trace one accepted message and one rejected message, and retain the queue ID. A syntactically valid file can still express the wrong trust boundary.

Verify the working path

sudo postfix check
sudo doveconf -n
sudo ss -lntup
sudo firewall-cmd --get-active-zones
sudo ausearch -m AVC -ts recent
sudo dnf updateinfo list security
sudo postconf -n
sudo doveconf -n
  • Run the syntax or lookup test before reload. A reload must never be the first parser of a production configuration.
  • The positive test proves the intended path. The negative test proves an unauthorized sender, recipient or client is not accidentally accepted.
  • Stop the named dependency in the disposable lab and verify temporary failure or controlled bypass matches the documented policy.
  • Repeat the accepted path after restart and reboot, then compare effective configuration rather than only source files.

Production decisions before continuing

DecisionChoose deliberatelyEvidence to retain
Failure policyA security dependency failure follows the documented availability boundary and pages an out-of-band channel; it never silently opens relay or disables authentication.SMTP transcript, queue state and dependency alert
Trust boundaryTrust only the explicitly named local daemon, authenticated identity, internal host or validated result required at this stage. Never infer trust merely because traffic originates on localhost.Matching client, sender, recipient or daemon identity
Secrets and dataRestrict credentials, message samples and keys to the minimum service identity.Owner, mode, label and secret rotation record
ActivationValidate, reload, run positive and negative tests, then watch one complete message.Syntax output, queue ID and linked log events
RollbackRestore the exact files and map/database state changed by this lesson.Rollback command and repeated acceptance result

Place mail server security and recovery in the message path

A production mail server needs least privilege, relay and abuse controls, patching, secret rotation, backups, restore tests and monitoring across every daemon. Security is the composition of network exposure, daemon privilege, identity, rate controls, data protection and recoverability, not one hardening parameter.

Understand the component before configuring it

LayerQuestion to answerEvidence
InputConnection, envelope, content or stored-message evidence entering this stageSMTP transcript, lookup input or message header
DecisionSecurity is the composition of network exposure, daemon privilege, identity, rate controls, data protection and recoverability, not one hardening parameter.Effective configuration and exact matched rule
OutputAn explicit accept, reject, defer, annotate, route or delivery resultQueue state, delivery status or downstream response
DependencyThe named daemon, lookup, socket, DNS record and storage required for the decisionSocket, timeout, journal and controlled outage test
RecoveryCan processing resume without duplicate, loss or unauthorized delivery?Retained queue ID, backup and repeated acceptance

Build it step by step

  1. Draw the path. Mark the connection, envelope, content and authenticated identities available at this stage.
  2. Inventory the effective state. Capture package version, active service, sockets, Postfix parameters, master services and lookup results.
  3. Prepare one coherent configuration. Substitute documented lab values and verify ownership, mode and SELinux context.
  4. Validate before activation. Run component syntax checks, map queries and a non-delivering test where supported.
  5. Exercise three outcomes. Send an intended message, an intended denial and a message while the named dependency is unavailable.
  6. Trace one queue ID. Join ingress, policy, filtering, routing and final delivery events without relying on subject text.
  7. Close the change. Restart or reboot where relevant, repeat tests, check queue age and document rollback.

Operate and inspect the component

postconf -n
postconf -M
doveconf -n
ss -lntup
firewall-cmd --list-all
getenforce
find /etc/postfix /etc/dovecot -xdev -type f -printf '%m %u:%g %p\n'
postqueue -p
  • Replace sample hostnames, addresses and queue IDs only after resolving them from the lab. Do not paste production identities into a public command transcript.
  • postconf -n shows non-default global parameters; postconf -M and postconf -P expose master service and field overrides.
  • A successful lookup proves only that input. Test present, absent, disabled and dependency-unavailable results separately.
  • Use the queue ID as the correlation key. Message subjects and recipient addresses are not unique and may contain sensitive information.

Evidence and acceptance criteria

EvidenceHealthy resultFailure meaning
SyntaxAll component validators succeed before activationThe running service would parse an unreviewed or invalid state
Positive pathA reserved valid message follows the intended path and produces the expected evidence.The intended message cannot complete this decision point
Negative pathA deliberately invalid identity, recipient or content sample is denied or classified at the designed stage.The configuration may relay, authenticate, route or deliver too broadly
Dependency failureStopping the dependency produces the documented temporary failure or reviewed bypass and raises an observable signal.Messages may be lost, permanently rejected or silently bypass controls
PersistenceEffective state and tests agree after restart and rebootOnly transient state was changed

Worked incident: mail server security and recovery behaves differently from the design

A backup contains main.cf but omits SQL, Maildir, Sieve, TLS and DKIM keys. Restore starts daemons but loses identity and mail. A coordinated encrypted backup plus isolated restore test proves the actual recovery point.

Troubleshooting by symptom

SymptomInspect firstDefensible next action
Service active but no decisionSocket, effective configuration and queue-linked logsFind the first layer where the message bypasses the component
Every message failsSyntax, permissions, label, dependency and timeoutRestore the last valid state and retest one fixture
Invalid sample passesRule order, trusted-source exception and actual input identityCorrect the narrow matching rule and rerun negative tests
Intermittent deferralDependency latency, process limits, queue age and resource pressureFix capacity or failure policy without discarding queued mail

Unsafe operations and recovery boundaries

  • Unsafe: changing several mail-flow stages in one reload makes causality and rollback ambiguous.
  • Unsafe: logging full credentials, private keys or customer messages expands the incident boundary.
  • Unsafe: deleting or requeueing the whole queue to hide a failure destroys mail or creates duplicates.

Rewritten knowledge checks

What is the input to this decision?
Identify the exact connection, envelope, content, DNS or stored-message field named in the lesson.
What proves the component ran?
A queue-linked log, header, lookup result or delivery status produced by that component.
What should dependency outage do?
A security dependency failure follows the documented availability boundary and pages an out-of-band channel; it never silently opens relay or disables authentication.
Why run a negative test?
It proves trust or matching has not become broader than the intended path.
What completes the change?
Persistence, monitoring, rollback and one end-to-end message after restart.
What must be captured before this change?
The effective configuration, package versions, owned sockets, a UTC test result and the exact files or database rows that rollback will restore.
Why is a service restart not an acceptance test?
A running process does not prove the intended message path, denial path, dependency failure behavior or persistence.
What makes a placeholder safe to replace?
Its source, format, owner and scope are explained and the substituted value is verified before activation.
When should rollout stop?
Stop when identity is ambiguous, syntax fails, the negative test becomes permissive, a dependency failure produces permanent loss or rollback cannot be executed.
What evidence belongs in handover?
The reviewed configuration, syntax output, positive and negative transcripts, logs, monitoring threshold, backup location and tested rollback result.

Cumulative lab checkpoint

  1. Capture the inherited checkpoint and state the exact sender, recipient, client address and expected SMTP result.
  2. Install the required package from a recorded source and save the package/file/service inventory.
  3. Apply the complete lab configuration, including permissions, socket paths, map generation and service ownership.
  4. Run syntax and lookup validation, then activate without closing the recovery session.
  5. Complete positive, negative and dependency-outage tests while retaining queue IDs and UTC logs.
  6. Restart the participating services, repeat the accepted path and confirm no unexplained deferred mail remains.
  7. Execute rollback once, prove the previous behavior, then reapply the reviewed state as the checkpoint for the next lesson.

Primary references

Advertisement