暑假的时候见识了Vestacp,用它可以方便快捷的搭建一个邮局。但是邮局经常崩,常收不到邮件。寒假了就折腾了一下Docker。
PS(2017.2.13更新):将近一个月了,期间收了已经有上百封邮件。我用uptime robot检测的还没有一例宕机事故,监控页面在这里。docker容器的稳定性是有目共睹的。
一、基础知识
1.常见邮局端口&&协议:
发邮件的协议有SMTP,收邮件的协议有POP3和IMAP。
- SMTP:明文使用25端口。加密后使用25/587/465端口。
- IMAP:明文使用143端口。加密后使用143/993端口。
- POP3:明文使用110端口。加密后使用110/995端口。
2.常见邮局软件和安全软件:
- sendmail:用于发邮件。资格最老的邮局,所有Linux发行版基本都带。但是配置麻烦。
- postfix:Wietse Venema觉得sendmail配置太麻烦了,就开发了一个“简化配置版sendmail”,即postfix。支持smtp协议。
- dovecot:用于收邮件,支持imap/pop3。
- spamassasin:垃圾邮件过滤器。可以自订规则。
- clamav:邮件杀毒工具。
- opendkim:生成dkim签名。有什么用?详见下面的“反垃圾邮件技术”。
- fail2ban:防止别人暴力破解用户名密码的工具。
3.反垃圾邮件技术:
假设我要在1.1.1.2这台机器上配置best.pm、best.nl这两个域名用于发邮件。1.1.1.2的主机名是mail1.wangchenyu.net.cn。那么我们需要
- 设置rDNS,将1.1.1.2映射到mail1.wangchenyu.net.cn。DNS是域名->IP的解析。rDNS即IP->域名的解析。有了这个rDNS记录,收到邮件的服务器就能确认mail1.wangchenyu.net.cn可以被用在1.1.1.2这个IP上。一般在主机商后台可以添加rdns记录,找不到的话提交一个工单即可。
- 设置best.pm和best.nl的MX记录,记录名为@,值为mail1.wangchenyu.net.cn,优先级为10。MX记录用于别人向best.pm这个域发送邮件时查找收信服务器。不设置的话无法收到别人发的邮件,并且自己发出的邮件的“可信度”也会大大降低。优先级
- 设置DKIM签名。DKIM先由发件服务器生成,之后每封邮件都会带上这个签名。接着,还要在best.pm和best.nl上各添加一条TXT记录,记录名和值在发件服务器生成DKIM时都会提供。收到邮件后会对比邮件中的DKIM签名和DNS中的TXT记录是否一致。
- 设置SPF记录。这个记录规定了可以用这个域发邮件的主机。在best.pm和best.nl上各添加一条TXT记录,记录名为
@
,值为v=spf1 mx ~all
即可允许所有IP使用此域。 - 设置DMARC记录。这个记录指出他们的地址被 SPF 和/或 DKIM/或别的方法保护。在best.pm和best.nl上各添加一条TXT记录,记录名为
_dmarc
,值为v=DMARC1; p=none
二、操作步骤
这里我选择了一个Github上的docker-mailserver。正如介绍中所言,它的功能齐全,配置简单,并且不需要*sql数据库。部署和升级都相对简单得多。在服务器上安装docker和docker-compose。
1.参照着上面给的说明,首先拉取镜像:
docker pull tvial/docker-mailserver:latest
|
2.创建docker-compose.yml
version: '2'
services:
mail:
image: tvial/docker-mailserver:2.1
hostname: mail1
domainname: wangchenyu.net.cn
container_name: mail
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
volumes:
- /home/mail:/var/mail
- /home/mail-state:/var/mail-state
- /root/config/:/tmp/docker-mailserver/
- /etc/letsencrypt:/etc/letsencrypt
environment:
- ENABLE_SPAMASSASSIN=0
- ENABLE_CLAMAV=0
- ENABLE_FAIL2BAN=1
- ONE_DIR=1
- DMS_DEBUG=0
- SSL_TYPE=letsencrypt
cap_add:
- NET_ADMIN
3.添加邮件账户:
mkdir -p /root/config
| |
touch /root/config/postfix-accounts.cf
| |
docker run --rm \
| |
-e MAIL_USER=user1@best.pm \
| |
-e MAIL_PASS=mypassword \
| |
-ti tvial/docker-mailserver:latest \
| |
/bin/sh -c
'echo "$MAIL_USER|$(doveadm pw -s SHA512-CRYPT -u $MAIL_USER -p $MAIL_PASS)"' >> /root/config/postfix-accounts.cf
|
如果有多个邮箱账户,则多次执行上面的docker run
语句就行。
4.创建DKIM key:
docker run --rm \
| |
-v
"/root/config":/tmp/docker-mailserver \
| |
-ti tvial/docker-mailserver:latest generate-dkim-config
|
执行完之后查看/root/config/opendkim/keys/best.pm/mail.txt
的内容就是我们要设置的dns解析。我的内容是:
cat /root/config/opendkim/keys/best.pm/mail.txt
| |
mail._domainkey IN TXT (
"v=DKIM1; k=rsa; "
| |
"p=MIGfMA0GCSqGSIb3DPENNNNNNNNNNCBiQKBgQCy9JV3FnXjLjsRJs/N0fy1C233333IV7t3f7fWpv/lo4NsoPEtG693hTgApkhuLl9KeV233333DMTagtXN898lXenKFEIS4COi7X/RjbGuOoApg4qS23333333TfXsrjN3xVC78E9T/HrS6pJN5fX+1s+1s+1s+1s+1s+1sIDAQAB" ) ; ----- DKIM key mail
for best.pm
|
如果是自己搭建的bind,直接把这段塞进域名的hosts文件就行。如果使用的是第三方解析,就去后台添加一条TXT记录,记录名是mail._domainkey,记录值是将两段引号内的字符串拼接起来即可,如我的就是:
v=DKIM1; k=rsa;p=MIGfMA0GCSqGSIb3DPENNNNNNNNNNCBiQKBgQCy9JV3FnXjLjsRJs/N0fy1C233333IV7t3f7fWpv/lo4NsoPEtG693hTgApkhuLl9KeV233333DMTagtXN898lXenKFEIS4COi7X/RjbGuOoApg4qS23333333TfXsrjN3xVC78E9T/HrS6pJN5fX+1s+1s+1s+1s+1s+1sIDAQAB
|
5.申请letsencrypt证书并自动续费:
非CentOS请参考certbot.eff.org。
安装certbot工具:
sudo yum install -y certbot
|
确保将mail1.wangchenyu.net.cn解析到了1.1.1.2,然后执行:
certbot certonly --standalone -d mail1.wangchenyu.net.cn
|
即可申请到mail1.wangchenyu.net.cn的证书,申请后证书就放在
/etc/letsencrypt/live/mail1.wangchenyu.net.cn
下,其中
fullchain.pem
是机构证书+域名证书chain.pem
是机构证书cert.pem
是域名证书privkey.pem
是域名私钥
因为上面的docker-compose.yml
中已经把/etc/letsencrypt
映射到了容器中所以到这里就完成了证书的工作。
输入crontab -e
打开定时任务设置面板,然后按i进入编辑模式,粘贴进这段代码即可每周一凌晨5点0分给证书续期:
0 5 * * 1 /usr/bin/certbot renew --quiet
到这里已经万事大吉了。
如何检测SSL配置是否成功?
参照https://github.com/tomav/docker-mailserver/wiki/Configure-SSL,
启动容器后运行:
docker
exec mail openssl s_client -connect 0.0.0.0:587 -starttls smtp -CApath /etc/letsencrypt/
|
和
docker
exec mail openssl s_client -connect 0.0.0.0:993 -starttls imap -CApath /etc/letsencrypt/
|
看到这个说明成功了:
Verify return code: 0 (ok)
6.启动容器:
执行下列命令即可:
docker-compose up -d mail
|
三、客户端配置
服务器配置好了,如何连接?
在任一个邮件客户端中这么配置:
收信:
- 服务器地址:
mail1.wangchenyu.net.cn
- 协议:
IMAP
- 端口:
993
- 用户名:
user1@best.pm
- 密码:
mypassword
- 使用SSL:是
发信:
- 服务器地址:
mail1.wangchenyu.net.cn
- 协议:
SMTP
- 端口:
587
- 用户名密码同上
- 使用SSL:是
Enjoy it!