メール鯖をDockerへ移行した
神か?
2024/06/09: v14版に更新(微修正、基本は変更なし)
2024/06/20: SPF, DKIM, DMARCの設定方法を追加
超参考
以前構築した記事
定義
- Host:
mail
- Domain:
sample.com
- MailUser:
user1
- SSL/TLS証明書:
/mnt/certificate/{cert,privkey}.pem
- RelayHost:
mail.so-net.ne.jp
- RelayHostPort:
587
- RelayHostUser:
hogehoge@aa.so-net.ne.jp
- RelayHostPass:
hogegenoge
構築
DMS_GITHUB_URL='https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master'
wget "${DMS_GITHUB_URL}/docker-compose.yml"
wget "${DMS_GITHUB_URL}/mailserver.env"
wget "${DMS_GITHUB_URL}/setup.sh"
chmod a+x ./setup.sh
docker-compose.yml
version: '3.8'
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
hostname: mail.sample.com
env_file: mailserver.env
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS)
#- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
#- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
#- "110:110" # POP3
- "995:995" # POP3 (with TLS)
volumes:
- ./docker-data/dms/mail-data/:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
- /mnt/certificate:/mnt/ssl:ro
restart: always
stop_grace_period: 1m
cap_add:
- NET_ADMIN
healthcheck:
test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
timeout: 3s
retries: 0
logging:
options:
max-size: 1m
max-file: '3'
diff mailserver.env
diff -u mailserver.env.orig mailserver.env | grep ^+
変更分のみ。
+POSTMASTER_ADDRESS=user1@mail.sample.com
+TZ=Asia/Tokyo
+ENABLE_POP3=1
+ENABLE_FAIL2BAN=1
+SSL_TYPE=manual
+SSL_CERT_PATH=/mnt/ssl/cert.pem
+SSL_KEY_PATH=/mnt/ssl/privkey.pem
+POSTFIX_INET_PROTOCOLS=ipv4
+DEFAULT_RELAY_HOST=[mail.so-net.ne.jp]:587
+RELAY_HOST=mail.so-net.ne.jp
+RELAY_PORT=587
+RELAY_USER=hogehoge@aa.so-net.ne.jp
+RELAY_PASSWORD=hogegenoge
ハマりポイント
Postfixの基本的な設定がわかっていればハマることはほとんどないと思う。
が、一点だけクソハマったので書き残しておく。
mail postfix/trivial-rewrite[1670]: warning: do not list domain mail.sample.com in BOTH mydestination and virtual_mailbox_domains
mail postfix/smtpd[1420]: NOQUEUE: reject: RCPT from unknown[{送信元Addr}]: 550 5.1.1 <user1@mail.sample.com>: Recipient address rejected: User unknown in local recipient table; from=<{送信元メアド}> to=<user1@mail.sample.com> proto=ESMTP helo=<{送信元メアド}>
メール送信時、上記のエラーが出て「えぇ?ユーザーいるじゃん???」という頭になってしまう。
エラーにも書いてある通り、mydestination
と virtual_mailbox_domains
の中身が被っていることが原因らしい。
docker-data/dms/config/postfix-main.cf
に以下を追記すればOK
mydestination = localhost.$mydomain, localhost
このことに関する参考はこちら
Postfixの『Recipient address rejected: User unknown in local recipient table』で15分ほどハマった話
LANからはすべてのアクセスを許可する
docker-data/dms/config/postfix-main.cf
にPostfixの設定を書けばDocker内のPostfixの main.cf
の対象部分を上書いてくれる。
なにもしなければ
mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 192.168.64.2/32
になるが、LANからすべて許可したいので
mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 192.168.64.2/32 10.0.0.0/24
を追記すればOK。
初回起動時
とりあえず上記のように設定だけ済ませる。
docker-compose up [-d]
をせずにまずはメールアドレスを追加する
# メアド追加
./setup.sh email add user1@mail.sample.com
# postmasterのalias追加
./setup.sh alias add postmaster@mail.sample.com user1@mail.sample.com
# メアド確認
./setup.sh email list
# alias確認
./setup.sh alias list
これをすることで user1@mail.sample.com
が追加され、postmaster@mail.sample.com
にきたものを前者に転送することができる。
./setup.sh alias add postmaster user1@mail.sample.com
というように@以降を省略もできるのだがうまく動作しなかったためフルで書くべき。
ちなみに postmaster
は email add
しなくて良い。(すると転送されない)
たったこれだけで完璧なメール鯖を構築できる。
Docker様様や。
おわり
これで無事に送受信ができることを確認した。
4時間もかかってしまった…
2024/06/20 追記
SPF, DKIM, DMARCについて追記
基本的には公式ドキュメントを見ればOK
ただサブドメインで運用する場合にはかなり躓きやすいので書いておく。
SPF
SPFはFQDN単位で有効なため、今回のようにサブドメインで運用する場合は注意
$ dig mail.sample.com txt +short
"v=spf1 mx ~all"
また、今回のように RelayHost に mail.so-net.ne.jp
を設定している場合、そこからメールが送信される扱いになるため以下のようにする。
なお mail.so-net.ne.jp
のSPFレコードは so-net.ne.jp
にあった。
$ dig mail.sample.com txt +short
"v=spf1 include:so-net.ne.jp ~all"
DKIM
DKIMもFQDN単位で有効なため注意
# 鍵作成
$ ./setup.sh config dkim
# 公開鍵確認
$ sudo cat docker-data/dms/config/opendkim/keys/mail.sample.com/mail.txt
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=abcde"
"fghijk" ) ; ----- DKIM key mail for mail.sample.com
# コンテナ再起動
# これをしないと送信されるメールに署名が付かない
$ docker compose down && docker compose up -d
# DNS設定
# わかりづらいが <selector>._domainkey.<FQDN> という感じ
# 設定する際は " を除去してBase64は空白を空けず繋げる
$ dig mail._domainkey.mail.sample.com txt +short
"v=DKIM1; h=sha256; k=rsa; p=abcdefghijk"
DMARC
DMARCはルートから継承される
$ dig _dmarc.sample.com txt +short
"v=DMARC1; p=none; sp=none; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400; rua=mailto:dmarc.report@mail.sample.com; ruf=mailto:dmarc.report@mail.sample.com"
メールの疎通を確認でき、厳しく取り扱ってほしくなったら
p=quarantine
sp=quarantine
にする。