CMS・WordPress

Contact Form 7で自動返信は届くのに管理者宛だけ届かない原因|サーバーを分けた瞬間に壊れる設定

Webサイトをサーバー移転した後、問い合わせフォームの自動返信は届くのに、管理者宛の通知メールだけが届かない。

この症状に当たったことがあるなら、原因はほぼ確実にフォームの送信元(From)の設定です。サーバーの不調でも、プラグインの不具合でもありません。

そして厄介なのは、移転前の環境では何年も正常に動いていたという点です。設定を何も変えていないのに、サーバーを分けた瞬間に壊れます。

この記事では、なぜ旧環境では動いていたのかという仕組みから説明します。ここが分かっていないと、正しく直したつもりで別の壊れ方をします。

スポンサーリンク

結論

  • 送信元にフォーム入力者のアドレス(訪問者が入力した任意のアドレス)が入っていると、外部配送になった時点で弾かれやすくなる
  • 旧環境で動いていたのは、サイトと管理者宛のメールボックスが同じサーバー上にあったから。サーバー内配送では送信ドメイン認証のチェックが一切走らない
  • つまり設定は変えていないのに、配送経路が変わったことで壊れた
  • 正しい設定は、送信元を自ドメインの実在するアドレスにして、返信先はReply-Toで渡す
  • WordPress既定のwordpress@ドメインに戻すのも危険。そのメールボックスが実在しないと、配送失敗通知が誰にも届かない

この記事の前提

製造業のコーポレートサイトを、前の管理会社から引き継いで新ドメイン・新サーバーに再構築した案件で、実際に起きた事象です。作業中に確認・対処したことだけを書いています。

この案件ではメールサーバーの移転はしていません。メールは旧ドメイン側に残置しました。つまりこれは「メールを移したら壊れた」話ではなく、「メールを移さずにサイトだけ移したら壊れた」話です。

そしてこちらのほうが、実務ではよく起きます。

何が起きたか

移行後、フォームから送信すると入力者への自動返信は正常に届くのに、管理者宛の通知メールだけが届かない状態になりました。

Contact Form 7 のメール設定はこうなっていました。

送信先 : contact@旧ドメイン
送信元 : [your-name] <[your-email]>

[your-email] はフォームに入力されたアドレスです。つまり送信元が、まったく無関係な第三者のドメイン(gmail.com など)になっていました。

Contact Form 7 自身も管理画面で警告を出していました。

サイトのドメインに属していないメールアドレスが送信元に設定されています

一方、自動返信の送信元は固定のアドレスでした。

送信元 : [_site_title] <reply@旧ドメイン>

注意したいのは、こちらもサイトのドメインとは一致していないという点です。サイトは新ドメインに移っているのに、送信元は旧ドメインのままです。

つまり「自ドメインだから届いた」わけではありません。両方とも自ドメインではありませんでした。差はもっと別のところにあります。

なぜ管理者宛だけが壊れたのか

ここがこの記事の本題です。「送信元を自ドメインにしましょう」で終わる説明では、次に同じ問題を踏みます。

原因は2つ重なっています。ひとつは配送経路が変わったこと、もうひとつは送信元が訪問者の入力値だったことです。順に説明します。

理由1:宛先が同一サーバー上から外部に変わった

管理者宛メールの宛先は contact@旧ドメイン でした。

旧環境では、サイトもこのメールボックスも同じサーバー上にありました。同じサーバー内で完結する配送では、そもそも外部のSMTPを経由しません。送信ドメイン認証のチェックが一切走らずに配送されます。受信側の認証チェックは、外部から届いたメールに対して行われるものだからです。

移行後はこうなります。

旧環境: 旧サーバー → contact@旧ドメイン(同じサーバー) = サーバー内配送
新環境: 新サーバー → contact@旧ドメイン(別サーバー)   = 外部配送

設定は何も変えていないのに、配送経路だけが変わりました。そして外部配送になった瞬間、それまで一度も適用されていなかった認証チェックの対象になります。

自動返信のほうは、宛先が訪問者のアドレス(フリーメールなど)なので、旧環境でも最初から外部配送でした。つまり自動返信は環境が変わっても配送経路が変わっていません。ここが片方だけ壊れた1つ目の理由です。

理由2:送信元が訪問者の入力値だった

外部配送になったとき、次に効いてくるのが送信元です。

管理者宛の送信元は [your-email]、つまりフォームに入力されたアドレスでした。フリーメールのアドレスが入ることがほとんどです。

すると、こういうメールが飛ぶことになります。

送信したサーバー : 新サーバー
From:            : 訪問者@フリーメールのドメイン

受信側から見ると、フリーメールのドメインを名乗っているのに、そのドメインとは無関係なサーバーから届いたメールです。これは送信元を詐称したメールとまったく同じ形をしています。フリーメール各社は自社ドメインの詐称対策を厳しく運用しているので、この形は弾かれやすくなります。

自動返信の送信元は固定アドレスでした。サイトのドメインとは一致していないので褒められた設定ではありませんが、少なくとも「フリーメールを名乗る」形にはなっていません。これが2つ目の理由です。

差は「自ドメインかどうか」ではなく、「訪問者が入力した任意のアドレスか、固定のアドレスか」でした。

