Exchange ジャーナル受信用の SMTP ゲートウェイを Azure 上に作る話
Postfix + .NET + Event Hubs + Fabric で考える最小構成
Exchange / Exchange Online のジャーナルメールを外部保管したいとき、まず必要になるのは SMTP でメールを受ける入口 です。この記事では、その入口として Postfix を使い、Azure 上にジャーナル受信用ゲートウェイを構築する考え方を整理します。Exchange Online のジャーナリングでは、ルールに一致したメッセージを、指定した SMTP アドレス宛てのジャーナル レポートとして配送できます。 (Microsoft Learn)
今回の前提は次のようなものです。
- Exchange / Exchange Online からジャーナルメールを受けたい
- 受信したメールはあとで機械処理したい
- 後続では JSON 化して Event Hubs に流したい
- 保存・分析先として Fabric を想定している
この記事では、Postfix を「受信専用の SMTP ゲートウェイ」として使う方針で進めます。Postfix は MTA であり、SMTP 受信、キュー管理、ローカル配送、外部コマンド配送といった役割を持っています。 (Postfix)
この記事で作りたい全体像
構成イメージは次のとおりです。
Exchange / Exchange Online
↓ SMTP
Azure VM (Ubuntu + Postfix)
↓
Maildir / .eml 保存
↓
.NET Worker
↓
JSON化して Event Hubs
↓
Fabric
この構成では、Postfix は受信に専念し、.NET 側が解析と連携を担当します。メール基盤とアプリケーション処理を分けておくと、障害時の切り分けや保守がかなり楽になります。Postfix のドキュメントでも、SMTP 受信、キュー、配送といった責務が分離された構成として説明されています。 (Postfix)
そもそも Postfix とは何か
初見だと、Postfix を「メールサーバー全部」と思いがちですが、実際には少し違います。
Postfix は メールを読むソフトではなく、メールを受けて次へ渡すソフトです。
役割としては次のように考えると分かりやすいです。
- SMTP でメールを受ける
- いったんキューに載せる
- ローカルへ配送する、または別の宛先へ転送する
- 必要なら外部プログラムへ渡す
つまり、Postfix は Outlook のようなメールクライアントでも、Dovecot のような IMAP サーバーでもなく、配送の中心部品です。Postfix 公式の概要と基本設定文書でも、その位置づけが明確に説明されています。 (Postfix)
Exchange ジャーナル受信で Postfix が向いている理由
Exchange Online のジャーナリングは、古くからあるコンプライアンス向け機能で、Exchange の外部にメールを保管する必要があるケースを想定しています。ジャーナル ルールでは、ジャーナル対象とジャーナル送信先 SMTP アドレスを指定できます。 (Microsoft Learn)
この用途で Postfix が向いている理由は、主に次の 3 つです。
- SMTP 受信の入口として定番であること
- 受信したメールをローカル保存にも外部処理にもつなぎやすいこと
- Linux 上で軽量に構築しやすいこと
特に 2 点目は重要で、Postfix にはローカル配送だけでなく pipe(8) による外部コマンド配送もあります。将来的に「受信したら即処理」に発展させやすいのが利点です。 (Postfix)
Azure で動かすなら何に載せるべきか
今回の用途では、Azure VM が第一候補です。
理由は単純で、やりたいことが HTTP アプリの公開ではなく、SMTP サーバーとして 25/TCP でメールを受けることだからです。Azure の NSG は受信・送信トラフィックを制御でき、受信側では Public IP 宛ての通信がプライベート IP に変換された後に NSG で評価されます。 (Microsoft Learn)
つまり、Azure 側の最小構成は次のようになります。
Exchange Online / Exchange
↓ SMTP(25)
Public IP
↓
NSG
↓
Ubuntu VM + Postfix
この形なら、SMTP 受信口としての設計が素直です。
逆に、App Service のような HTTP 前提サービスは今回の目的には合いません。
Azure で気を付けること
送信よりも、まず受信を目的にする
Azure では Outbound の SMTP 25/TCP に制限があります。Microsoft Learn の最新トラブルシュート文書でも、Azure VM から外部ドメインへの直接 SMTP 送信はサブスクリプション種別に依存し、多くのケースで制限されると案内されています。古い Azure サブスクリプションや一部 Enterprise 契約を除き、ポート 25 の直接送信は使えない場合があります。 (Microsoft Learn)
ただし、今回の主用途は ジャーナルメールの受信 です。
なので設計上は、まず
- Inbound 25/TCP を受けられること
- Postfix が正しく受信できること
- 受信後はローカル保存または内部処理へ回すこと
を優先すれば十分です。
「外部へ直接 SMTP 送信するサーバー」として作ろうとすると、Azure 特有の制約に引っかかりやすくなります。 (Microsoft Learn)
まずは .eml / Maildir 保存から始めるのがおすすめ
初回構成では、Postfix で受けたメールを いったん Maildir や .eml として保存する方式を強くおすすめします。
理由はシンプルです。
- 受信した原本を残せる
- MIME 構造を後から確認できる
- Exchange 側の問題と .NET 側の問題を切り分けやすい
- 再処理しやすい
Postfix には pipe(8) による外部コマンド配送がありますが、初回からそこまで一気にやると、権限、標準入力、重複防止、失敗時リトライなど考えることが一気に増えます。最初はローカル配送に寄せる方が堅実です。 (Postfix)
私ならこう組む
最初の Azure 構成は、次のようにします。
[Exchange / Exchange Online]
↓
[Azure Public IP]
↓
[NSGで 25/TCP を許可]
↓
[Ubuntu VM + Postfix]
↓
[/home/journal/Maildir/]
↓
[.NET Worker Service]
↓
[Azure Event Hubs]
↓
[Microsoft Fabric]
役割分担は次のように割り切ります。
- Postfix: SMTP 受信、キュー、ローカル配送
- .NET Worker: Maildir 監視、MIME 解析、JSON 化、Event Hubs 送信
- Fabric: 保存、検索、分析
この分け方にすると、メール基盤を大きくいじらずにアプリを改善できます。
Azure 上の最小リソース構成
最低限必要なのは、だいたい次のくらいです。
- Virtual Network
- Subnet
- Network Security Group
- Public IP
- Ubuntu VM
- 必要に応じて監視用の Log Analytics / Azure Monitor
NSG では、少なくとも 受信用の 25/TCP を許可します。Azure の NSG は、送信元・送信先 IP、CIDR、ポート、プロトコル単位でルールを設定できます。 (Microsoft Learn)
Postfix 側の考え方
ジャーナル受信用サーバーとしては、Postfix を 汎用メールサーバーにしない のが大事です。
つまり、社員が日常的に送受信するメールサーバーではなく、ジャーナル専用の受信口にします。
考え方としてはこうです。
- 受信アドレスをジャーナル専用にする
- 外部への中継はさせない
- 受信元をできるだけ絞る
- 受信後はローカル配送して機械処理へ回す
Postfix の基本設定では、main.cf でこのサーバーが最終受信する宛先や、許可するネットワーク、配送方式などを設定します。 (Postfix)
最小構成のイメージ
たとえば、ジャーナル送信先を次のように考えます。
journal@journal.example.com
Exchange Online 側では、ジャーナル ルールでこの SMTP アドレスを指定します。ジャーナル ルールは、対象とジャーナル受信者を定義して、ジャーナル レポートを配送する仕組みです。 (Microsoft Learn)
Postfix 側では、このアドレス宛てメールをローカルユーザー journal に配送し、Maildir に保存します。
イメージ:
journal@journal.example.com
↓
local user: journal
↓
/home/journal/Maildir/
初回は Maildir で十分
Postfix のローカル配送で Maildir/ を使う構成は分かりやすく、検証にも向いています。
この段階で確認すべきことは次の 4 点だけです。
- Postfix が起動している
- 25/TCP で受けられる
-
journal@...宛てに届く - Maildir にファイルができる
ここまで確認できれば、後段の .NET Worker は SMTP を知らなくても進められます。
その後の .NET 側の役割
Maildir に落ちたメールは、.NET Worker Service で監視して処理します。
ここでやることは、ざっくり次のとおりです。
- 新着メールファイルの検出
- MIME / ヘッダー / 添付の解析
- 監査向けに必要な項目の抽出
- JSON 化
- Event Hubs への送信
- 処理済みファイルの移動またはアーカイブ
この分離が効くのは、メール受信そのものの信頼性と、アプリ処理の柔軟性を分けて考えられるからです。
実運用に入る前に追加したいこと
最小構成で動いたあと、実運用前には次を足したいです。
- TLS の有効化
- 受信元 IP 制限
- 監視とアラート
- キュー滞留監視
- ディスク容量監視
- 重複防止
- 原本アーカイブ
- DNS と逆引きの整理
Azure 側では NSG と監視、Postfix 側ではアクセス制御や TLS を追加していく流れになります。Azure のネットワーク制御や SMTP 制限は事前に理解しておいた方が事故が少ないです。 (Microsoft Learn)
まとめ
Exchange ジャーナル受信用の基盤を Azure 上に作るなら、Postfix を Azure VM に載せた受信専用ゲートウェイとして設計するのが分かりやすいです。Exchange Online のジャーナリングは指定した SMTP アドレスへジャーナル レポートを配送でき、Postfix はその入口として適しています。Azure では Outbound 25/TCP に制限があるため、まずは 受信に特化した設計にし、受信後は Maildir や .eml 保存を経由して .NET Worker で処理する構成が現実的です。 (Microsoft Learn)
参考リンク
- Exchange Online のジャーナリング (Microsoft Learn)
- Postfix 公式ドキュメント / 基本設定 / アーキテクチャ (Postfix)
- Azure NSG の概要 (Microsoft Learn)
- Azure の outbound SMTP 25/TCP 制限 (Microsoft Learn)