Azure App Service 上の WordPress で「Outlook と MailPoet は送れるのに、WPForms だけ届かない」。この“部分的な不達”は、SMTP 認証の取り違え・Azure のポート制限・プラグイン競合の三重奏が典型原因です。実機で再現した設定例と、現場でそのまま使える復旧手順・検証ポイントを余さず解説します。
事象の概要(環境と症状の再整理)
- 独自ドメインは Microsoft 365(Outlook)に接続済み。SPF/DKIM/DMARC は Microsoft 365 側で既に正しく構成。
- WordPress は Azure App Service 上で稼働。
- フォーム送信:WPForms。送信基盤:Brevo(旧 Sendinblue)用の WP‑SMTP。
- メルマガ:MailPoet(正常に配信できている)。
- 症状:Outlook 送受信は可、MailPoet も可。WPForms 経由の通知メールのみ不達。
先に結論(最短復旧のポイント)
最終的な決め手は次の 3 点でした。
- WP Mail SMTP(公式)で「Brevo」メーラーを選択し、API キーではなく SMTP キー を登録(ユーザー名=Brevo ログインメール、パスワード=生成した SMTP キー)。
- 暗号化は TLS/587(ダメなら SSL/465) を明示。Azure App Service は アウトバウンドの 25/TCP をブロック するため 25 は使わない。
- Azure 関連の拡張・プラグインを停止(SMTP ソケットをフックする系)。競合を除去したら WPForms も正常送信に復帰。
なぜ起きるのか(根本原因の整理)
| 原因カテゴリ | 具体例 | WPFormsだけ不達になりやすい理由 | 一次切り分け |
|---|---|---|---|
| SMTP 認証・資格情報の取り違え | Brevo の API キー を SMTP パスワードとして登録/ユーザー名が間違い/送信者ドメイン未認証 | MailPoet は自社配送(または別経路)を使い成功。一方 WPForms はサイト共通の PHPMailer 経由で失敗 | WP Mail SMTP の「メールテスト」で即判定。401/535 などの認証エラー |
| Azure の送信ポート制限 | App Service からの 25/TCP はブロック。TLS/587 または SSL/465 で出す必要 | MailPoet が API 経由の場合は影響を受けないが、WPForms は SMTP で失敗 | WP Mail SMTP の接続ログでタイムアウト/接続拒否 |
| プラグイン競合 | Azure 向け拡張・セキュリティ・最適化系が PHPMailer/SMTP を上書き | フォーム送信時のみ特定フックが動作し、MailPoet とは経路が分離 | 全停止→WP Mail SMTP のみ有効→段階的に有効化で再現プラグイン特定 |
| From/Return-Path の不整合 | From が Microsoft 365 ドメイン、実配送は Brevo。DMARC/ALIGN が崩れる | MailPoet はドメイン整合済みだが、WPForms はテンプレ不整合が放置されがち | 受信側ヘッダで Authentication-Results を確認 |
| Exchange Online 側の制限 | Authenticated SMTP がテナント/ユーザーで無効(Microsoft 365 SMTP を使う場合) | Brevo ではなく O365 SMTP を使っていたケースで露見 | Microsoft 365 管理センターで機能状態を確認 |
決定版:すぐに直すための手順
- Brevo で SMTP キーを発行
ダッシュボード → SMTP & API → SMTP タブ → 新しい SMTP キーを生成。
表示は一度きり。厳重に保管し、API キーと混同しないこと。 接続情報の目安- SMTP ホスト:
smtp-relay.brevo.com - ポート:
587(TLS)/465(SSL) - ユーザー名:Brevo ログインメール
- パスワード:発行した SMTP キー
- SMTP ホスト:
- WP Mail SMTP(WPForms 公式推奨)を設定
WordPress → WP Mail SMTP > 設定- メーラー:Brevo(または「Other SMTP」)
- From Email:
[email protected](Brevo/M365 で認証済み) - From Name:サイト名(任意)
- Force From Email/Force From Name を有効化
- 暗号化:TLS(まずは 587)/失敗時は SSL(465)を試行
- 認証:有効。ユーザー名=Brevo ログインメール、パスワード=SMTP キー
- WPForms 側の通知設定を統一
WPForms → 該当フォーム → 設定 > 通知
- 送信先アドレス(To)が正しいこと(カンマ区切りの全角/半角ミスに注意)。
- From Email が Step 2 の From と一致していること。
- Reply‑To を送信者メールにする場合は DMARC を崩さないよう From は固定。
- デバッグログを有効化し、Azure 側からも追う
/* wp-config.php 末尾あたりに追加(本番常時は非推奨) */ define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); // 画面には出さない/wp-content/debug.logと、Azure ポータルの Log Stream を併用。送信時刻に合わせてエラーメッセージを突き合わせます。 - Azure のネットワーク制限を前提に設定を固定
App Service は 25/TCP を送信不可。必ず 587/TLS または 465/SSL。
接続タイムアウトが出る場合は、ファイアウォール・WAF・セキュリティプラグインが 587/465 を遮断していないか点検。 - 競合プラグインを停止して切り分け
「Azure アプリ(サイト拡張)」「セキュリティ」「キャッシュ最適化」「メール周辺」など SMTP/PHPMailer に触る可能性があるものを一括停止 → WP Mail SMTP だけを有効化してテスト → 1 つずつ戻して再現したものを恒久的に無効化または設定見直し。
今回のケースでは、Azure 向けプラグインの停止で復旧。
チェックリスト(現場で使える一枚表)
| 項目 | 見るべき値 | 合格ライン | NGのときの例 |
|---|---|---|---|
| SMTP ホスト | smtp-relay.brevo.com | 名前解決→587/465 で接続確立 | 25 で試してタイムアウト |
| 資格情報 | ユーザー=Brevo ログインメール/パス=SMTP キー | 535 などの認証エラーが出ない | API キーを入れて 535 |
| From/Return‑Path | 同一ドメイン/Brevo で署名 | DMARC=pass, DKIM=pass, SPF=pass | From だけ Microsoft 365、配送は Brevo で d=不一致 |
| ポート | 587/TLS(優先) or 465/SSL | 接続成功 | 25 指定 |
| プラグイン競合 | SMTP/PHPMailer に触るもの | 最小構成で成功 | 最適化・セキュリティ系で通信失敗 |
詳細:DNS と認証(SPF/DKIM/DMARC)を正しく“揃える”
Microsoft 365 と Brevo を併用する場合、「誰が」「どのドメインで」署名しているかが肝心です。以下を満たせば実運用で強いです。
- From(ヘッダ)=独自ドメイン。Brevo 側でそのドメインに対する DKIM(CNAME) と Return‑Path(バウンス)ドメイン を構成。
- SPF は
include:spf.brevo.comとinclude:spf.protection.outlook.comの「両方」を入れるか、用途で分離(例:news.example.comは Brevo、example.comは Microsoft 365)。 - DMARC は
adkim=s/aspf=s(厳格)がおすすめ。はじめはp=noneで観測→quarantine→rejectへ段階移行。
代表的なレコード例(あくまで例。実値は各サービス画面の指示を優先)。
/* SPF(例) */
example.com. TXT "v=spf1 include:spf.protection.outlook.com include:spf.brevo.com ~all"
/* DMARC(例) */
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=s; aspf=s; fo=1; pct=100"
注意:TXT/CNAME の重複作成や 10DNS ルックアップ制限超過は配信率を落とします。既存値の統合・整理を行いましょう。
Azure 特有の落とし穴と回避策
- 25/TCP は使えない:App Service からのアウトバウンド 25 はブロック。587/465 を使います。
- 送信元 IP が固定でない:一部の SMTP サービスで IP ホワイトリストを設定している場合、App Service の送信元と合わずに拒否されることがあります。IP 制限がある場合は API 送信への移行や専用出口(NAT Gateway/VNET 統合)を検討。
- アプリ設定に資格情報を出さない:WordPress のオプションに平文保存せず、Azure App Settings 経由で環境変数に置くのが安全です。
/* wp-config.php で環境変数を読む(例) */
define('WPSMTP_HOST', getenv('WPSMTP_HOST'));
define('WPSMTP_USER', getenv('WPSMTP_USER'));
define('WPSMTP_PASS', getenv('WPSMTP_PASS'));
define('WPSMTP_PORT', getenv('WPSMTP_PORT') ?: 587);
add_action('phpmailer_init', function($phpmailer){
if(defined('WPSMTP_HOST')){
$phpmailer->isSMTP();
$phpmailer->Host = WPSMTP_HOST;
$phpmailer->SMTPAuth = true;
$phpmailer->Username = WPSMTP_USER;
$phpmailer->Password = WPSMTP_PASS;
$phpmailer->SMTPSecure = 'tls';
$phpmailer->Port = (int)WPSMTP_PORT;
}
});
「MailPoet は成功・WPForms は不達」をどう説明するか
MailPoet は独自の配送(API/専用インフラ)を用いることが多く、WordPress 共通の PHPMailer 設定や OS ソケット制限の影響を受けにくい設計です。一方 WPForms はサイト全体のメール送信設定(WP Mail SMTP など)を共有するため、SMTP キーの取り違え、25/TCP 利用、プラグイン競合といったインフラ側の問題が直撃します。今回のように「MailPoet は OK だが WPForms は NG」という差分は、まさに経路の違いから説明できます。
検証の進め方(決定木)
- WP Mail SMTP の「メールテスト」を実行:エラーコード/本文を保存。
- 最小構成で再現:WP Mail SMTP 以外を停止→再テスト。
- ポート切替:587/TLS → 465/SSL。接続タイムアウトならネットワーク、535 等なら認証系。
- From 統一:WPForms の通知テンプレで From を固定/Reply‑To を送信者。
- 受信側ヘッダ確認:
Authentication-Resultsの DMARC/DKIM/SPF を確認。 - Azure ログの詰め:Log Stream/Kudu で PHP・拡張機能・タイムアウトの同時刻相関を取る。
フォーム通知テンプレの黄金パターン
From: [email protected] ← 認証済み・Brevo DKIM ドメイン
Reply-To: {field.email} ← 送信者のメール(DMARC を崩さない)
Subject: [お問い合わせ] {field.subject}
To: [email protected]
ポイントは「From は固定・認証済み」「Reply‑To で差し替え」。これで DMARC を維持しつつ、運用者がそのまま返信できます。
サンプル:PHPMailer 詳細ログ(一時的な解析に)
add_action('phpmailer_init', function($phpmailer){
$phpmailer->SMTPDebug = 2; // 1 or 2
$phpmailer->Debugoutput = function($str, $level){
error_log("PHPMailer[$level]: " . trim($str));
};
});
本番では必ず戻してください。ログには資格情報やサーバー名が出る場合があります。
セキュリティ運用(最低限の 7 箇条)
- SMTP キーは「送信専用」権限に限定(可能ならローテーションを半年以下)。
- WordPress 利用者の権限を絞る。WPForms の通知先変更は管理者のみ。
- wp‑config.php に秘密情報を直書きせず、Azure App Settings を使用。
- プラグインは常に最新。特に SMTP/フォーム/セキュリティ系。
- DMARC レポート(rua)を運用し、なりすましや誤設定を早期検知。
- IP 制限がある SMTP は API 送信へ移行検討。
- バックアップとステージングで事前検証(本番直当て禁止)。
将来トラブルをなくす:SMTP を卒業する 2 つの道
- Microsoft Graph API(OAuth 2.0)で送信:Outlook/Exchange とドメイン完全整合。ポート制限の影響を受けにくい。アプリ登録・同意・スコープ設計が必要。
- Brevo の REST API:SMTP より堅牢でスループットも読みやすい。フォーム送信にだけ使い、ニュースレターは MailPoet/専用配信のままでも良い。
ケーススタディ(今回の構成との照合)
独自ドメイン islandwoodturners.com を M365 に接続しつつ、フォームは Brevo 経由で出す構成。既に M365 の SPF/DKIM/DMARC は OK。そこで Brevo の SMTP キーを WP Mail SMTP に登録、587/TLS へ統一。さらに Azure 関連のプラグインを停止した結果、WPForms の通知も正常化。MailPoet は当初から配信 OK で、分離経路であった点とも整合します。
よくある質問(FAQ)
Q. 587 と 465、どちらを使うべき? A. まずは 587/TLS。どうしても接続相性が悪い場合のみ 465/SSL を試します。25 は Azure で不可。 Q. MailPoet はなぜ届くの? A. MailPoet は API/自社配送で SMTP 設定に依存しないため。WPForms はサイト共通の SMTP(PHPMailer)を使うので、インフラの影響を受けます。 Q. SPF を二重に書くのはダメ? A. TXT レコードは 1 レコードに統合します(複数作ると「どれが正?」になりがち)。include: は 10 ルックアップ制限に注意。 Q. Microsoft 365 の MFA を有効にしているが、SMTP は使える? A. Microsoft 365 の SMTP(smtp.office365.com)を使う場合は、テナント/ユーザーで「Authenticated SMTP」を許可し、アプリ パスワード利用を検討。今回は Brevo SMTP なので対象外ですが知識として。 Q. 送信は成功しているのに、Gmail にだけ届かない。 A. DMARC/ALIGN、ARC、コンテンツ判定、逆引き、Return‑Path のドメインなど総合点での減点の可能性。まずはヘッダで Authentication-Results を確認し、送信ドメインの整合から手を付けます。 Q. 共有サーバーのように速度が遅い。 A. SMTP はネットワーク往復が多く、遅延源になりがち。API 送信へ移行すると改善することが多いです。
最終まとめ(運用に残すメモ)
- Azure App Service は 25/TCP 送信不可。587/TLS または 465/SSL を使う。
- Brevo はSMTP キーで認証。API キーと混同しない。
- WPForms の不達は「PHPMailer 設定」「プラグイン競合」「From/DMARC」の三点を疑う。
- DNS は SPF/DKIM/DMARC/Return‑Path を 同一ドメインで整合。TXT/CNAME の重複に注意。
- 恒久対策は Microsoft Graph API または Brevo REST API への移行が有力。
今回の解決ステップ(再掲・コンパクト版)
| ステップ | 内容 | 補足 |
|---|---|---|
| 1 | Brevo の SMTP キーを生成(SMTP & API → SMTP → 生成) | ユーザー名=Brevo ログインメール/パスワード=SMTP キー |
| 2 | WP Mail SMTP を設定(メーラー:Brevo、From を固定、TLS/587) | 競合する他の SMTP プラグインは無効化 |
| 3 | WPForms の通知テンプレを統一(From 固定/Reply‑To で差し替え) | To の全角/半角やカンマ区切りミスに注意 |
| 4 | デバッグログ有効化(wp-content/debug.log) | WP Mail SMTP Pro があれば Email Log も活用 |
| 5 | Azure のネットワーク制限を確認(Log Stream/Kudu) | 25 は不可。587/465 のみ |
| 6 | 競合プラグインを停止(Azure 向け拡張を含む) | 今回、停止で正常化 |
付録:トラブル再発を防ぐ設定テンプレ
/* wp-config.php:メールヘッダの統一(From を強制) */
add_filter('wp_mail_from', function($email){ return '[email protected]'; });
add_filter('wp_mail_from_name', function($name){ return 'Island Woodturners'; });
/* WPForms の通知側:Reply‑To に {field.email} を設定(WPForms の GUI で) */
エンジニア向けメモ(SLA/可観測性)
- 監視:Brevo の配信イベント(accepted/delivered/bounce/spam)をダッシュボードで週次点検。異常時は SMTP キー漏えいの可能性も見る。
- アラート:フォーム送信数・失敗数を計測(WPForms の Webhook + Function Apps等でメトリクス化)。
- SLA:フォーム送信の遅延許容(例:P95 < 3s)。達しない場合は API 送信へ切替を検討。
最終結果:競合していた Azure 関連プラグインを無効化し、WP Mail SMTP に正しい Brevo SMTP キーと 587/465 を設定。WPForms の通知メールも正常配信に復帰。MailPoet は従来通り正常で、設計差による症状の違いとも整合しました。

コメント