2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SynologyのDockerで自宅ラボ向けSMTPリレーサーバーを構築

2
Posted at

自宅のSynology NASや自宅サーバーで動いている各種アプリ(バックアップ完了通知、監視アラートなど)から、実際にメールを送信できるようにしたい——そんな動機で、Docker上にSMTPリレーサーバーを構築しました。本記事はその構築手順と、途中でハマったポイントの記録です。

注記: ドメイン名、IPアドレス、メールアドレスなどの実際の値はすべて仮のものに置き換えています。

やりたかったこと

  • 自宅LAN内の各アプリからは認証なしでメールを投げられるようにする
  • 実際の配送は、信頼性のある外部のSMTPプロバイダ(今回は契約しているConoha WINGのSMTP)に任せる
  • 自分のドメインのメールサーバーを一から構築するような大掛かりなことはしたくない

構成としては以下のようなシンプルな中継(リレー)の形です。

[自宅サーバー/NASの各アプリ]
        │ 認証なしでSMTP送信
        ▼
[Dockerコンテナ: SMTPリレー (Postfix)]
        │ 認証ありでSMTP中継 (587番ポート)
        ▼
[外部のメールプロバイダのSMTP]
        │
        ▼
   [宛先メールボックス]

自作アプリ側の実装や設定を一切変えずに、単に「ローカルのIP:ポート宛てに投げるだけ」でメールが送れるようにするのが狙いです。

使用したイメージ

Postfixをリレー専用に軽量にラップした boky/postfix というDockerイメージを使いました。環境変数だけで「どこに中継するか」「誰からの接続を許可するか」を設定できるのが便利です。

docker-compose.ymlの作成

Synologyの /volume1/docker/smtp-relay/ のようなフォルダに、以下のような docker-compose.yml を配置しました。

version: "3.8"
services:
  smtp-relay:
    image: boky/postfix
    container_name: smtp-relay
    restart: unless-stopped
    ports:
      - "2525:25"
    environment:
      - RELAYHOST=[smtp.example-provider.jp]:587
      - RELAYHOST_USERNAME=notification@example.com
      - RELAYHOST_PASSWORD=xxxxxxxxxxxxxxxx
      - ALLOWED_SENDER_DOMAINS=example.com
      - SMTP_NETWORKS=192.168.0.0/24

ポイントは以下の3つです。

  • ports: NAS側の25番ポートが他の用途と衝突する可能性があるため、2525:25 として外部公開ポートをずらしています。LAN内の他機器からは NASのIP:2525 宛てに送信します。
  • SMTP_NETWORKS: 認証なしでリレーを許可するIPレンジです。これを自宅LANのサブネットに限定することで、誰でも使える「オープンリレー」になることを防いでいます。
  • ALLOWED_SENDER_DOMAINS: 送信元(From)として許可するドメインのホワイトリストです。

Synologyの Container Manager からGUIでプロジェクトを作成するか、SSH接続して以下のコマンドで起動しました。

cd /volume1/docker/smtp-relay
sudo docker-compose up -d

動作確認:swaksでテスト送信

SMTPのテスト送信には swaks というコマンドラインツールが便利です。NASではなく、別のLinux PC(テストを行う側の端末) にインストールします。

sudo apt update
sudo apt install swaks -y

そこから、NASのIP宛てにテストメールを送信します。

swaks --to test@example.com --from notification@example.com --server 192.168.0.10 --port 2525

250 2.0.0 Ok: queued as ... が返ってくれば、コンテナがメールを受け付けたことは確認できます。

ハマりポイント①:「受け付けた」と「届いた」は別

swaksの実行結果は成功していても、それはPostfixコンテナがメールをキューに入れたことを示しているだけで、実際に外部プロバイダへの中継が成功したかどうかは別問題でした。中継の成否は、コンテナのログを見て初めて分かります。

sudo docker logs --tail 50 smtp-relay

中継に成功していると、以下のようなログが出力されます。

postfix/smtp[...]: <キューID>: to=<宛先>, relay=<リレー先のホスト>:587, ..., status=sent (250 2.0.0 Ok: queued as ...)

