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
は該当サーバのホスト名としてしか使用していなかったので見落としていました。
状況を順を追って行くと
mb_send_mail
がキックされ、Webサーバがメールを送信する- 1.の際に、自身のホスト名である
hoge.example.jp
を使用してメールを送信する - メールの宛先である
hoge@xn–eckwd4c7cu47r2wf.jp
のメールサーバmail.xn–eckwd4c7cu47r2wf.jp
で送信元メールアドレスのドメイン名をDNSで名前解決できるかチェックする - 名前解決できないので弾かれる
という流れ。
対処
送信元メールアドレスのドメインを存在するメールアドレスに変えれば良いのですが、上述の通り From
を指定してもWebサーバのデフォルトから変わらなかったので、 hoge.example.jp
をAレコードに追加することで回避するようにしました。