携帯メール配信 成功術

記事/携帯メール… 04.6.2 10:16 AM ページ82
迷惑メール対策に
負けない!
Perl & qmailで実践!
携帯メール配信
成功術
小林 博幸 KOBAYASHI Hiroyuki ● [email protected]
携帯メール配信プログラム
の基本
はじめに
携帯電話によるIP 接続サービス契約数は,本稿執
それでは実際に,携帯3キャリア(NTTドコモ,ボ
筆時点ですでに,7000 万件を超えています.Web 開
ーダフォン,KDDI)向けの簡単なPerl スクリプトを
発を仕事にされている方なら,携帯電話向けサービス
例にしながら,見ていきたいと思います(リスト1)
.
の開発に関わったことがある人も多いのではないでし
qの@mail という配列がメールアドレスのリスト,
ょうか.実は,日本で一番多いユーザエージェントは
wの$subjectがメールの件名,eの$bodyがメールの
はInternet Explorerではなく,ドコモのブラウザかも
本文になります注2.
しれません;-) 本稿では,携帯電話向けサービスの中
rではSMTPプロトコルで通信するためのモジュー
でもニーズが高いメール配信の実際について解説しま
ルであるNet::SMTP を用いて,自ホスト(127.0.0.1)
す.
のSMTP サーバに接続しています.他にsendmail コ
携帯電話を対象としたメール配信の場合,各携帯
マンドやqmail-injectコマンドなどのMUA(Mail User
キャリアがいわゆる迷惑メール対策をとっていること
Agent)注3 を直接叩いて配信するという方法が挙げら
もあり,PC 向けのメールシステム開発とは異なるノ
れますが,
ウハウが必要になります.筆者は現在,主に携帯電話
向けのWebアプリケーション開発に関わっています注1
が,こうした問題は携帯向けメール配信システムを開
発する際にはほぼ必ず考慮しなくてはならないと言え
るのではないかと思います.ここではまず,携帯向け
¡ネットワークを経由してメールを送信することがで
きる
¡複数サーバに転送するなど負荷分散することができ
る
¡他プロセスをfork(作成)しない
メールプログラムの基本を概観し,続いて,いわゆる
「迷惑メール対策」対策について解説していきます.
などの利点があるので,Net::SMTPモジュールを利用
なお,本稿では開発言語にPerl,MTA(Message
してSMTPで送るのがよいでしょう.実際に,配信パ
Transfer Agent)にqmail を使用した場合を例にとっ
フォーマンス向上のためにサーバを増やす場合は,こ
て解説します.別の言語,MTA を使用している場合
の接続先を増やす方法が適用できます.
には,適宜置き換えて読んでくだされば幸いです.
tではメールの各種ヘッダを定義しています.From
注 1)㈱モバイルファクトリーにて,携帯向け「着メロ」インセンティヴ型広告メール媒体などを開発,数社に OEM 供給しています.
注 2)説明を簡単にするための便宜上の仕様です.
注 3)電子メールの読み書きやメールサーバへの送信,サーバの自分のメールボックスからのメールの受信などを行うソフトやアプリケ
ーション.ここでは,SMTP サーバ(MTA)に対して,メールを配信するクライアントコマンドを指しています.
82● WEB +DB PRESS Vol.21
記事/携帯メール… 04.6.2 10:16 AM ページ83
携帯メール配信 成功術
は差出人,Toは宛先です.Subjectはここでは日本語
で,From ヘッダとは別に渡されます.宛先が存在し
文字コード用汎用モジュールであるJcode モジュール
ないなどのエラーが発生した場合,この宛先に返送さ
を使用して,MIMEエンコードしています.メールの
れます.
oのNet::SMTP モジュールのto メソッドで,宛先
ヘッダにはASCII文字しか使えないことになっており,
件名(Subject)もその例外ではありません.MIME
を指定します.ここでは,Toヘッダと同じアドレスに
エンコードは件名に日本語を使用したいと
きに用いる符号化の手法の1つです.
あいうえお → =?ISO-2022-JP?B?GyRCJ
CIkJCQmJCgkKhsoQg==?=
このように「あいうえお」という文字を
変換して,Subjectヘッダとして使用します.
Content-Type はメールの種別,文字コ
ードなどを指定しています.携帯向けメー
ルではShift-JISやUTF-8などのコードを受
け付ける機種もあるようですが,ここでは
●リスト 1 Perl による携帯メール配信プログラム
#!/usr/bin/perl
use
use
use
use
use
strict;
Net::SMTP;
Jcode;
Time::Piece;
Digest::MD5;
my @mail = ('[email protected]'); q
my $subject = 'テストメール'; w
my $body = <<'MAIL' e
これはテストです
タンダードであるISO-2022-JP(JIS コー
[email protected]
MAIL
;
ド)で送っています注4.
my $smtp = Net::SMTP->new('127.0.0.1') or die($!); r
日本語のメール配信におけるデファクトス
yではMessage-ID というヘッダを生成
for my $mail ( @mail ){
しています.RFC2822,RFC822では,メ
my %header = (From
To
Subject
'Content-Type'
ー ル に は 唯 一 無 二 で <local-part "@"
domain> という形式のMessage-ID を付加
Message-ID を自動で付加するMTA も存
在するようですが,qmail は付加しない実
$header{Date} =
Time::Piece->new->strftime('%a, %d %b %Y %H:%M:%S +0900'); u
装ですので,MUA 側で付加します.
local-part には現在時刻,無名ハッシュ
my $env_from = $mail;
$env_from =˜ s|@|=|;
$env_from = sprintf('error-%[email protected]',$env_from); !0
のアドレス,乱数,プロセス番号をもと
に,MD5 の値を生成し,プロセス番号と
結合しています.domain には環境変数
$smtp->mail($env_from); i
$smtp->to($mail); o
HOST を使用しています.
$smtp->data();
uではTime::Pieceモジュールを用いて,
while( my ($k,$v) = each(%header) ){
$smtp->datasend("$k: $v\n");
}
現在時刻を送信時間としてヘッダに指定し
ます.
$smtp->datasend("\n");
$smtp->datasend(Jcode->new($body,'euc')->jis); !1
$smtp->dataend;
iのNet::SMTP モジュールのmail メソ
います.エンベロープFROMとは,SMTP
'[email protected]', t
$mail,
Jcode->new($subject,'euc')->mime_encode,
'text/plain;charset=ISO-2022-JP');
$header{'Message-ID'} = sprintf('<%s.%s@%s>', y
substr(Digest::MD5::md5_hex(time().{}.rand().$$),0,32), $$,
$ENV{HOST});
しなければいけないとされています.この
ッドで,エンベロープFROM を指定して
=>
=>
=>
=>
}
$smtp->quit;
で通知されるメールの差出人情報のこと
注 4)絵文字などを送る必要がある場合は,Shift-JIS などにする必要があるでしょう.
WEB +DB PRESS Vol.21 ●83
記事/携帯メール… 04.6.2 10:16 AM ページ84
Perl & qmail で実践!
迷惑メール対策に
負けない!
●図 1 送信されるメール
Subject: =?ISO-2022-JP?B?GyRCJUYlOSVIJWEhPCVrGyhC?=
Content-Type: text/plain;charset=ISO-2022-JP
To: [email protected]
From: [email protected]
Date: Sat, 17 Apr 2004 21:39:29 +0900
Message-ID: <[email protected]>
これはテストです
が違ってきます.
配信プログラムはとっくに実行が終了しているのに,
実際の端末にメールが届かないという現象が発生しま
す.これは,Net::SMTPモジュールで配信queueに入
れることは完了したが,配送先のキャリアが用意して
いるSMTPサーバが,一時的に受信を拒否するため配
[email protected]
送不能となって,queueに未配送メールが溜まってい
ることが原因です.
●図 2 qmail-qstat コマンド
topaz.intra# /var/qmail/bin/qmail-qstat
messages in queue: 98
messages in queue but not yet preprocessed: 0
●図 3 qmail-qread コマンド
queue にどれくらいメールが溜まっているのかを確
認するためのコマンドが,qmail-qstat です(図2)
.
この例では,98通未配送になっていることがわかり
ます.実際の宛先を確認するコマンドがqmail-qread
です(図3).上の行がエンベロープFROM,下の行
topaz.intra# /var/qmail/bin/qmail-qread | head
17 Apr 2004 07:02:46 GMT #634892 740 <error-******@topaz.intra>
remote ********@docomo.ne.jp
17 Apr 2004 07:03:51 GMT #634984 732 <error-******@topaz.intra>
remote ********@c.vodafone.ne.jp
17 Apr 2004 07:03:33 GMT #634938 739 <error-******@topaz.intra>
remote ********@docomo.ne.jp
17 Apr 2004 07:04:49 GMT #635053 737 <error-******@topaz.intra>
remote ********@docomo.ne.jp
17 Apr 2004 07:05:54 GMT #635145 746 <error-******@topaz.intra>
remote ********@ezweb.ne.jp
が宛先のような結果が表示されます.
PC 向けのメール配信でも,配信先のメールサーバ
がダウンしていたり,名前が解決できない宛先の場合
などに同様な現象が発生しますが,あくまでも例外的
な状況でのみ発生し,大概のメールはすぐに受信され
るはずです.
一方,携帯向けのメール配信では,配信先ドメイ
なりますが,Toヘッダに違うアドレスを指定すること
ンが事実上3 つのみで,しかも,なかなか受信してく
ができ,実際に配信されるのは,このtoメソッドで指
れないといった状況が発生します.これが「迷惑メー
定したアドレスになります.
ル対策」の一環である,受信ブロックです.
!0では,error-(メールアドレス)という動的なア
迷惑メール対策
カウントに返送されるようにしてあります.これは,
どの宛先に対して配送不能のエラーが起きたかを記録
するためです.詳しくは後で述べるエラーメール削除
で解説します.
!1では,Content-Type ヘッダでcharset=ISO-2022-
悪質なSPAM業者が携帯メール宛に無作為にメール
を送り続ける行為が横行し,問題となっていることを
ご存知の方も多いと思います.一時は携帯間の正規
JP としたとおり,Jcode モジュールでJIS に変換して
のメールですら遅延が発生してしまったこともあり,
送信しています.
各キャリアが対策をせざるを得ない状況のようです注5.
実際に送信されるメールの内容は,図1 のようにな
具体的には,以下のようなブロックを受けます.
ります.
q同時接続セッション数を絞る
配信したはずなのに送ら
れないメール
同時に接続するセッション数を絞るというやり方を
とるもので,配信元IP を元に制限しているようです.
ができたと思います.ここまでではPC 向けの配信と
w宛先不明メールを受け取ると一定
時間セッションを受け付けない
まったく同じですが,これが大量配信になると,状況
宛先不明のメールを連続して送った場合,SPAMと
リスト1 のようなスクリプトで,携帯メールの配信
注 5)メールを受け取れるように,サーバを増強するのが筋だと思うのですが….
84● WEB +DB PRESS Vol.21
記事/携帯メール… 04.6.2 10:16 AM ページ85
携帯メール配信 成功術
みなして,一定時間セッションを受け付けないという
ものです.まったく受けつけない状況が発生するので,
MTA のログはエラーの山となり,いつまでもqueue
が減少しない状況が発生します.
実際には, 421 などのコードを返してセッション
を切られてしまいます(図4)
.
eセッションを張ろうとしたま
ま黙り込んでしまう
セッションを張ろうとしたまま,応答がなくなって
qqueue の lifetime
qmailのデフォルトでは,queueに入っていることが
できるlifetimeは7日間になっていますので,これはこの
ままでよいでしょう.これはqueuelifetimeというファイ
ルで設定できます.lifetimeが極端に短い場合は,バウ
ンスされないように,調整する必要があります.
wtimeout 値
しまう現象です.タイムアウトするまで応答を待って
リモートのSMTP サーバが応答するまでのtimeout
しまうため,現実的に配信ができなくなる効果を狙っ
を設定するとよいでしょう.qmailでは,timeoutremote
ているものと思われます(図5)
.
で設定できます.デフォルト値は1200秒ですので,10
実際のログには図6 のように記録されます.
秒などにすれば,応答しないタイプのブロックに対し
先ほども触れた
は,RFC821 によると,
て効果があります.ただしあまりにもきつい閾値を設
Service not avaliable(サービス利用不可能)とあり,
定すると,配信が成功したにもかかわらず失敗したと
一時的に接続を拒否することを示します.deferral
誤認して,二重配送の原因にもつながりますので,注
しきいち
421
(延期)の扱いになりますので,qmailは再度queueに
メールを残し,再送するということになります.EZweb
の例は接続すらできなかったときのログです.
意してください.
e再送間隔の調整
qmail の場合,再送間隔はある計算式によって,だ
「迷惑メール対策」対策
んだん長くなっていくような仕様になっています.実
際には7 分,20 分,33 分…のように延びていきます.
このままですと,メール配信が極端に遅延して,深
夜に届いたり,翌日に届いてしまうことになります.
下手したら1 週間後になんてこともあります.メール
配信に対してお金が関わっていること(広告など)も
多いでしょうから,ほとんどの場合は改善しなければ
ならないと思います注6.そこで以下に,筆者が実行し
た「迷惑メール対策」の対策方法を挙げてみたいと思
います.
●図 4 一定時間セッションを受け付けない
topaz.intra% telnet mx.t.vodafone.ne.jp 25
Trying 210.175.1.210...
Connected to mx.t.vodafone.ne.jp.
Escape character is '^]'.
421
Connection closed by foreign host.
●図 5 セッションを張ろうとしたまま黙り込んでしまう
topaz.intra% telnet mx.t.vodafone.ne.jp 25
Trying 210.175.1.210...
(応答がない.ただの屍のようだ…)
●図 6 配信不能ログの例
¡NTTドコモ
*** ** ******** ***** qmail: 1082098857.198406 delivery 84027: deferral: Connected_to_203.138.180.112_
but_greeting_failed./Remote_host_said:_421_Service_not_available,_closing_transmission_channel
¡ボーダフォン
*** ** ******** ***** qmail: 1082131375.545234 delivery 13919366: deferral: Connected_to_210.175.123.23_
but_greeting_failed./Remote_host_said:_421/
¡EZweb(KDDI)
*** ** ******** ***** qmail: 1081834456.739041 delivery 656816: deferral: Connected_to_219.125.149.6_
but_connection_died._(#4.4.2)/
注 6)というか筆者がそうでした;-)
WEB +DB PRESS Vol.21 ●85
記事/携帯メール… 04.6.2 10:16 AM ページ86
Perl & qmail で実践!
迷惑メール対策に
負けない!
これでは,ブロックされるたびに,パフォーマンスが
落ちることになりますので,再送間隔を調整してやる
tSMTP サーバを増やす
必要があります.qmail の場合,qmail-send プロセス
各キャリアの迷惑メール対策は基本的にグローバルIP
にALRMシグナルを送ることにより,現在queueに残
アドレスごとに処理されていますので,IPアドレスを増
っているメールに対して,即時に再送してくれます.
やすことにより,単純にパフォーマンスが上がります.
cron などで,定期的にALRMシグナルを送ってやる
コストがかかりますが,単純で有効な手段です.
注7
とよいでしょう.
topaz.intra# killall -ALRM qmail-send
rエラーアドレスの削除
特定接続サービス
正規にメールアドレスを取得し,パーミッションを
得ているにもかかわらずメールが遅延してしまうとい
宛先不明アドレスをなくすために,エラーになった
う状況に,不満を持つ開発者も多いと思います.そん
宛先に再度配信しないように,リストを常にクリーン
な中,
「特定接続サービス」というサービスが2002 年
な状態に保つのも有効です.
3月にNTTドコモより開始され,さらに2003年9月に
qmailでは拡張アドレスというしくみがあります.ユ
ーザerror は[email protected] というメールだけでは
ボーダフォンが追従,まったく同様のサービスが開始
されました.
なくerror-****@topaz.intra というメールアドレスも
これは,通常,DNSのMXレコード注8 から解決され
管理できる機能です.これを利用することで,エラー
るサーバとは違う,特定の別の経路を用意してくれる
が起きた場合,どのメールアドレスでエラーが起きた
というもので,執筆時現在(2004年6月)
,NTTドコ
のかを簡単に記録することができます.
モとボーダフォンより提供されています(図7)
.
.qmail-error-defaultというファイルを,以下の内容で
qmailaliasに置くと,/path/to/error.plが起動されます.
配信元のIPアドレスを申し込むと接続を許可してく
れるというもので,IPアドレスごとに契約する必要が
あります.また,同時接続セッションを増やすことも
|/path/to/error.pl
error.pl によってEXT2 などの環境変数で,拡張の
部分の文字列を取得できますので,バウンス先のアド
レスを,たとえば,[email protected] に送る際,
できます.
qmail での設定例
qmail では,人為的にメールの配信経路を指定する
には, M X レコードや A レコード注9 ではなく,
error-kobayasi%[email protected]
smtproutesという設定ファイルを作成します.
としておくことで,配送不能になった場合,error.pl
が起動され,どのアドレスが配送不能になったかを認
docomo.ne.jp:[キャリアより通知されたIP]
識することができます.次回からリストにこのメール
このようなファイルを作成すると,@docomo.ne.jp
アドレスを加えないように処理することで,宛先不明
のメールは,設定されたIPのSMTPサーバに対してリ
の率が落ち,パフォーマンスが改善します.
レーするようになります.設定したあと,反映させる
にはqmail-send にALRM シグナルを送ってください.
topaz.intra# killall -ALRM qmail-send
注 7)UNIX 系の OS で,コマンドなどを自動的に決まった時間に実行させるツール.
注 8)MX(Mail eXchanger)レコードは,利用ドメイン名宛のメールの配送先であるホスト名を定義するレコードです.mail.topaz.intra
のように IP アドレスではなく,名前で指定するものです.
注 9)ホスト名から IP アドレスへの対応を示すレコードです.メールの配信経路は,MX レコードがない場合,A レコードで解決した IP
アドレスのホスト先に配送されます.
86● WEB +DB PRESS Vol.21
記事/携帯メール… 04.6.2 10:16 AM ページ87
携帯メール配信 成功術
図 7 特定接続サービスのしくみ
サーバ
特定接続サービス
専用のSMTPサーバ
特定接続
携帯電話
サーバ
一般接続
遅延
携帯電話
MXレコードで解決
されるSMTPサーバ
サーバ
キャリア
一般接続
また,ワイルドカードを含ませることもできます.
図 8 smtproutes で経路を決める方法
配信プログラム
.vodafone.ne.jp:[キャリアより通知されたIP]
このように先頭を「.」にすると,サブドメインすべ
てに対して有効になりますので,@*.vodafone.ne.jp
@docomo.ne.jp
のメールを特定接続サービス用のSMTPサーバにリレ
192.168.200.1
@vodafone.
ne.jp
@ezweb.ne.jp
ーすることができます.
特定接続サービスの実際
192.168.200.2
192.168.200.3
192.168.200.4
筆者が実際に導入してみたところ,NTT ドコモの
特定接続サービスは劇的な効果が見られました.配信
するメールのFrom アドレスが限定されるという制限
特定接続
特定接続
はあるものの,基本的に同時接続数のみの制限になる
ので,コネクションを蹴られるということがなく,安
定した配信が可能になりました.一方ボーダフォンで
ブルにつながる可能性があります.さらに特定接続サ
は,通常のMXで決定される経路と同様のブロックが
ービスを利用する場合は,基本的にIP ごとの契約で
行われています(2004 年6 月現在)
.宛先不明のアド
すので,配信サーバをキャリア別に分け,キャリアご
レスを連続して送るとまったく接続を受け付けなくな
とに対応できる環境が望ましいでしょう.
るなどのブロックが生じるので,特定接続の恩恵は薄
いのが現状のようです.
配信サーバをキャリア別
に分ける
迷惑メール対策はキャリアごとに状況が異なり,そ
れぞれに適した対応が必要です.また,ブロック方法
キャリア別に配信プログラムで接続先SMTPサーバ
を分ける方法もありますが,qmailではsmtproutesで
経路を決めてあげる方法が,汎用的で,トラブルにも
対応できます(図8)
.
ここでは,まず配信サーバ192.168.200.1 のSMTP
に配信し,192.168.200.1 のsmtproutes で各キャリア
ごとに配信サーバにリレーしています.
が一定でない節が見られ,画一的な方法だけではトラ
WEB +DB PRESS Vol.21 ●87
記事/携帯メール… 04.6.2 10:16 AM ページ88
Perl & qmail で実践!
迷惑メール対策に
負けない!
図 9 MRTG によるメール配信の監視
任意のコマンドを指定できますので,さまざまな状態
をグラフ化するツールとして使うことができます.設
定ファイルmrtg.cfgのTarget の項目を
Target[queue-size]: `/var/qmail/bin/qmail-qstat
| /usr/bin/cut -d ":" -f2`
192.168.200.1のsmtproutes
にすることより,図9 のようなグラフが生成されます.
docomo.ne.jp:[192.168.200.2]
.vodafone.ne.jp:[192.168.200.3]
ezweb.ne.jp:[192.168.200.4]
突然の「迷惑メール対策」
にどう対処するか
各キャリア別配信サーバでは,192.168.200.1からの
筆者の環境では,突然の迷惑メール対策によるブロ
メールを転送してもよいように,qmail-smtpd を起動
ックのため,ほとんど配信ができないといった状況が発
した際に指定した,.cdbファイル注10 で許可します.
生したことがありました.昨日の今までは配信できてい
たのに…というのが,迷惑メール対策の実情です注11.
192.168.200.1:allow,RELAYCLIENT=""
:allow
こんなとき,最後の手段として役に立ったのが,他の
サーバへリレーして,違うIPで送るというものです.
また,192.168.200.2,192.168.200.3 では,各キャ
迷惑メール対策はIPベースでブロックしているらし
リアの特定接続サービス用の経路をsmtproutes で指
く,まったく別のIPで送るとすんなり浮けつけてくれ
定します.
る事 例 がありました. 具 体 的 には, 一 時 的 に
smtproutesで他サーバへリレーさせました;-)
192.168.200.2のsmtproutes
docomo.ne.jp:[キャリアより通知されたIP]
192.168.200.3のsmtoroutes
.vodafone.ne.jp:[キャリアより通知されたIP]
まとめ
以上,携帯電話のメール配信の現場でどのような現
象が起きているか,またそれに対して考えられる対処法
などを考察してみました.メールが止まると「交通事故
メール配信監視
や離婚以上のショック」との調査注12 もあるくらいのメ
ール配信システムは,トラブルがあると胃が痛いシステ
「迷惑メール対策」が未来永劫同じ状況であるとは
ムの上位に挙げられるのではないでしょうか注13.特に携
考えにくく,ある日突然ブロックされたなどの現象が
帯向けのメール配信では,迷惑メール対策の大きな壁
発生するかもしれませんので,メールの配信状況を監
が立ちはだかり,困難も多いようです.状況も刻々と変
視するとよいと思います.筆者の環境では,queueの
わっていきますが,これから携帯向けのメール配信サー
数が閾値よりも多いと警告メールがくるようになって
ビスを開発される方にとって,この記事が1つの指針に
います.また,MRTGを使用して,全サーバのqueue
なれば幸いです.#
の状況を一目で確認できるようになっています.MRTG
は主にネットワークの負荷を監視するツールですが,
注 10)tcprules コマンドでつくられる,設定用のバイナリ形式ファイル.D.J.Bernstein 氏のアプリケーションに使われています.
注 11)画一的にすると簡単に対策されてしまうため,わざと対策方法を変えているのではないかと筆者は疑っています.
注 12)http://hotwired.goo.ne.jp/news/news/20030730206.html
注 13)ミスが大きく目立って問題となってしまうからでしょうか.多重配信,配信遅延など….筆者は胃が痛いです.
88● WEB +DB PRESS Vol.21