もし認証エラーや接続エラーがあれば、status=deferredSASL authentication failed といった記録が残ります。「swaksが成功した」だけで安心せず、必ずログまで確認することが重要だと学びました。

なお、ログには以下のような無害な警告も出ていましたが、これはXOAUTH2用のSASLプラグイン設定ファイルが存在しないだけの警告で、通常のパスワード認証を使っている場合は無視して問題ありません。

WARNING postfix/smtp[...]: sasl-xoauth2: Unable to open config file /etc/sasl-xoauth2.conf: No such file or directory

ハマりポイント②:ドメイン制限を外そうとしたらクラッシュループに

当初、「送信元ドメインを気にせず誰でもリレーを使えるようにしたい」と考え、ALLOWED_SENDER_DOMAINS の行を丸ごとコメントアウトして再起動しました。すると、コンテナが起動してはすぐに落ち、リスタートを繰り返すという状態になってしまいました。

原因

boky/postfix イメージは、セキュリティ上の理由から ALLOWED_SENDER_DOMAINS を空のまま起動することを許可しない設計になっていました。空文字のまま起動しようとすると、起動スクリプトがエラーで即座に終了し、restart: unless-stopped の設定によって「起動→エラー終了→再起動」のループに陥っていた、というのが真相でした。

対処法(今回は不要だったが判明した解決策)

もし本当にドメイン制限なしで運用したい場合は、ALLOWED_SENDER_DOMAINS を空にするのではなく、専用の環境変数 ALLOW_EMPTY_SENDER_DOMAINS に値を設定することで、意図的に制限を外せることが分かりました。

environment:
  - ALLOW_EMPTY_SENDER_DOMAINS=true
  # ALLOWED_SENDER_DOMAINSは設定しない

ただし、この設定を使っても SMTP_NETWORKS によるIPベースの制限は別に効いているため、これだけで即座に「誰でも使えるオープンリレー」になるわけではない、という点も確認できました(mynetworks はデフォルトでプライベートIPレンジに限定されています)。

最終的な結論:そもそもリレー先の制限に引っかかっていた

上記の対処法を試す前に、根本的な原因が別にあることが分かりました。中継先である契約中のレンタルサーバーのSMTP自体が、「登録済みのドメインをFromアドレスに使っていないと送信を拒否する」という制限を持っていたのです。

つまり、ALLOWED_SENDER_DOMAINS をコンテナ側で外しても外さなくても、そもそもリレー先のSMTPサーバー側の制限によって、契約ドメイン以外のFromアドレスからは送信できない仕様でした。

最終的には、次のようにコンテナ側にも同じドメインを明示的に指定することで解決しました。

environment:
  - ALLOWED_SENDER_DOMAINS=example.com

この設定により、以下のような二重チェックの構成に落ち着いています。

  1. コンテナ側で、正しいFromドメイン以外のメールをそもそも受け付けない
  2. リレー先のSMTPプロバイダ側でも、同じドメインの制限が別途かかっている

結果として、想定外のドメインからの送信リクエストはコンテナの時点でブロックされ、無駄なリレー試行やエラーも発生しなくなりました。

まとめ

  • boky/postfix は環境変数だけでSMTPリレーを立てられて非常に手軽
  • swaksの成功メッセージは「受付成功」であって「配送成功」ではない。必ずコンテナログで status=sent を確認する
  • ALLOWED_SENDER_DOMAINS を空にすると boky/postfix はクラッシュループする。制限を外したい場合は ALLOW_EMPTY_SENDER_DOMAINS を使う
  • ただし、そもそも中継先のSMTPプロバイダ側にもFromドメインの制限がかかっている場合があるので、コンテナ側の設定だけを疑うのではなく、リレー先の仕様も確認する必要がある
  • SMTP_NETWORKS によるIPベースの制限は、オープンリレー化を防ぐ最後の砦として重要。ドメイン制限を緩めても、ここは自宅LANのサブネットに限定したまま維持するのがおすすめ

自宅ラボでの通知メール送信は地味な作業に見えて、ログをきちんと追わないと「動いているようで動いていない」状態に気づきにくい典型例でした。同じようにSMTPリレーを立てようとしている方の参考になれば幸いです。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?