概要
docker-postfixを使用してDockerのコンテナ内リンク(またはローカルネットワークやVPN)からの送信専用SMTPリレー(SMTPサーバ)を構築した際のメモ。
作者公式Dockerイメージをdocker-composeでハンドリングしてDKIMに対応させる。自身の用途としてはdocker-composeで構築したオンプレアプリ類からユーザーへのメール配信用。
なお、実績のないドメインからのメールはSPFもDKIMも関係なく問答無用で迷惑メール扱いされるのが普通で、アカウント云々の文言が含まれる場合は尚更である。ユーザーへの念押しは必須。
※RHEL8互換環境を想定、それ以外の場合は必要に応じて読み替えのこと
DKIM
docker-postfixではDKIMはoptionalのため、鍵は自分で用意する必要がある。今回はOpenDKIMを使用し、ホスト上で鍵を作成してvolumesでマウントする。
パッケージのインストール
DKIM鍵を生成するためにホストにOpenDKIMと依存パッケージをインストールする。
dnf install -y opendkim opendkim-tools
- OpenDKIMはEPELに収録されている
鍵の生成
mkdir -p /etc/opendkim/keys/<DOMAIN>
opendkim-genkey -b 2048 -d <DOMAIN> -D /etc/opendkim/keys/<DOMAIN> -s <SELECTOR> -v
-
<DOMAIN>は使用するドメイン名(exmaple.com等) -
<SELECTOR>はDKIM鍵の識別名のようなもの(例えばmail等)- 指定しないと
defaultになる
- 指定しないと
- 実行すると秘密鍵が
/etc/opendkim/keys/<DOMAIN>/<SELECTOR>.privateに生成され、TXTレコードの内容が/etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txtに出力される
DNS
DKIMレコード
出力された /etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txt を元にDNSにDKIMレコードを追加する。OpenDKIMが出力するテキストはzoneファイルの書式のためbindならそのまま使える。
<SELECTOR>._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIB......"
- Type: TXT
- Name:
<SELECTOR>._domainkey - Value:
v=DKIM1; k=rsa; p=MIIB......-
/etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txtの二重引用符の中身を連結したもの
-
- TTL: 適当
SPFレコード
わかりやすい解説が大量にあるため検索して参照のこと。
<DOMAIN>. IN TXT "v=spf1 +ip4:<GLOBAL_IP>/32 -all"
- 修飾子
+-~?はその条件に一致した場合の扱いを規定する-
+: 認証する(省略可)/-: 認証しない/~: 認証しないが受信推奨/?: 認証の有無を評価しない
-
- よって設定した条件以外で送る可能性が全くない場合、allディレクティブの修飾子は
~ではなく厳格な-の方がより安全
Composeファイル
environmentの項目はdocker-postfixのreadmeを参照のこと。
コンテナ間リンク用設定例
version: '3.8'
services:
smtp:
image: panubo/postfix:latest
container_name: smtp
hostname: smtp-server
environment:
- MAILNAME=<DOMAIN>
- TZ=Asia/Toyo
- USE_TLS=no
- USE_DKIM=yes
- DKIM_KEYFILE=/etc/opendkim/keys/<DOMAIN>/<SELECTOR>.private
- DKIM_SELECTOR=<SELECTOR>
expose:
#- '25'
- '587'
volumes:
- /etc/opendkim:/etc/opendkim
networks:
- container-link
logging:
options:
max-size: "10m"
max-file: "3"
networks:
default:
external:
name: bridge
container-link:
name: docker.internal
- 各コンテナで指定するSMTPサーバのアドレスはdocker-postfixコンテナのhostnameと待ち受けポートになる
- この設定例では
smtp-server:587を指定することになる
- この設定例では
- 許可するIP範囲は明示的に指定しないと
127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16に設定される- コンテナ間リンクで使用する場合はそのままでOKと思われる
- TLSは標準でON(
USE_TLS=yes)のため、不要なら明示的に切る必要がある- コンテナ間リンク内で閉じているなら不要と思われる
- DKIMを有効化し、先の手順で作成したDKIM鍵をマウントして使用する
- コンテナ間リンクに明示的に命名したbridgeネットワークを使用している
- 立てたSMTPサーバを使用するコンテナはこのネットワークに繋げること
- 当然ながらメールにはSMTPのチェーンの始点となる送信元コンテナのhostnameとIPが記載される
- 内部アクセス専用のため認証はない
その他設定例
ローカルIP 10.0.0.1 のアダプタ上でIPアドレス範囲 10.0.0.0/24 からのアクセスのみ待ち受ける
environment:
- MYNETWORKS=10.0.0.0/24
ports:
- '10.0.0.1:587:587'
TLSの使用を強制し、Let's Encryptの証明書と鍵を使用(使用するドメインで繋がるようにしておく必要がある)
environment:
- USE_TLS=yes
- TLS_SECURITY_LEVEL=encrypt
- TLS_KEY=/etc/letsencrypt/live/<DOMAIN>/privkey.pem
- TLS_CRT=/etc/letsencrypt/live/<DOMAIN>/fullchain.pem
volumes:
- /etc/letsencrypt:/etc/letsencrypt
実際のヘッダー
Gmailに送ったもの。
-
s=mailは<SELECTOR>のこと -
Receivedに送信元コンテナのホスト名とIPが入っている


