Configuration
A detailed step-by-step setup guide walks through all of the following configuration with more and options.
Only start the mailserver after all initial configuration has been completed, and sufficient time has passed for DNS entries to update.
Important
DNS changes should be applied to all domains on which the mail server will be hosting.
Hosting multiple domains will generate different keys for each domain. Use the correct keys.
Add Initial User Accounts
Actual email accounts for users. These are accounts that will be logged into.
Warning
These passwords should be unique for the user.
docker run --rm -e MAIL_USER={EMAIL} -e MAIL_PASS={PASS} -ti tvial/docker-mailserver:latest /bin/sh -c 'echo "$MAIL_USER|$(doveadm pw -s SHA512-CRYPT -u $MAIL_USER -p $MAIL_PASS)"' >> /data/mail/server/config/postfix-accounts.cf
Note
If the docker container is already running, these can be added dynamically using the setup helper script.
./setup.sh email add {EMAIL} {PASS}
Add Aliases
Local system aliases for mail delivery.
blackhole: /dev/null
Note
blackhole alias is made to redirect specific mail to /dev/null
(discard).
Add Virtual Mailboxes
Maps additional email addresses to accounts on the system. This enables a single user to have multiple email addresses, as well as catch-alls and blackhole known compromised email addresses.
# Some standard aliases.
handle@{DOMAIN} {USER}@{DOMAIN}
another_email_address@{DOMAIN} {USER}@{DOMAIN}
{USER}@{DOMAIN2} {USER}@{DOMAIN}
# Blackhole these addresses. (accept delivery and drop data).
known_spammer_email@{DOMAIN} blackhole@localhost
# Send all secondary domain emails to primary domain account.
@{DOMAIN2} {USER}@{DOMAIN}
Note
If the docker container is already running, these can be added dynamically using the setup helper script.
./setup.sh alias add {EMAIL} {RECIPIENT}
Use Dovecot for SMTP Authentication
Set Dovecot to handle SMTP authentication for sending email. See SASL SMTP postfix options.
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
Set Global Sieve Filters (Optional)
Apply global mail filtering rules before delivering mail.
See configure sieve filters. In this example, enable vacation messages (even for non-existing addresses to cover aliases) and send a message requesting the sender to update email address.
plugin {
sieve = ~/.dovecot.sieve
#sieve_default = /var/lib/dovecot/sieve/default.sieve
sieve_dir = ~/sieve
sieve_before = /usr/lib/dovecot/sieve-global/before.dovecot.sieve
sieve_extensions = +notify +imapflags +vnd.dovecot.pipe +vnd.dovecot.filter
sieve_plugins = sieve_extprograms
#recipient_delimiter = +
#sieve_max_script_size = 1M
#sieve_max_actions = 32
#sieve_max_redirects = 4
#sieve_quota_max_scripts = 0
#sieve_quota_max_storage = 0
sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe
sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter
sieve_vacation_dont_check_recipient = yes
}
Note
90-sieve.conf
can be copied from the server to use as a base template.
docker cp mail:/etc/dovecot/conf.d/90-sieve.conf .
services:
mail:
volumes:
- /data/mail/config/90-sieve.conf:/etc/dovecot/conf.d/90-sieve.conf
require "fileinto";
require "vacation";
# Automatically move flagged spam to spam folder
if header :contains "X-Spam-Flag" "YES" {
fileinto "spam";
stop;
}
# Allow email-update@{DOMAIN} to be delivered.
if address :is "to" "email-update@{DOMAIN}" {
keep;
stop;
}
# Autorespond with CM deprecation, send to special mailbox.
if address :is :domain "to" "{DOMAIN}" {
fileinto "email-update";
vacation
:days 1
:addresses "email-update@{DOMAIN}"
:subject "[Action Required]: Your contact information is out of date."
text:
You've recently sent an email to {DOMAIN}, which is no longer used.
Please request updated contact information by mailing:
email-update@{DOMAIN}
and you'll receive new contact information. Please delete any current
{DOMAIN} email addresses you have, as these are now invalid.
.
;
}
Generate DKIM Config
DKIM provides a method for validating a domain name identity that is associated with an email message through cryptographic authentication.
docker run --rm -v /data/mail/config:/tmp/docker-mailserver -ti tvial/docker-mailserver:latest generate-dkim-config
Note
Regenerate when new domains are added to the mail server.
Data is saved to /data/mail/config/opendkim/keys
Record |
TXT |
Name |
mail._domainkey_.{DOMAIN}. |
Target/Value/Data |
“v=DKIM1; k=rsa; ” “p=AZER…” “aUIOPQSDF…” |
TTL |
5 seconds |
Note
The DKIM data must be quoted for it to be properly stored. The generated data may be broken across multiple lines. Just use the content within the parentheses and separate quoted data with a single space. This allows the public key to be properly re-assembled for services that do not support large TXT record data.
Setup SPF Policy
Setup soft-failing for SPF policy enforcment.
Record |
TXT |
Name |
mail.{DOMAIN}. |
Target/Value/Data |
“v=spf1 mx ~all” |
TTL |
300 seconds |
Note
The MX
for mail.{DOMAIN}
must exist for this to work. see
Setup Mail DNS Entries for all DNS entries required for functioning service.
Tip
Once server is verified to work, switch to enforce
by changing the DNS
record to: v-spf1 mx -all
.
Setup DMARC Policy
Protects from phishing attacks by validating From
fields. Setup DMARC for
quarantine of flagged emails. The mailserver will automatically configure DMARC
using the POSTMASTER_ADDRESS
in the docker compose definition.
Record |
TXT |
Name |
_dmarc.{DOMAIN}. |
Target/Value/Data |
“v=DMARC1; p=quarantine; rua=mailto:postmaster@{DOMAIN}” |
TTL |
300 seconds |
Note
Use p=none
to test and ensure everything is working correctly.
p=reject
is the most strict but you must ensure everything is working
properly; this should be the default when service is live.
All DMARC policies.
Setup SSL Certificates
The container will automtically setup all services correctly if provided the appropriate Let’s Encrypt certificates.
Note
Explicit FQDN certificates should be created for the mail server DNS name, and
exist in the letsencrypt/live
. See Initial Setup
before proceeding.
mail:
volumes:
- /data/letsencrypt:/etc/letsencrypt:ro
Just add the letsencrypt live directory in read-only to enable SSL connections.
Disable Unsecured Services
POP3 should not be used, and unencrypted IMAP should be disabled.
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
port = 0
}
inet_listener pop3s {
port = 0
ssl = yes
}
}
Setup Mail DNS Entries
Setup DNS entries to allow for properly resolution of mail server. Redirect {DOMAIN} to mail.{DOMAIN} for mail inquries.
Root Domain Mail Redirect MX DNS Entry
Record |
MX |
Name |
{DOMAIN} |
Target/Value/Data |
10 mail.{DOMAIN}. |
TTL |
300 seconds |
Mail subdomain MX DNS Entry
Record |
MX |
Name |
{DOMAIN} |
Target/Value/Data |
10 {IP}. |
TTL |
300 seconds |
Mail subdomain A DNS Entry
Record |
A |
Name |
mail.{DOMAIN}. |
Target/Value/Data |
10 {IP}. |
TTL |
300 seconds |
Wildcard subdomain MX DNS Entry
Record |
MX |
Name |
@.{DOMAIN}. |
Target/Value/Data |
10 mail.{DOMAIN}. |
TTL |
21600 seconds |
Ensure DKIM DNS entry exists. See Use Dovecot for SMTP Authentication.
Ensure SPF DNS entry exists. See Setup SPF Policy.
Ensure DMARC DNS entry exists. See Setup DMARC Policy.