▼yahoo.co.jp宛のメールをPostfixで配送する▼

結論: smtp_mx_session_limit を増やす。

$Id: yahoo421.html,v 1.29 2015-04-11 01:53:35+09 kabe Exp $ (2009-07)


▼背景

yahoo.co.jp のメールサーバ群は中途半端なIPアドレスブラックリストを 保持しており、 すぐにブラックリストに登録されて?なかなかメールが届きません。
時限式のようなのでいずれは届くようですが、1〜2日遅れは普通。 1週間遅れの例もあり。 mailq にも大量のyahoo.co.jp宛メールが滞留しがち。

インターネットの電子メールが遅れるのはそんな珍しくなく、 昔は数日遅れが当然だったしシステムがそれを見越して作られています。 急ぎの連絡は電話を使いましょう。 Y!J利用者は返信が来ないと怒らないように。差出人は既に送信済かも

▼観察

yahoo.co.jpのメールサーバ群(MX4つ×IPアドレス4つずつ=16台*)は、 IPアドレスベースのブラックリストを保持しており、 SMTP接続時のバナーでいきなり 421 Message from (NN.NN.NN.NN) temporarily deferred で接続拒否します。 HELOすら送らせない。


% telnet mx3.mail.yahoo.co.jp 25 Trying 203.216.247.184... Connected to mx3.mail.yahoo.co.jp. Escape character is '^]'. 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Connection closed by foreign host. % _

Postfixのメールログ的には以下のように deferred 扱いになります。


Jul 26 19:07:55 mailhost postfix/qmgr[21149]: 2F8ADE3345: from=<sender@sender.domain>, size=4270, nrcpt=1 (queue active) Jul 26 19:07:56 mailhost postfix/smtp[19545]: 2F8ADE3345: host mx1.mail.yahoo.co.jp[124.83.183.240] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 26 19:07:56 mailhost postfix/smtp[19545]: 2F8ADE3345: to=<recipient@yahoo.co.jp>, relay=mx3.mail.yahoo.co.jp[114.111.75.205], delay=7327, status=deferred (host mx3.mail.yahoo.co.jp[114.111.75.205] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co. jp/help/jp/mail/in_trouble/in_trouble-28.html)

yahoo.co.jp宛に頻繁にメールを出したり、forwardを設定している人がいると、 mailqのdeferredキューに ものすごい勢いでyahoo.co.jp宛のメールが溜まっていきます。 logcheck を走らせていると、deferredのログが拾われるので 1時間毎に警告メールが来たりして大変にうるさい。 (これはlogcheckを調整すればいいんですが)

なお、ブラックリストではなく 高負荷で受け取り保留にされる場合は、 接続拒否ではなく DATAフェーズの 応答で

