緣由
原本就有一台 postfix, 採用 apt 套件安裝 (之後再改成 docker container), 想要幾個目的
1. 為吉甲資訊, gilgal.tw 建立 mail server
2. 為 postfix 建立 virtual user 和 mailbox
3. 需建立 POP3/IMAP 服務
4. 整合 Let’s Encrypt 提供 SMTP(25, 465, 587), POP3(995), IMAP(993)
5. 因無 PTR 紀錄, 無法自動轉寄信件到 gmail, 所以採用 gmail + pop3 取信
6. 整合 LDAP 帳號供 gmail 取信用, 並不能使用原帳密, 另外再做一個類似 service account 的帳號供 gmail 使用
以下紀錄說明重要的步驟
幾個重要設定
- 調整 DNS RR
@ IN A IP1
@ IN MX 0 mx.gilgal.tw.
www IN A IP1
mail IN A IP2
mx IN A IP2
pop3 IN A IP1
imap IN A IP1
smtp IN A IP1
其中 IP1 提供 HTTP/HTTPS 供 Let’s Encrypt 申請 SSL 憑證用
IP2 則提供 SMTPs, POP3s, IMAPs 服務
- 利用 certbot 取得 SSL 憑證
# dry run 確認是否有問題, 若沒有問題, 則移除 --dry-run 並再執行一次
certbot certonly --dry-run --email cytseng@gmail.com --agree-tos -d pop3.gilgal.tw -d imap.gilgal.tw -d mx.gilgal.tw -d smtp.gilgal.tw -w /srv/web --manual
並把 fullchain.pem 和 privkey.pem 複製到 /etc/postfix/ssl 之下
因 30天需要更新 Let’s Encrypt SSL 憑證, 所以寫了一個小小的 script 判斷
- 自動更新 Let’s Encrypt SSL 憑證
/usr/local/sbin/renew_postfix_ssl.sh 內容如下
#!/bin/sh
BASEDIR='/etc/postfix/ssl'
# 產生憑證 checksum 檔
CERT_CHECK=`cat BASEDIR/fullchain.checksum 2>/dev/null`
KEY_CHECK=`catBASEDIR/privkey.checksum 2>/dev/null`
if [ "x{CERT_CHECK}" != "x`md5sum /etc/certbot/etc/live/pop3.gilgal.tw/fullchain.pem | awk '{print1}'`" ]; then
echo `md5sum /etc/certbot/etc/live/pop3.gilgal.tw/fullchain.pem | awk '{print 1}'`>BASEDIR/fullchain.checksum
cp /etc/certbot/etc/live/pop3.gilgal.tw/fullchain.pem BASEDIR
fi
if [ "x{KEY_CHECK}" != "x`md5sum /etc/certbot/etc/live/pop3.gilgal.tw/privkey.pem | awk '{print 1}'`" ]; then
echo `md5sum /etc/certbot/etc/live/pop3.gilgal.tw/privkey.pem | awk '{print1}'` > BASEDIR/privkey.checksum
cp /etc/certbot/etc/live/pop3.gilgal.tw/privkey.pemBASEDIR
else
exit
fi
postfix reload
/etc/cron.d/local
10 0 * * * root /bin/sh /usr/local/sbin/renew_postfix_ssl.sh > /dev/null 2>&1
- 安裝 docker, 並調整 daemon.json 設定
參考以下文章
Install Docker Engine on Debian
調整 docker 基本設定
- 建立 postfix virtual user 專用帳號
為讓此帳號能和 container 裡的帳號對應, 所以 uid/gid 調整為 1001000
groupadd -g 1001000 virtualmail
useradd -u 1001000 -g virtualmail -s /usr/bin/nologin -d /var/mail/vhosts -m virtualmail
- 修改 postfix 以支援 virtual domain 和 virtual user
# 讓 postfix 不再支援舊設定
compatibility_level = 3.6
smtpd_tls_cert_file=/etc/postfix/ssl/fullchain.pem
smtpd_tls_key_file=/etc/postfix/ssl/privkey.pem
myhostname = mail
mydomain = gilgal.tw
# 要放 virtual domain 的網域, 則不能放在 mydestination
# 因 mydestination 屬於處理未在 virtual domain 的 email
# virtual_mailbox_domains 則處理 virtual domain 的 email
mydestination = localhost.localdomain, localhost
virtual_mailbox_domains = gilgal.tw, mail.gilgal.tw
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 1000
virtual_uid_maps = static:1001000
virtual_gid_maps = static:1001000
- 新增 vmailbox 檔案, 設定 virtual user mailbox
/etc/postfix/vmailbox 內容
joshua@gilgal.tw cytseng/
joshua@mail.gilgal.tw cytseng/
service@gilgal.tw cytseng/
service@mail.gilgal.tw cytseng/
postmap /etc/postfix/vmailbox
其中 cytseng/ 為 maildir 格式, 會在 /var/mail/vhosts/cytseng
裡產生這樣的目錄結果
.
├── cur
├── new
└── tmp
若為 cytseng 則為 mailbox 格式, 則會在 /var/mail/vhosts/cytseng
用一個 cytseng
檔案放置所有的 mail 資料
因吉甲會用到的 mail 都只有自己在用, 所以都轉到自己帳號(cytseng) 之下
會用 cytseng/
也是為了配合 LDAP 帳號為 cytseng
- 利用 dovecot docker image 建立 POP3s/IMAPs 服務, 並和 LDAP 連結取得帳號資訊
/srv/docker/dovecot/docker-compose.yaml 內容
services:
dovecot:
image: dovecot/dovecot
container_name: dovecot
hostname: dovecot
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/certbot:/certbot
- ./etc-dovecot:/etc/dovecot
- /var/mail/vhosts:/srv/mail
- /srv/prod/dovecot/log:/log
ports:
- 993:993/tcp
- 995:995/tcp
etc-dovecot/dovecot.conf 內容
mail_home=/srv/mail/%n
mail_location=maildir:/srv/mail/%n
mail_uid=1000
mail_gid=1000
protocols = imap pop3
first_valid_uid = 1000
last_valid_uid = 1099
passdb {
args = /etc/dovecot/dovecot-ldap.conf.ext
driver = ldap
}
userdb {
driver = prefetch
}
userdb {
args = /etc/dovecot/dovecot-ldap.conf.ext
driver = ldap
}
ssl=yes
ssl_cert=</certbot/etc/live/pop3.gilgal.tw/fullchain.pem
ssl_key=</certbot/etc/live/pop3.gilgal.tw/privkey.pem
namespace {
inbox = yes
separator = /
}
service lmtp {
inet_listener {
port = 24
}
}
listen = *
log_path=/log/dovecot.log
info_log_path=/log/dovecot-info.log
debug_log_path=/log/dovecot-debug.log
auth_verbose=yes
auth_debug=yes
mail_debug=yes
verbose_ssl=yes
!include_try /etc/dovecot/conf.d/*.conf
etc-dovecot/dovecot-ldap.conf.ext 內容
hosts = LDAP IP
dn = 'BIND DN'
dnpass = 'BIND PWD'
base = BASEDN
pass_attrs = \
=password=%{ldap:userPassword}, \
=user=%{ldap:cn}, \
=home=%{ldap:homeDirectory}, \
=uid=%{ldap:uidNumber}, \
=gid=%{ldap:gidNumber}
pass_filter = (&(objectclass=user)(cn=%u))
user_filter = (&(objectclass=user)(cn=%u))
# For using doveadm -A:
iterate_attrs = =user=%{ldap:cn}
iterate_filter = (objectClass=user)
LDAP 設定幾乎都是客製, 其中 base 不要和常用帳號的 basedn 相同, 避免常用帳號的密碼被猜出來, 而能登入工作站或其他服務
- 啟動 postfix / dovecot
postfix reload
docker-compose -f /srv/docker/dovecot/docker-compose up -d
這樣就能完成 POP3s/IMAPs 服務
- 調整 gmail 帳號, 利用 POP3 取用
吉甲信箱
TODO
- 讓 postfix 能使用 LDAP 認證
- 確認 DNS PTR 結果, 之後改用自動轉寄至 gmail
參考文件
- LDAP Authentication (ldap)
- LDAP Settings for auth
- LDAP Backend Configuration
- Virtual user mail system with Postfix, Dovecot and Roundcube
- Setting your Postfix self-hosted mail server up for multiple domains
- How to Set Up Postfix to Use Virtual Mailboxes on Ubuntu 20.04
–Postfix: which option for multiple domains and multiple users? - 在 Postfix/Dovecot 郵件伺服器上安裝並設定 SSL
- Dovecot Core Settings