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.user1domain- part of email after "@", eg.example.compassword- user password in plaintextaliases- list of aliases, each alias must be full emailrestrict- list of restrictions, may besendfor suppress mail sending orreceivefor suppress mail receiving
mail_accounts:
- username: user1
domain: example.com
password: aaaaa
aliases:
- [email protected]
- [email protected]
restrict: []Install this Ansible role within the context of playbook
ansible-galaxy install hmlkao.docker_mailserverThen 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:
- [email protected]
- [email protected]
restrict: []
- username: no-reply
domain: example.com
password: bbbbb
aliases: []
restrict:
- receive
mail_domains:
- server1.example.com
mail_cert_email: [email protected]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_foldervariable in fileconfig/opendkim/keys/<domain.tld>/mail.txton 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"
mailis DKIM selector, not subdomain so there have to bemail._domainkeyfor all, NOserver1._domainkeyor 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:[email protected]; ruf=mailto:[email protected]; 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
- [email protected]
- 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 [email protected] 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
mailto 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.ymlencrypted byansible-vaultfirst.# ansible-vault edit host_vars/server1.example.com.yml mail_accounts: - username: user1 domain: example.com password: aaaaa aliases: - [email protected] - [email protected] restrict: [] - username: no-reply domain: example.com password: bbbbb aliases: [] restrict: - receive
-
Create file
vault-pass.txtwith your Ansible Vault (NOTE: You should add this file to.gitignoreto 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_accountsis 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: [email protected] <-- 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:
[email protected]
- Email Address:
- Receiving Email
- Server Type: IMAP
- Server:
mail.example.com - Username:
[email protected] - 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:
[email protected]
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-serverWhen 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.gzextension
ansible-galaxy collection build
- Creates tarball with
-
Upload Collection
ansible-galaxy collection publish ./hmlkao-docker_mailserver-<version>.tar.gz