そして移行前は、そもそも判定の土俵に乗っていなかったという事実が重なっています。

補足:SPFが見ているのは From: ではない

ここで、よくある誤解を1つ解いておきます。
多くの解説が「送信元ドメインのSPFレコードを見て判定される」と書いていますが、正確ではありません。

SPFが検証するのはFrom: ヘッダーではなく、エンベロープ送信者(Return-Path)です。

この2つは別物です。封筒に書かれた差出人と、便箋に書かれた差出人が違う、という状態がメールでは普通に起こります。

PHPの mail() 関数で送信した場合、こうなります。

エンベロープ送信者 : www-data@サーバーのホスト名   ← sendmailが自動で付ける
From:              : 訪問者@gmail.com              ← フォームが指定した値

SPFはエンベロープ送信者を見るので、判定対象はサーバー自身のドメインになります。gmail.comのSPFレコードは参照されません。

では From: の不一致は誰も問題にしないのかというと、それを見るのがDMARCです。DMARCは「From: のドメインと、SPFやDKIMで認証されたドメインが揃っているか」を検証します。ただしDMARCの判定をどう扱うかは受信側次第で、厳格でない受信サーバーなら通ってしまいます。

だから「設定としては間違っているが、環境によっては届いてしまう」という、いちばん厄介な状態が生まれます。

今回の設定はまさにそれで、

サイトとメールが同じサーバーにある限りは動くが、分けた瞬間に破綻する設定

だったことになります。

ここは強調しておきたいのですが、当時の制作に瑕疵があったわけではありません。同一サーバー構成という前提の中では、実際に正しく動いていました。前提が変わっただけです。

引き継ぎ案件で前任者の設定を責めても何も解決しません。「どの前提に依存していたのか」を特定するほうが早いです。

スポンサーリンク

正しい設定

Contact Form 7 の場合、こうします。

送信元       : [_site_title] <info@自ドメイン>
追加ヘッダー : Reply-To: [your-email]

info@自ドメイン は実在するメールボックスである必要があります。

Reply-To があれば運用は変わらない

「送信元を自ドメインにすると、返信するときに宛先を手で打ち直すことになるのでは」と思うかもしれませんが、なりません。

Reply-To が入っていれば、メールソフトの返信ボタンはそちらを宛先にします。受け取る側の操作は何も変わりません。

この案件で興味深かったのは、すでにReply-Toが設定されていたことです。つまり From を入力者のアドレスに書き換える必要は最初から無く、認証を通らなくするという副作用だけを持っていたことになります。

wordpress@ドメイン に戻すのは危険

送信元を触らず、WordPress既定の wordpress@ドメイン に戻すという判断もあり得ます。自ドメインではあるので、認証は通ります。

ただしそのメールボックスは通常、実在しません。

実在しないアドレスを送信元にすると、配送に失敗したときのバウンス(配送失敗通知)が誰にも届きません。

これが「数ヶ月間、問い合わせが1件も届いていなかったことに誰も気づかなかった」という事故の典型的な形です。送信は成功しているように見え、失敗の通知だけが宙に消えます。

送信元には、実在して、誰かが見ているメールボックスを指定してください。

SMTPプラグインを使う方法

もうひとつの解決策として、SMTP送信プラグインで自ドメインのメールアカウントに認証接続して送る方法もあります。

この場合はエンベロープ送信者もそのアカウントになるため、認証の観点では最も素直です。送信ログが残るので、届いたかどうかの切り分けも楽になります。

ただしメールアカウントのパスワードをWordPressに保存することになるので、サイトが乗っ取られたときの影響範囲が広がります。どちらを選ぶかは運用次第です。

サーバーを分ける前に確認すること

この事故は、移転前に4つ確認しておけば防げます。

  • フォームの送信元が自ドメインか。第三者のドメインが入っていたら、移転で必ず壊れます
  • メールボックスの管理主体は誰か。他社の管理下にあると、迷惑メールフォルダの確認すらできず、切り分けが何倍も重くなります
  • 実体のあるメールボックスか、転送設定か。転送なら転送先を押さえておけば、移行後はそこへ直接送る構成にできます
  • SPF / DKIM / DMARC / MX の現状。移転後にどれが変わるのかを先に把握しておきます

特に2つ目は技術ではなく段取りの話ですが、実際にいちばん時間を食うのはここです。

まとめ

  • 自動返信は届くのに管理者宛だけ届かないなら、まず送信元(From)を疑う
  • 壊れる条件は2つ重なる。宛先が同一サーバーから外部に変わったことと、送信元が訪問者の入力値だったこと
  • 差は「自ドメインかどうか」ではない。訪問者が入力した任意のアドレスか、固定のアドレスかで挙動が分かれる
  • SPFが見ているのは From: ではなくエンベロープ送信者。だから「設定は間違っているのに届く」環境が存在する
  • 送信元は自ドメインの実在するアドレス。返信先は Reply-To で渡す
  • wordpress@ドメイン のような実在しないアドレスは、バウンスが消えるので使わない

引き継ぎ案件でメールボックスの管理主体が他社にあると、この切り分け自体ができなくなります。何を事前に確認しておくべきかは前の制作会社からサイトを引き継ぐとき、技術より先に確認すべきアカウントと契約にまとめました。

スポンサーリンク