0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Exchange のジャーナル受信サービスを .NET / C# で作るときの現実解

0
Last updated at Posted at 2026-04-07

Exchange のジャーナル受信サービスを .NET / C# で作るときの現実解

Fabric + Event Hubs 前提なら、なぜ Postfix を挟むのか

Exchange のジャーナルを受信して、監査や分析のために別基盤へ連携したい、という要件は今でもあります。
今回の前提は、受信したジャーナルメールを .NET / C# で解析し、JSON に正規化して Azure Event Hubs に流し、その先は Microsoft Fabric で扱う、というものです。 (Microsoft Learn)

結論から書くと、この構成では Exchange → Postfix などの専用 SMTP 受信基盤 → C# 解析サービス → Event Hubs → Fabric という形がかなり現実的です。
特に Exchange Online を使う場合、ジャーナリング先に Exchange Online のメールボックスは使えません。さらに、配送失敗時に備える alternate journaling mailbox も Exchange Online のメールボックスにはできません。そのため、ジャーナルの受け口は Microsoft 365 の外側に用意する必要があります。 (Microsoft Learn)


まず押さえたい前提

Exchange のジャーナリングは、いわゆる「通常のメール転送」とは少し違います。
ジャーナリングでは、Exchange が journal report を生成し、その中に元メールを添付する形で外部へ配送します。Microsoft Learn でも、ジャーナリングは Exchange の古いコンプライアンス機能であり、Microsoft 365 の外へデータを出す仕組みなので、重複や配送失敗の監視は利用者側の責任になる、と明記されています。 (Microsoft Learn)

つまり、この仕組みを使うときは、単に「メールを受ける」だけでは足りません。
少なくとも次を考える必要があります。

  • ジャーナル配送先の用意
  • 配送失敗時の alternate journaling mailbox
  • SMTP 受信基盤
  • 原本保全
  • 重複排除
  • 再送や障害時のリカバリ
  • 後段分析基盤への連携

このあたりを考えると、C# のサービス単体で SMTP 受信まで全部背負うより、SMTP は専用基盤に任せ、C# は解析と連携に集中するほうがきれいです。これは Exchange の制約と、ジャーナリング運用の責務分担を素直に反映した設計です。 (Microsoft Learn)


今回の前提構成

今回想定しているのは、次のような構成です。

Exchange Online / Exchange Server
    ↓ Journal Rule
journal@archive.example.com
    ↓
Postfix などの SMTP 受信基盤
    ↓ .eml 保存
.NET / C# Journal Receiver
    ↓ MIME 解析 / JSON 正規化
Azure Event Hubs
    ↓
Microsoft Fabric Eventstream
    ↓
Eventhouse または Lakehouse

Fabric 側は、Eventstream で Azure Event Hubs をソースとして受けられます。さらに Eventstream はイベントの変換やルーティングを行い、宛先として Lakehouse や Eventhouse を使えます。リアルタイム検索や監視寄りなら Eventhouse、長期分析や Delta テーブル化を重視するなら Lakehouse が相性のよい選択です。 (Microsoft Learn)

Azure Event Hubs は、フルマネージドのイベントストリーミング基盤で、低遅延・高スループットでイベントを受け付けられます。.NET 向けの公式クライアントも提供されており、複数コンシューマーへ同じイベントを配る pub/sub の中継点として使いやすいです。 (Microsoft Learn)


なぜ Postfix を推すのか

この記事のポイントはここです。
「C# でサービスを作る」のに、なぜあえて Postfix を前段に置くのか。

理由は、SMTP を受ける責務と、ジャーナルを業務データとして扱う責務は分けたほうが圧倒的に安定するからです。

参考
https://qiita.com/lowgain/items/6c4083a047b06dfb4310

1. SMTP サーバーとしての責務を自前で持たなくてよい

ジャーナル受信サービスを C# 単体で作る場合、単に MIME を読むだけではなく、SMTP サーバーとしての振る舞いも考えなければいけません。

  • SMTP セッション処理
  • TLS
  • 一時障害時の再送
  • キュー管理
  • 受信失敗時のエラー応答
  • 受信順序や同時接続
  • ディスクへの安全なスプール

この部分は、アプリケーションの本質ではありません。
しかも、ジャーナリングは「取りこぼしが気持ち悪い」タイプの要件です。そこで SMTP の成熟した実装に寄せたほうが安全です。Postfix はそのための定番の一つで、メール受信の責務を安定して肩代わりしてくれる存在です。これは一般的な設計判断ですが、Exchange のジャーナリングが外部配送と NDR 監視を利用者側責任としていることを考えると、かなり相性がよいです。 (Microsoft Learn)

2. C# 側を「解析サービス」に集中させられる

Postfix を前段に置くと、C# 側は SMTP をしゃべる必要がなくなります。
やることはかなり明確です。

  • .eml を読む
  • journal report を解析する
  • 添付された元メールを取り出す
  • 必要項目を JSON に正規化する
  • Event Hubs に送る
  • 原本保全用ストレージへ保存する

つまり、C# 側は メールサーバーではなく、ジャーナル正規化パイプラインになります。
この分離は、実装もテストもかなり楽です。

3. 障害時の切り分けがしやすい

構成が分かれていると、障害の切り分けも明快です。

  • Exchange から届いていないのか
  • SMTP 受信までは来ているのか
  • .eml 保存までは成功しているのか
  • C# パーサーで失敗したのか
  • Event Hubs 送信で失敗したのか
  • Fabric 側取り込みで詰まっているのか

