Practical tools for system, network, security, and operations administrators.

SYS-C0194 · Mail Server Administration

Mail Server Administration Guide

Separate submission from relay, and never leave a mail server open to the world.

Updated 25 October 2026 · Pillar guide

This is an original planning guide. It is not a vendor manual, an official standard, or legal advice. Example addresses use documentation ranges. Review every command before you paste it.

Who may send, and who may read

A mail server that accepts mail for your domains and a mail server that lets clients send are related and not the same listener. Submission is the authenticated port your users send through. The public port 25 receives mail from other servers for the domains you host. An open relay accepts mail from the world for domains you do not host, and you will not configure one. The lab uses a documentation address and a prefix you name, and production replaces both with the real domain and the real client prefix.

Postfix is a common MTA. Dovecot is a common way to serve mailboxes over IMAP. The generators on this site draft a main.cf shape and a Dovecot shape. Read them. A draft that sets mynetworks to every address is a draft you delete. mynetworks in the lab is 192.0.2.0/24 only if that is the lab you built, and in production it is the prefix your authenticated clients or your internal hosts actually use. Everyone else authenticates or is refused.

Mailboxes are files or a database with an owner. The permissions guide applies. A mailbox directory that other users can read is a privacy incident. Logs from the mail guide's logging setup will contain addresses. They should not contain passwords. If a debug flag prints a password, turn it off and rotate that password.

The security desk's email guide is the companion for SPF, DKIM, and DMARC. This page does not pretend those records are optional decoration, and it does not invent the DNS for you. Until those records exist, do not be surprised when other servers refuse or spam-folder your mail. Fix them as their own change.

A lab that receives for one name and does not relay

The lab hostname is edge-01.example.com and the domain you accept for is example.com, which you use only because it is a documentation name. Do not point a real domain at this lab by accident. The host accepts mail for example.com and refuses to relay for other domains. A test from the lab prefix to a local mailbox works. A test that tries to send to an unrelated domain, without authentication, fails. That failure is the proof you want.

Submission, if you enable it, requires authentication and TLS you have a certificate for, or it stays off in the lab. Do not enable submission on every interface with no password to see if a client works. The client test uses one account whose password is prompt-for-this in any note, replaced before the daemon starts, and never written into the ticket.

Dovecot, if the lab needs to read the mailbox, listens for that user and that mailbox path. It does not turn on a clear-text login on a public address. The config test for each daemon is the one the package documents. Reload only after it passes.

Write the accept domains, the mynetworks prefix, and the result of the refused relay test in the ticket. Rollback is the previous main.cf, which you kept.

# Review before you paste. Lab intent, not a complete config.
# Accept example.com only. Relay is not open.
# mynetworks is the lab prefix you named, never every address.
# A send to an unrelated domain without auth must fail.
# Replace prompt-for-this. Do not store the password in the ticket.

A change you can finish

Production replaces example.com with a domain you host and replaces the prefix with the real client network. The refused-relay test is repeated after the change. DNS records from the security companion are a separate ticket that has to be true before you expect other servers to trust you.

Rollback is the previous configuration and a reload. You do not debug a possible open relay by widening mynetworks.

  1. List the domains you accept mail for.
  2. Set mynetworks to the prefix you operate, not to the world.
  3. Prove an unauthenticated send to an unrelated domain fails.
  4. Prove a local delivery to a lab mailbox works.
  5. Turn on submission only with authentication, and keep the password out of the ticket.
  6. Pass each daemon's config test before reload.
  7. Hand SPF, DKIM, and DMARC to their own change with the security companion.

Mistakes that outlive the command

mail server administration fails in the same few ways. Each one looks finished on the day you type it. The list is here so the ticket can forbid them before the window, not so you can recognise them in an incident review.

Decisions to write down before the window

One decision for mail server administration: Accepted domains are a list. example.com stays only in the lab. mynetworks is a prefix you can draw. It is not every address. Unauthenticated relay to other domains fails, and you have a transcript of that failure. Submission requires authentication. The password is prompt-for-this in notes and real in the password store, not in the ticket. Mailbox files follow the permissions guide. Config tests pass before reload. The generators' drafts were searched for a wide mynetworks and that line was removed. SPF, DKIM, and DMARC are a companion change, not a paragraph you skip. Logs do not contain passwords. Rollback is the previous main.cf and dovecot config. And a second person saw the refused relay.

Mail checks before the server accepts real mail

Confirm this before you call the change done: The accept-domain list matches the ticket. mynetworks is the named prefix, not the world. An unauthenticated relay attempt failed. A local test message was delivered. Submission is authenticated or still off. No password is in the ticket or the log. Mailbox modes match the permissions guide. Both daemons passed their config tests. The previous configs are saved. example.com is not left in a production accept list. The security companion owns the DNS records and they are not guessed here. A second person saw the relay refusal. The queue is not full of mail to domains you do not host. The hostname in the prompt matches the hostname in the ticket for mail server administration. The result line includes the time and the person, not only the command. You can point at the rollback value without searching a chat history. And done is a sentence a second person can repeat: the proof for mail server administration happened, and the next host is not started early. If one of those fails, stop.

Tools for this guide

These tools run in the browser on this site. They do not log into your machines.

Guides in this cluster

These supporting pages belong to this pillar.

Companion: Security: Email Security Guide.