利用Docker自建多功能加密郵件伺服器
暑假的時候見識了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
內容參考docker-compose.yml.dist,我略做改動如下,注意hostname
和domainname
,他倆最終要能拼成主機名: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
YAML3.新增郵件賬戶:
mkdir -p /root/config |
touch /root/config/postfix-accounts.cf |
docker run --rm \ |
-e [email protected] \ |
-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證書並自動續費:
安裝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
- 使用者名稱:
[email protected]
- 密碼:
mypassword
- 使用SSL:是
發信:
- 伺服器地址:
mail1.wangchenyu.net.cn
- 協議:
SMTP
- 埠:
587
- 使用者名稱密碼同上
- 使用SSL:是
Enjoy it!