全部を 1 サービスに押し込むと、この切り分けがかなり苦しくなります。

4. 一時的な後段障害に強くできる

たとえば Event Hubs が一時的に失敗した、Fabric 側がメンテ中だった、といったときでも、Postfix 側で受信済みのメールが安全にスプールされていれば、C# サービスは後から再処理できます。

この「まず受け切る」「後で処理する」という分離は、ジャーナルのような証跡系データではかなり重要です。
Event Hubs 自体も高スループットですが、正本保存というよりはイベント中継に向いた基盤なので、前段に SMTP スプール、後段に原本保全を持つ設計のほうが安心です。 (Microsoft Learn)


Postfix を使わない案はどうか

もちろん、Postfix 以外の選択肢もあります。

C# が直接 SMTP を受ける

PoC ならできます。
ただし本番では、SMTP サーバー品質の実装まで背負うことになり、かなり重くなります。

別メールサーバーで受けて IMAP で回収する

これもできます。
ただ、今度はメールボックス運用や既読管理、回収遅延、肥大化対策が必要になります。

Exchange Online のメールボックスで受ける

これは Exchange Online のジャーナリングでは不可です。
ジャーナリング先も alternate journaling mailbox も Exchange Online のメールボックスにはできません。 (Microsoft Learn)

この比較をすると、専用 SMTP 受信基盤として Postfix を置く案が、実装量と運用安定性のバランスがよいと感じます。


.NET / C# 側の役割

C# サービスの役割は、受信した .eml を「分析しやすい JSON」に変換することです。

主な処理は次の通りです。

  • journal report 原文を読む
  • 添付されている元メール message/rfc822 を抽出する
  • Message-Id, Subject, From, To, Cc, Date などを取り出す
  • 原本の SHA-256 を計算する
  • JSON に正規化する
  • Event Hubs に送る
  • 必要なら原本 .eml を Blob などへ保存する

ここで大事なのは、Event Hubs に送る JSON を正本にしすぎないことです。
JSON は分析用、原本 .eml は証跡用、という分離が無難です。これは記事としては設計判断ですが、ジャーナリングが元メッセージを外部に保持するための仕組みであることを考えると、元の .eml をどこかに残しておく意味は大きいです。 (Microsoft Learn)


Event Hubs 経由にする意味

Event Hubs を挟むメリットは、受信と消費を疎結合にできることです。

たとえば後段で、

  • Fabric でリアルタイム分析する
  • 別サービスでアラートを出す
  • 他システムにも転送する

といった拡張がしやすくなります。
Event Hubs は publish-subscribe 型の高スケーラビリティなイベント基盤で、複数の受信側を持ちやすいのが強みです。 (Microsoft Learn)

また、Fabric Eventstream が Azure Event Hubs をソースとして扱えるので、Microsoft 系サービスで流れを組みやすいのも大きいです。 (Microsoft Learn)


Fabric 側はどこに着地させるべきか

Fabric では、用途に応じて主に 2 つの候補があります。

Eventhouse

向いているのは次のようなケースです。

  • リアルタイム検索
  • 監査ダッシュボード
  • 異常検知
  • 時系列集計
  • KQL での即時分析

Lakehouse

向いているのは次のようなケースです。

  • 長期保管
  • Delta テーブル化
  • Notebook / Spark 分析
  • Power BI での二次活用

Eventstream は Event Hubs から受けたイベントを加工し、Lakehouse や Eventhouse に送れます。
そのため、まずは Eventhouse に入れて運用監視寄りに使い、必要に応じて Lakehouse にも広げる、という構成も取りやすいです。 (Microsoft Learn)


この構成の実装イメージ

かなりシンプルに書くと、全体の責務はこうなります。

Exchange

  • Journal Rule を設定する
  • 配送先は journal@archive.example.com
  • alternate journaling mailbox も外部に用意する

Postfix

  • journal@archive.example.com を受信する
  • .eml としてスプール / 保存する
  • SMTP レイヤーの信頼性を担保する

.NET / C#

  • .eml をポーリングまたは監視する
  • MimeKit などでパースする
  • JSON に正規化する
  • Event Hubs に送信する
  • 原本保存も行う

Fabric

  • Eventstream で Event Hubs を受信する
  • Eventhouse / Lakehouse に着地させる

この分離にすると、各層の責務がかなり明確です。


まとめ

Exchange のジャーナル受信サービスを .NET / C# で作るとき、
「C# で全部やる」のではなく、SMTP 受信は Postfix に任せ、C# はジャーナルの解析と JSON 化に集中するという設計はかなり相性がよいです。

特に Exchange Online では、

  • ジャーナリング先に Exchange Online メールボックスは使えない
  • alternate journaling mailbox も Exchange Online に置けない
  • ジャーナリングは古い機能で、外部配送や NDR 監視は利用者責任

という制約があるため、外部に専用受信基盤を持つ前提で考えるのが自然です。 (Microsoft Learn)

そのうえで、

Exchange → Postfix → C# → Event Hubs → Fabric

という流れにすると、

  • 受信の安定性
  • 解析ロジックの単純化
  • 後段との疎結合
  • Fabric でのリアルタイム分析や長期分析

を両立しやすくなります。 (Microsoft Learn)

ジャーナルの受信は地味ですが、要件としてはかなり重い領域です。
だからこそ、SMTP は SMTP に強い仕組みに任せ、アプリケーションは「証跡を壊さず、扱いやすいデータに変換する」ことに集中したほうが、結果として堅い構成になると思います。


0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?