Postfix のサンドボックス環境をローカルに作る
この記事は「はてなエンジニア Advent Calendar 2022」の 23 日目の記事です。 昨日は id:onishi さんで はてなのエンジニア×人事の取り組み - 大西ブログ でした。
訳あって Postfix を勉強しています。
Postfix 実用ガイド などを参考に Postfix を動作させてみようと思ったのですが、インターネットを経由した場合のメールの送受信は準備や設定が大変そうでした。このため、メールの送受信などをローカルで試せる Postfix サンドボックス環境を作ってみることにしました。
サンドボックス環境の概要
- リポジトリは hiroygo/postfix-local です
- docker compose でメール送信用 Postfix コンテナとメール受信用 Postfix コンテナを起動します
- メール送信用コンテナのホスト名を
send.localhost
、メール受信用コンテナのホスト名をrecv.localhost
としてます。2 つのコンテナは共通の docker network で接続されているため、互いのコンテナを名前解決できます - メールの送信では、メール送信用コンテナ内で Postfix sendmail コマンドを実行します。これによりメールがメール送信用コンテナからメール受信用コンテナに送信されます。送信者は
root@send.localhost
で、受信者はroot@recv.localhost
です
メールを送受信してみる
make send-mail
でメールを送信して、make show-recv-mail
で受信したメールを確認できます。もし root ユーザ(root@recv.localhost
)以外に送信したい場合はユーザの追加が必要になります。ログは make log-send
、 make log-recv
で確認できます。
% make up ... % make send-mail ... % make show-recv-mail docker compose exec -it recv.localhost cat /var/spool/mail/root From root@send.localhost Sat Dec 10 08:10:53 2022 Return-Path: <root@send.localhost> X-Original-To: root@recv.localhost Delivered-To: root@recv.localhost Received: from send.localhost (unknown [172.22.0.3]) by recv.localhost (Postfix) with ESMTPS id A34C812EF3F for <root@recv.localhost>; Sat, 10 Dec 2022 08:10:53 +0000 (UTC) Received: by send.localhost (Postfix, from userid 0) id 95DFA12EF02; Sat, 10 Dec 2022 08:10:53 +0000 (UTC) From: root@send.localhost To: root@recv.localhost Subject: this is subject Message-Id: <20221210081053.95DFA12EF02@send.localhost> Date: Sat, 10 Dec 2022 08:10:53 +0000 (UTC) this is body. % make log-send docker compose logs send.localhost postfix-local-send.localhost-1 | Dec 10 08:10:29 send postfix/postfix-script[102]: starting the Postfix mail system postfix-local-send.localhost-1 | Dec 10 08:10:29 send postfix/master[103]: daemon started -- version 3.5.13, configuration /etc/postfix postfix-local-send.localhost-1 | Dec 10 08:10:53 send postfix/pickup[104]: 95DFA12EF02: uid=0 from=<root> postfix-local-send.localhost-1 | Dec 10 08:10:53 send postfix/cleanup[114]: 95DFA12EF02: message-id=<20221210081053.95DFA12EF02@send.localhost> postfix-local-send.localhost-1 | Dec 10 08:10:53 send postfix/qmgr[105]: 95DFA12EF02: from=<root@send.localhost>, size=307, nrcpt=1 (queue active) postfix-local-send.localhost-1 | Dec 10 08:10:53 send postfix/smtp[116]: 95DFA12EF02: to=<root@recv.localhost>, relay=recv.localhost[172.22.0.2]:25, delay=0.06, delays=0.01/0.02/0.02/0.01, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as A34C812EF3F) postfix-local-send.localhost-1 | Dec 10 08:10:53 send postfix/qmgr[105]: 95DFA12EF02: removed
サンドボックス環境は役に立ったか
master デーモン だけでなく、smtp や smtpd の動作やログも確認できて、勉強になりました。ただサンドボックス環境の構築が思ったより大変で、構築のために試行錯誤してたら、だいぶ Postfix の勉強ができてしまった感があります...
細かいこと
- Postfix 公式の Docker イメージはなさそうだったので、普通に apt-get install してます
- メール送信用コンテナ、メール受信用コンテナとも main.cf はほぼデフォルトです。変更点は以下を見てもらえるとわかります
recv.localhost
用の MX レコードの設定は不要です。Postfix はメール送信時、 MX レコードが無いと A レコードから、送信先を決定するっぽいです- send/run.sh
- メール送信用コンテナでは、このスクリプトから Postfix の master デーモン を起動します
- コンテナ終了時は
shutdown_handler
でシグナルを受け取りpostfix stop
で master デーモンと、その子プロセスを終了させます。master デーモンのソースコードをみた感じ、子プロセスの終了を待機してなさそうなので、スクリプト側で待機処理を入れています - Postfix は名前解決に
/var/spool/postfix/etc/resolv.conf
を使うので、Postfix 起動前に/etc/resolv.con
をコピーしています。/etc/resolv.conf
はコンテナ起動時に書き換えられるため、コンテナ起動後にコピーします。コピーではなくシンボリックリンクでもいいと思います