【この記事の所要時間 : 約 9 分】
先日、あるメールアカウントのバウンスメールが大量にサーバの管理者宛メールアドレス(root@***.co.jp)に戻ってくるという状態が発生した。
ネットワークエンジニアに聞くと、メールの送り方に問題があるために、発信元(Fromヘッダ)にバウンスメールが届かない状況になっているとのこと。
調べてみると、そのメールアカウントを使ってあるメール送信システムがメールを送信していた。
そのメール送信部分のプログラムは以下のようになっていた。
mb_send_mail($mail_to, $mail_subject, $mail_content, “From: $mail_from\nBcc: $mail_bcc”);
mail関数は、http://search.net-newbie.com/php/function.mail.htmlの「例3」の様に(第5引数の指定を)する必要があるとのことで以下のように修正。
mb_send_mail($mail_to, $mail_subject, $mail_content, “From: $mail_from\nBcc: $mail_bcc”, “-f$mail_from”);
これでたぶん大丈夫だろう。
せっかくの機会なので、よくわかっていないメールについて調べてみた。
まずアプリケーションを作る上で理解しておかなければならないのが、「エンベロープとヘッダの違い」である。
エンベロープとヘッダ(1)
# エンベロープ(envelope)
* 封筒に書かれた情報
* MAILコマンド,RCPTのコマンドの引数
# ヘッダ(header)
* 本文(便箋の先頭部分)に書かれた情報
* DATAコマンドの後に送られる
* 空白行までの範囲
上記が違いというか定義。
コマンドレベルと見てみると・・・・
エンベロープとヘッダ(2)
S: 220 mail.example.jp ESMTP Ready
C: HELO mta.example.com
S: 250 Hello mta.example.com
C: MAIL FROM: <alice@example.com> ← エンベロープFrom
S: 250 <alice@example.com> … OK
C: RCPT TO: <bob@example.jp> ← エンベロープTo
S: 250 <bob@example.jp> … OK
C: DATA
S: 354 Go ahead
C: From: alice@example.com ← ヘッダFrom
C: To: bob@example.jp ← ヘッダTo
C: Subject: test
C:
C: This is a test message.
C: .
S: 250 Message accepted
C: QUIT
MAILコマンドの引数として、『エンベロープFrom』がきて、RCPTコマンドの引数として、『エンベロープTo』がくる。そして、DATAコマンドの後に、「From: メールアドレス」という形式で『ヘッダFrom』、「To: メールアドレス」という形式で『ヘッダTo』がくる。
エンベロープとは
封筒に書く宛先(住所と名前)は、メールで置き換えるとヘッダではなく、エンベロープと言われる情報になります。エンベロープには配送の宛先、発信者のアドレス情報などが記入されており、ここに記述されている情報が実際のMTAによるメール配信に使われています。エンベロープはメーラーで表示できるヘッダとは異なり、通常、見ることができません。
ということで、MTA(sendmailなど)は、エンベロープをメール配信に利用しているとのこと。
メーラーで表示できるヘッダではないということがポイントかな。
で、今回の問題がなぜ起こったかといえば、mail( )関数で5番目の引数(additional_parameters)がなかったために、Return-Path(エラー時の返送先)がこのプログラムの実行ユーザー(root@***.co.jpなど)になっていたからであった。(ちなみに、safe_mode=Onだと第5パラメータは使用できない。)
Return-Pathは、明示的に送信元(エンベロープFrom)を指定してやる必要があるとのことで、調べていくと、これはメール関係では常識とのこと。(知らなくてごめん。。。)
※実際には、プログラムの実行ユーザーはrootではないが、エイリアスでroot@***.co.jpに飛ばしていたため、バウンスメールは管理者宛メールアドレス(root@***.co.jp)にきたみたい。
エンベロープとヘッダ(6)
エンベロープとヘッダの関係
* もともと役割が異なる
o エンベロープFrom・Toは配送用(MTAが利用)
o ヘッダFrom・Toは記録用(受信者・MUAが利用)
* 両者が一致しなくてもよい
o Bccで指定したアドレス
o メーリングリストの宛先・差出人アドレス
* 特にspamメールでは一致しないことが多い
ただし、これで万事OKかというとそうは問屋がおろさない。
PHPマニュアルにも以下のように書かれている。
mail – PHPマニュアル
additional_parameters(オプション)
パラメータ additional_parameters は、 追加のパラメータをメール送信プログラムに渡す際に使用可能です。 メール送信プログラムは、設定オプション sendmail_path により設定されます。例えば、 sendmail を使用する際に -f オプションを使って エンベロープの sender アドレスを設定する際に使用できます。
この方法でエンベロープの sender ヘッダ(-f)を設定する際は、 ‘X-Warning’ ヘッダが付加されないように Web サーバの実行ユーザを sendmail 設定に追加しておく必要があるかもしれません。 sendmail を利用している場合、これは /etc/mail/trusted-users で設定します。
ということで、mail関数で第5引数の指定した場合、 ‘X-Warning’ ヘッダが付加されて「迷惑メール」扱いになる可能性があるので、 ‘X-Warning’ ヘッダが付加されないようにしなさいとPHPマニュアルではかかれている。ということで関連情報を調べてみると・・・
X-Authentication-Warningフィールドの制御
PHPからmail関数を使用してメールを送る際にX-Authentication-Warningフィールドが自動で付加されてしまい、場合によっては迷惑メールとして扱われてしまう可能性があるので対処法を探してみました。
編集箇所は/etc/mail/submit.cf内の以下の部分です。 Tapacheを追加しました。#####################
# Trusted users #
#####################
# this is equivalent to setting class “t”
Ft/etc/mail/trusted-users
Troot
Tdaemon
Tuucp
Tapachesubmit.cfを保存したらmake submit.cfを実行して、sendmailを再起動。これでX-Authentication-Warningがヘッダに含まれなくなりました。
ということで、これは、mail関数で第5引数の指定した場合、 エンベロープfromを偽装できるが、代わりに ‘X-Warning’ ヘッダが付加さるという「警告」がでる。その「警告」を消すための方法が、信頼できるユーザとしてWeb サーバの実行ユーザを sendmail trusted user に指定するというもの。信頼できるユーザの場合は警告が表示されないので。
なので、上記では、ユーザー apacheを trusted userに追加している。
以下、参考までに。
trusted user を指定する。
配信メールがスパム(迷惑メール)扱いされていて困っている人はこのあたりもチェックしてみてはどうだろうか?
技術評論社
売り上げランキング: 140,417