1. 程式人生 > >利用Docker自建多功能加密郵件伺服器

利用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發行版基本都帶。但是配置麻煩。
  • postfixWietse 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

。那麼我們需要

  1. 設定rDNS,將1.1.1.2對映到mail1.wangchenyu.net.cn。DNS是域名->IP的解析。rDNS即IP->域名的解析。有了這個rDNS記錄,收到郵件的伺服器就能確認mail1.wangchenyu.net.cn可以被用在1.1.1.2這個IP上。一般在主機商後臺可以新增rdns記錄,找不到的話提交一個工單即可。
  2. 設定best.pm和best.nl的MX記錄,記錄名為@,值為mail1.wangchenyu.net.cn,優先順序為10。MX記錄用於別人向best.pm這個域傳送郵件時查詢收信伺服器。不設定的話無法收到別人發的郵件,並且自己發出的郵件的“可信度”也會大大降低。優先順序
  3. 設定DKIM簽名。DKIM先由發件伺服器生成,之後每封郵件都會帶上這個簽名。接著,還要在best.pm和best.nl上各新增一條TXT記錄,記錄名和值在發件伺服器生成DKIM時都會提供。收到郵件後會對比郵件中的DKIM簽名和DNS中的TXT記錄是否一致。
  4. 設定SPF記錄這個記錄規定了可以用這個域發郵件的主機。在best.pm和best.nl上各新增一條TXT記錄記錄名為@,值為v=spf1 mx ~all即可允許所有IP使用此域。
  5. 設定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
Bash

2.建立docker-compose.yml

內容參考docker-compose.yml.dist,我略做改動如下,注意hostnamedomainname,他倆最終要能拼成主機名:
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
YAML

3.新增郵件賬戶:

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
Bash

如果有多個郵箱賬戶,則多次執行上面的docker run語句就行。

4.建立DKIM key:

docker run --rm \
-v "/root/config":/tmp/docker-mailserver \
-ti tvial/docker-mailserver:latest generate-dkim-config
Bash

執行完之後檢視/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
Bash

如果是自己搭建的bind,直接把這段塞進域名的hosts檔案就行。如果使用的是第三方解析,就去後臺新增一條TXT記錄記錄名mail._domainkey記錄值兩段引號內的字串拼接起來即可,如我的就是:

v=DKIM1; k=rsa;p=MIGfMA0GCSqGSIb3DPENNNNNNNNNNCBiQKBgQCy9JV3FnXjLjsRJs/N0fy1C233333IV7t3f7fWpv/lo4NsoPEtG693hTgApkhuLl9KeV233333DMTagtXN898lXenKFEIS4COi7X/RjbGuOoApg4qS23333333TfXsrjN3xVC78E9T/HrS6pJN5fX+1s+1s+1s+1s+1s+1sIDAQAB
Bash

5.申請letsencrypt證書並自動續費:

安裝certbot工具:

sudo yum install -y certbot
Bash

確保將mail1.wangchenyu.net.cn解析到了1.1.1.2,然後執行:

certbot certonly --standalone -d mail1.wangchenyu.net.cn
Bash

即可申請到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/
Bash

docker exec mail openssl s_client -connect 0.0.0.0:993 -starttls imap -CApath /etc/letsencrypt/
Bash

看到這個說明成功了:

Verify return code: 0 (ok)

6.啟動容器:

執行下列命令即可:

docker-compose up -d mail
Bash

三、客戶端配置

伺服器配置好了,如何連線?

在任一個郵件客戶端中這麼配置:

收信:

  • 伺服器地址:mail1.wangchenyu.net.cn
  • 協議:IMAP
  • 埠:993
  • 使用者名稱:[email protected]
  • 密碼:mypassword
  • 使用SSL:是

發信:

  • 伺服器地址:mail1.wangchenyu.net.cn
  • 協議:SMTP
  • 埠:587
  • 使用者名稱密碼同上
  • 使用SSL:是

Enjoy it!