mb_send_mail から送信したメールが 450 4.1.8 Sender address rejected: Domain not found エラーになってしまう

mb_send_mail から送信したはずのメールが届かない、という現象に遭遇したのでメモしておきます。

現象

PHPで mb_send_mail を使ってメールを送信するプログラムを作ったのですが、待てど暮らせど届かないのでエラーログを見たところ、以下のようなログが記録されていました。

Mon dd hh:ii:ss HOSTNAME mta/smtp[XXXXXXXX]: ZZZZZZZZZZZ: to=, relay=mail.xn–eckwd4c7cu47r2wf.jp[192.0.2.1]:25, delay=dddd, delays=dddd/dddd/ddd/dddd, dsn=4.1.8, status=deferred (host mail.xn–eckwd4c7cu47r2wf.jp[192.0.2.1] said: 450 4.1.8 webserver@hoge.example.jp: Sender address rejected: Domain not found (in reply to RCPT TO command))

サンプルプログラム

再現するために書いたシンプルなプログラムは以下。

<?php

date_default_timezone_set('Asia/Tokyo');
mb_language('ja');
mb_internal_encoding('UTF-8');

try {
    $sender = mb_encode_mimeheader('テスト送信者');

    $headers = <<< EOM
From: {$sender} <hoge@example.jp>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-2022-JP
EOM;

    $body = <<< EOM
test

㈱
⑨
EOM;

    $to = 'hoge@xn–eckwd4c7cu47r2wf.jp';
    $subject = 'テストメールです';

    $convertedMailBody = mb_convert_encoding($body, 'ISO-2022-JP-MS', 'UTF-8');
    $flag = mb_send_mail($to, $subject, $convertedMailBody, $headers);
    var_dump($flag);
}
catch (Exception $e) {
    var_dump($e->getMessage());
}

このPHPを該当サーバに設置してアクセス、上述の現象が発生することを確認しました。

しかも困ったことに、今回の現象は発生しても mb_send_mail 的には true で返ってきてしまうので表面上気付かないという……。

原因

原因としては、Webサーバのホスト名(ログの hoge.example.jp )がDNSのAレコードから漏れていて名前解決できないことが原因で、メールサーバ側に弾かれていました。

example.jp はもちろん名前解決できる状態でしたし、 hoge.example.jp は該当サーバのホスト名としてしか使用していなかったので見落としていました。

状況を順を追って行くと

  1. mb_send_mail がキックされ、Webサーバがメールを送信する
  2. 1.の際に、自身のホスト名である hoge.example.jp を使用してメールを送信する
  3. メールの宛先である hoge@xn–eckwd4c7cu47r2wf.jp のメールサーバ mail.xn–eckwd4c7cu47r2wf.jp で送信元メールアドレスのドメイン名をDNSで名前解決できるかチェックする
  4. 名前解決できないので弾かれる

という流れ。

対処

送信元メールアドレスのドメインを存在するメールアドレスに変えれば良いのですが、上述の通り From を指定してもWebサーバのデフォルトから変わらなかったので、 hoge.example.jp をAレコードに追加することで回避するようにしました。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。