In this tutorial we'll walk through the whole process of setting up a fully functionally email server on your VPS/dedicated server/what-ever-server-you-have.
Tools needed:
- Docker
- Docker-composer
- DNS management system.
- You
Install docker
The official installation guide is here:
https://docs.docker.com/engine/install/
Take a look.
Install Docker composer
Docker composer is an official tool that builds up a series containers with a docker-composer.yaml
file that describes that way they should interact.
Full description comes here: https://docs.docker.com/compose/install/
Basically, you get it by running:
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
A mail system on docker
We chose docker-mailserver. It is a very simplistic yet fully functional mailserver comprised of several time-proofed softwares such as
- postfix (as smtp)
- fail2ban (as anti-hack)
- Dovecot (as imap)
- AutoDKIM (as authenticator) and etc.
Follow the instructions on its github page. As of the day I wrote this blog, the installation commands are:
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/mailserver.env
curl -o .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/compose.env
chmod a+x ./setup.sh
There are tons of environment variables to fiddle with, among all the env variables, some of them are that we are going to emphases.
TLS
If you already have your long-term tls cert, you're welcome to go here and follow the simple steps there.
To obtain a free cert, we need Let's encrypt certbot. However, certbot will occupy the 80 and 443 ports when renew and does nothing after that, which breaks our normal website. There is another alternative thing exists that also utilize the official certbot by only placing challenge files in a folder so we can use existing nginx/apache/xxx to complete the challenge. It's called letsencrypt-auto
Assuming the place of our letsencrypt installation to be /data/mail/letsencrypt
and nginx www root to be /data/wwwroot/www
, this is the finally command to start a cert docker:
docker run --name auto-letsencrypt -d \
-e 'DOMAINS=YOUR_MAIL_DOMAIN' \
-e EMAIL=something@somedomain.com \
-e CHECK_FREQ=15 \
-v /data/mail/letsencrypt:/etc/letsencrypt \
-v /data/mail/lib/letsencrypt:/var/lib/letsencrypt \
-v /data/wwwroot/www:/var/www \
gordonchan/auto-letsencrypt
Do remember to point your dns to your vps ip before that.
Now we have a working cert in folder /data/mail/letsencrypt/etc/live/your-domain/
, open mailserver.env
and set SSL_TYPE
to letsencrypt
.
DNS
After you changed some env variables as needed, it's time to bring the mail-server to life.
docker-compose up mail -d
Now you can connect to your mail-server with your favorite client. But unfortunately, the mails you sent out this way are likely to be rejected or filtered, cuz you're not trusted and are very likely to be a spammer to the receiver. We need to authenticate ourselves, by DNS records and there is a lot to set.
DKIM
First, let's sign our mail with DKIM../setup.sh config dkim
to generate a new key pair, a new key pair should then be stored on /data/mail/config/opendkim/keys/yourdomain/, download mail.txt
from this folder.
Open the text file, it should contains something like:
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=SOME DATA"
"SOME OTHER DATA" ) ; ----- DKIM key mail for your.domain
If your dns provider supports large txt record, set a txt record with all text concatenated, if not, like oracle dns, there is a button called add additional text
which allows you to append another 256 long text to the record, use that to complete the record. Or you may like to migrate to another provider that supports it.
SPF
SPF aka. Sender policy frame describes which domain and ip is qualified to send out mails on behalf of the email address.
There are two parts that need to be set: the domain
@ TXT "v=spf1 include:your.mail.server.domain include:other.domains.that.allowed.to.send ~all"
and the ip that qualified to call itself "your.domain"
your.mail.server.domain TXT "v=spf1 ip4:your.server.ip -all"
DMARC
set it as
@ TXT "v=DMARC1; p=reject; rua=mailto:admin@your.domain; ruf=mailto:admin@your.domain; adkim=s; aspf=s"
MX
Last but not least, if you want to receive mails with your mail-server instead of just a simple send machine (forwarding received mails to other well-known providers like gmail with email forwarder is well implemented), don't forget to set your mail server as the MX record.
@ MX 10 your.mail.server.domain
Note: MX record can't point to CNAME record. It must be an A or AAAA record.
Caveats
The composed mail container can be stopped or restarted, but please don't send SIGHUP to it.
This whole service is guarded with supervisor but supervisor is not capable of correctly killing all the child processes on restart.
A tail
command spawned by mail-server on start will be left alive with no parent process on supervisor restart and stuck in a dead loop that eats up all your CPU resouces.
So please don't try to restart the container with signal!
Now, test your spam score with https://www.mail-tester.com/.
Have fun.
0 comment