Ansible role is based on top of project docker-mailserver/docker-mailserver.
Role will create all needed prerequisites to run mail server in Docker but doesn't install the Docker itself.
All data are stored on host to prevent data loss during Docker restart.
- Account management
- Multiple accounts
- Multiple domains
- LDAP
- Let's Encrypt Key renew automation
- Standalone
- Nginx Proxy
- Host OS support
- Debian based
- Red Hat based
- Managable features
- ClamAV
- Fail2Ban
- OpenDKIM
- OpenDMARC
- Postgrey
- Spamassasin
- Ubuntu 18.04 LTS
Variable name | Default | Description |
---|---|---|
mail_accounts |
[] |
List of mail accounts according to Mail account format |
mail_domains |
[] |
List of mail domains (the first one should be your MX however certificate will be issued for all of them) |
mail_cert_email |
"" |
Email used for Let's Encrypt account |
mail_persist_folder |
/opt/mail |
(optional) Persistent folder for mail data, configuration, etc. on host |
mail_docker_image |
docker.io/mailserver/docker-mailserver |
(optional) Shouldn't be changed |
mail_docker_tag |
latest |
(optional) Image Docker tag used to run mail server |
mail_dkim_size |
2048 |
(optional) DKIM key size (available values are 1024, 2048, 4096) |
mail_amavis_config |
"" |
(optional) Configure Amavis overrides |
Each account in variable mail_accounts
has these parameters:
username
- part of email before "@", eg.user1
domain
- part of email after "@", eg.example.com
password
- user password in plaintextaliases
- list of aliases, each alias must be full emailrestrict
- list of restrictions, may besend
for suppress mail sending orreceive
for suppress mail receiving
mail_accounts:
- username: user1
domain: example.com
password: aaaaa
aliases:
- admin@example.com
- abuse@example.com
restrict: []
Install this Ansible role within the context of playbook
ansible-galaxy install hmlkao.docker_mailserver
Then create your playbook yaml file
---
- name: Localhost installation
hosts: localhost
roles:
- role: hmlkao.docker_mailserver
vars:
mail_accounts:
- username: user1
domain: example.com
password: aaaaa
aliases:
- admin@example.com
- abuse@example.com
restrict: []
- username: no-reply
domain: example.com
password: bbbbb
aliases: []
restrict:
- receive
mail_domains:
- server1.example.com
mail_cert_email: my-mail@somewhere.com
Suppose that your server host is server1.example.com
-
Be sure your public ports are opened
-
Add MX record to your DNS
example.com IN MX "1 server1.example.com."
-
Add TXT record with SPF to your DNS
example.com IN TXT "v=spf1 a mx ~all"
-
Add TXT record with DKIM to your DNS
-
You can find DKIM key in folder defined by
mail_persist_folder
variable in fileconfig/opendkim/keys/<domain.tld>/mail.txt
on your host (server)- Beware of that the record is divided by 250 characters so you have to concat it together
-
TXT record should look something like
mail._domainkey IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIIB...jwfx"
mail
is DKIM selector, not subdomain so there have to bemail._domainkey
for all, NOserver1._domainkey
or whatever else- Custom selector cannot be used.
-
-
Add TXT record with DMARC to your DNS What happen with mails which doesn't meet SPF and DKIM validation.
_DMARC IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:abuse+rua@example.com; ruf=mailto:abuse+ruf@example.com; fo=1"
-
ruf
- Reporting URI for forensic reports -
rua
- Reporting URI of aggregate reports -
Verify in commandline if is TXT applied
dig mail._domainkey.example.com TXT
-
-
Configure reverse DNS for host public IP
-
Ask your provider to configure reverse DNS
-
You should get something similar (where
<1.2.3.4>
is your public server IP)$ dig -x <1.2.3.4> +short server1.example.com.
-
There are many tools to test your mail server, eg.:
- dkimvalidator.com
- Generate email address which you can use to verify your SPF/DKIM config
- check-auth@verifier.port25.com
- Just send mail to this mail address from your account mail and your will receive report back to your mail address
- mxtoolbox.com
- Test your SMTP configuration
- Especially Deliverability test is useful (test SPF and DKIM)
- Just send mail to ping@tools.mxtoolbox.com from your account mail and your will receive report back to your mail address
- NOTE: MXToolBox DKIM validation fails (eg. docker-mailserver/docker-mailserver, serverfault.com even if another validators works well, don't know why but it looks that Google DKIM validation fails too (just send mail to any Gmail adrress and you will get report to mail according to your DMARC configuration)
- checktls.com
- Test connection to your SMTP port
- Fill your
domain.tld
(eg.example.com
) to the field
- Google Postmaster tools
- Fill your
domain.tld
(eg.example.com
) to the domain field - Fill
mail
to DKIM selector field - Doesn't work for me from unknown reason
- Fill your
- Google Toolbox
- Mail troubleshooting
- Test via OpenSSL
-
Create file
host_vars/server1.example.com.yml
encrypted byansible-vault
first.# ansible-vault edit host_vars/server1.example.com.yml mail_accounts: - username: user1 domain: example.com password: aaaaa aliases: - admin@example.com - abuse@example.com restrict: [] - username: no-reply domain: example.com password: bbbbb aliases: [] restrict: - receive
-
Create file
vault-pass.txt
with your Ansible Vault (NOTE: You should add this file to.gitignore
to prevent leak of sensitive data!)echo 'my-secret-vault-password' > vault-pass.txt
-
Set up Ansible with ansible.cfg
$ cat > ansible.cfg <<EOF [defaults] vault_password_file = vault-pass.txt EOF
-
Variable
mail_accounts
is then available in the role for hostserver1.example.com
.--- - name: More complex installation hosts: server1.example.com roles: - role: hmlkao.docker_mailserver vars: mail_domains: - server1.example.com <-- my MX server - mail.example.com <-- pretty name for email clients mail_cert_email: my-mail@somewhere.com <-- notification mail for Let's Encrypt
Suppose your mail server is running on domain server1.example.com
and we have some pretty CNAME like mail.example.com
which points to our mail server and account with username user1
is created.
Version: 3.28.5-0ubuntu0.18.04.1
- Edit > Accounts
- Add "Mail Account"
- Identity
- Email Address:
user1@example.com
- Email Address:
- Receiving Email
- Server Type: IMAP
- Server:
mail.example.com
- Username:
user1@example.com
- Encryption method: TLS on dedicated port
- Port should change to 993
- Authentication: Password
- Sending Email
- Server Type: SMTP
- Server:
mail.example.com
- Port: 587
- Check "Server requires authentication"
- Encryption method: STARTTLS after connecting
- Authentication:
- Type: Login
- Username:
user1@example.com
Version: 2020.03.01.300951155.release
- Add another account
- Other
- Fill your email > Manual setup
- What type of account is this?: Personal (IMAP)
- Fill your password > Next
- Server:
mail.example.com
- IMAP port: 465 (SSL/TLS)
- Outgoing server
- Server:
mail.example.com
- Server:
You would be able to receive/send mails now.
Version: 15.0 (3693.40.0.1.81) / 2022-02-14
- Choose a Mail account provider... > Other Mail Account...
- Fill
- Name: < your name >
- Email address: < the whole email address >
- Password: < password to your mail account >
- When is error message shown
- Choose "IMAP"
- Fill address of your mail server > according to MX record
- Sign in
TBD
TBD
There are published only three ports
- TCP/25 - SMTP port for receiving emails from other SMTP servers
- TCP/587 - SMTP Submission port for sending emails from clients
- TCP/993 - IMAP port for downloading emails to clients
Docker container named mail-server
is configured to always restart even after server boot.
All data (mail data, certificates, configuration) are stored on the host in folder defined in Ansible variable mail_persist_folder
.
TLS certificates are issued by Let's Encrypt issuer by certbot/certbot
Docker image according to these instructions.
This role creates systemd
renew service and timer which will run the service once per day. No cronjob configuration needed.
They are generated directly to file postfix-accounts.cf
according to these instructions.
You can see what happen in Docker logs on host
docker logs mail-server
When you found some bug in the role create an issue on GitHub please.
- RSA sign and verify using Openssl : Behind the scene
- Interesting article about how RSA signing (used by DKIM) works
All helping hands are appreciated. Check CONTRIBUTING.md
-
$ cat ~/.ansible.cfg [galaxy] server_list = beta [galaxy_server.beta] url = https://beta-galaxy.ansible.com/api/ token = <token>
-
(first use) Create Ansible Galaxy metadata
- Creates folder
<namespace>.<collection>
ansible-galaxy collection init hmlkao.docker_mailserver
- Creates folder
-
Build collection package
- Creates tarball with
tar.gz
extension
ansible-galaxy collection build
- Creates tarball with
-
Upload Collection
ansible-galaxy collection publish ./hmlkao-docker_mailserver-<version>.tar.gz