451 Message temporarily deferred
451 hostname.yahoo.co.jp Resources temporarily unavailable. Please try again later [#4.16.1].
を返すので、区別できます。 (DATAの後だとトラヒック低減にならないので意味無いんじゃ…)

▼調査

もう少し配送成功したログを見ていると、同じ配送試行にて 2回目のSMTP接続で配送に成功している場合があります。


Jul 26 20:14:35 mailhost postfix/qmgr[21149]: 15F4DE33DA: from=<sender@sender.domain>, size=2292, nrcpt=1 (queue active) Jul 26 20:14:35 mailhost postfix/smtp[19721]: 15F4DE33DA: host mx3.mail.yahoo.co.jp[203.216.247.183] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 26 20:14:36 mailhost postfix/smtp[19721]: 15F4DE33DA: to=<recipient@yahoo.co.jp>, relay=mx2.mail.yahoo.co.jp[203.216.243.171], delay=1502, status=sent (250 ok dirdel)

つまり、 IPアドレスブラックリストは全MXで共有されているわけではない ということ。

であれば、違うMXへしつこくリトライすれば 配送が成功する確率が高くなると考えられます。

(全16MXにてブラックリストされた場合はこの限りではないが…)

Update: 同じサーバーにすぐにつなぎなおすと220バナーが返ることもあるので、 2値のブラックリストではなく、確率的に421を返す実装の気がします。 連続観測すると、だいたい全サーバで同様に確率値が変わるので、 IPアドレスブラックリストは共通?

Update 2010-09: MXとしてのIPアドレスは 2010-05-20 に10個、2010-07-08 に 8個と減らされており、 同一IPアドレスでも負荷分散装置の下に実サーバが12台程度ぶら下がる構成に 変更されています。 ざっと数えたところ実サーバは118台ある模様。 よって、同一IPアドレスに対してリトライしても、 実サーバが違うので配送成功することがあります。 現時点では拒否動作は負荷分散機ではなく実サーバ側で行われている模様。

▼検討

リトライを頻繁に行うには、普通は minimal_backoff_time, maximal_backoff_time, queue_run_delay あたりを調整しますが、 これらを短くすると他のサイトに確実に迷惑がかかるので 短くしてはいけません。 (長くする分には迷惑にはならないが、小トラブル時の遅延が大きくなる)
なおこれらの値は qmgr(8) 管轄で、全体に共通。 master.cf で 配送先毎に設定 にはできません。

複数のMXに対しリトライするには、smtp_mx_session_limitを 調整します。 デフォルトは 2 なので、最初のログ例のように2つのMXを試したら defer扱いになります。
smtp_mx_address_limit もPostfixのバージョンによっては 0(無制限)ではなかったりするので、=16 あたりに変更しておきます。 (デフォルト設定の smtp_skip_4xx_greeting = yes についても確認)

Yahooの接続拒否はHELO以前で行われるため、 Postfix 2.3 以降では smtp_mx_session_limit での カウントの仕方が違います。 2.3以降ではデフォルトのままでもいい(変わらない)かも?

まずは smtp_mx_session_limit = 5 あたりで試してみましょう。 むやみに増やすと、他の弱小サイトに迷惑がかかります。

5回目の試行で成功した例↓


Jul 30 09:27:11 mailhost postfix/qmgr[4197]: 0F845E3496: from=<sender@sender.domain>, size=8284, nrcpt=1 (queue active) Jul 30 09:27:23 mailhost postfix/smtp[4225]: 0F845E3496: host mx5.mail.yahoo.co.jp[203.216.243.173] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 30 09:27:23 mailhost postfix/smtp[4225]: 0F845E3496: host mx3.mail.yahoo.co.jp[203.216.247.183] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 30 09:27:24 mailhost postfix/smtp[4225]: 0F845E3496: host mx3.mail.yahoo.co.jp[114.111.75.205] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 30 09:27:24 mailhost postfix/smtp[4225]: 0F845E3496: host mx2.mail.yahoo.co.jp[203.216.243.170] refused to talk to me: 421 Message from (NN.NN.NN.NN) temporarily deferred - 4.16.50. Please refer to http://help.yahoo.co.jp/help/jp/mail/in_trouble/in_trouble-28.html Jul 30 09:27:24 mailhost postfix/smtp[4225]: 0F845E3496: to=<recipient@yahoo.co.jp>, relay=mx1.mail.yahoo.co.jp[124.83.183.240], delay=61968, status=sent (250 ok dirdel) Jul 30 09:27:24 mailhost postfix/qmgr[4197]: 0F845E3496: removed

一旦、保留状態が検出されると、qmgr(8)はその宛先はしばらく到達不能 ("dead") と判定し、minimal_backoff_time の間は 同じエラーコードで同一サーバ宛の他のメールもブロックします。 ので、デフォルトの1000s (16分ほど) は、Y!Jに対してメールが一切飛びません。

このdead判定時間中に 再送待ちになっていたdeferredメールに 再送がかかっても、qmgrはすぐにdeferredに戻してしまいます。 (ログ的には、qmgr ... (queue active) の直後、smtp接続せずにすぐ421エラーで 配送待ちに回される)

▼隔離

yahoo.co.jp 宛の配送にだけ smtp_mx_session_limit を適用するには、 QSHAPE_README などにあるように専用のtransportを master.cfに準備します。

この方法だと smtp_mx_session_limit 値は yahoo.co.jp 専用になるので、 値を大きくしても他サイトに迷惑はかかりません。

/etc/postfix/master.cf:

... ## local # limit yahoo.co.jp with transport:slowrelay # smtp_mx_session_limit=5 seems to be most effective, as # yahoo.co.jp MX resolves to 16 IP addresses which incoming blacklist # is not always in sync; thus some would accept the mail. slowrelay unix - - n - 2 smtp -o smtp_mx_session_limit=5
/etc/postfix/transport:

... # retry more for yahoo.co.jp yahoo.co.jp slowrelay:
/etc/postfix/main.cf:

... transport_maps = hash:/etc/postfix/transport ...

設定を隔離した場合は、 transport_destination_concurrency_limit を 大きくして、421 を食らっても簡単にあきらめない(dead判定しない) 設定にするのも良いでしょう。

こういった、高速サイトだがたまにエラーを出す宛先については、 Postfix付属の QSHAPE_README の highvolume.com 項に チューニング例があります。


▼効果

設定前後の、yahoo.co.jp宛メールの配送遅延状況
[設定前後の遅延状況]

グラフの見方: グラフ左端が、遅延なしで配送されたメールの割合。 グラフ右端が遅延の最も大きかったもの。 グラフが左上に行くほど良好な配送状況。

以前からyahoo.co.jp はブラックリストを運用していますが、 効き目を強化したのは2009/04下旬頃からのようなので、 その前後での遅延状況を比べてみます。

この配送状況は、MXが220を返す確率が 2/16 でおおよそ一定だった(気がする)ころの結果で、 Y!J がこの値をいじると次節のように悪化します。

▼確率変動

yahoo.co.jp のMX群が421拒否ステータスを返すのは2値ではなく 確率的に行われているようなので、 拒否率の変化と、どの程度の期間ブラックリストが続くのか、 連続観測してみます。

220(配送可能)ステータスを返すMXの割合の経時変化
[220を返す確率の経時変化]

グラフの見方: 縦軸が、配送可能な220ステータスが観測された確率。1.0が良好な状況。 グラフが低空飛行しているとメールが届きにくい。 緑線は移動平均。

実際には単純に負荷に応じて拒否率を決めているだけかもしれませんが、 確率が0.5から大きく改善することはないようです。 いずれにしろ、日中は拒否されまくりなので

日中は @yahoo.co.jp 宛のメールは届かない
と思ったほうが良いようです。 配送遅延が滅多に1日を超えないのは、 早朝の配送可能時間帯に配送されるからだと思われますが、 Y!Jの利用者にとっては メールが1日遅れで届く ように見えるはずです。

この期間、30分以内の配送率は8割まで下がってしまっています。 (グラフ茶線)
[2009-09-07週の配送状況]

421での拒否率がこうも高いと、Postfixのパラメータをいじって 改善できるレベルではありません。 Y!J宛配送専用のメールサーバ (別インスタンス起動でも良い) を立て、qmgrの再送間隔を詰める、 改造して配送試行にて同一アドレスへのリトライも行う、 といった対策になりそうです。 spam送信機と挙動が似てくるので、あまりお勧めは出来ません。

なお、普段はメールを発信しない、ブラックリストに載っていない アドレスから観測すると、 全MXが常に 220 の正常ステータスを返します。


▼長期確率変動

Update 2011-08: 半年程度、220ステータスの確率を観測してグラフを描いてみました。 Y!Jがメールサーバ系を更新したあとで、実メールサーバが120台程度 ある状況下でのサンプリングです。

220(配送可能)ステータスを返すMXの割合の経時変化 (2011/01〜2011/07)
[220を返す確率の6ヶ月状況]

グラフの見方: 縦軸が、配送可能な220ステータスが観測された確率。1.0が良好な状況。 橙線は移動平均。 03/01中ほどの直線区間は震災によるデータ欠け。

2011/06下旬に確率値が急降下していますが、 どういう条件で再度ブラックリスト入りするのかは不明。


▼SPFレコードは関係あるのか?

確かに yahoo.co.jp のMXに対し配送試行している時刻には Y!JのDNSサーバからの TXTレコード 問い合わせが来るようですが、


Aug 10 17:17:32 dnsserver named[1233]: client 203.216.244.9#57316: query: mydomain.co.jp IN TXT

SMTPの接続拒否が SMTPバナーの段階で行われている、 つまりSPF問い合わせに必要な差出人のメールアドレス(MAIL FROM:)を Y!Jのサーバが知るなので、 関連があるとすれば Y!J の実装が間違っているか、 バッチ処理的な ゆるい関係と思われます。 (SPFはマイクロソフト発案なので、Y!が間違っていても別に不思議はない)

なお yahoo.co.jpにはSPFが設定されていますが、 米国 yahoo.com にはありません。 当然ですね


外部リンク

本来は Y!J 自身が提供しなければならないヘルプの操作手順書を、 関係ない第三者が書かなければならないというのが問題の深さを示しているような。


かべ@sra-tohoku.co.jp