<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>横浜鯖缶日誌 &#187; バグ</title>
	<atom:link href="http://pandora-lab.com/category/%e3%83%90%e3%82%b0/feed/" rel="self" type="application/rss+xml" />
	<link>http://pandora-lab.com</link>
	<description>なんとも地味な日々の作業記録</description>
	<lastBuildDate>Fri, 05 Feb 2010 19:08:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Net_UserAgent_Mobile のバグについて</title>
		<link>http://pandora-lab.com/2010/02/04/net_useragent_mobile-%e3%81%ae%e3%83%90%e3%82%b0%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/</link>
		<comments>http://pandora-lab.com/2010/02/04/net_useragent_mobile-%e3%81%ae%e3%83%90%e3%82%b0%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 12:27:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[バグ]]></category>

		<guid isPermaLink="false">http://pandora-lab.com/?p=144</guid>
		<description><![CDATA[携帯のユーザエージェントから様々な情報を引き出すことのできるPEAR::Net_UserAgent_Mobile
とても便利で利用させてもらってます。
結構ながいこと地味な開発が続いて、2009年にstableとなったんだけど、まだ致命的なバグがある。
例えば下記のスクリプト

&#60;?
require_once('Net/UserAgent/Mobile.php');
$user_agent = 'DoCoMo/2.0 N900iS(c100;TB;W24H12)';
$agent = Net_UserAgent_Mobile::factory($user_agent);
print "キャリア: ".$agent-&#62;getCarrierLongName()."\n";
print "機種:".$agent-&#62;getModel();
?&#62;

ユーザエージェントを

$user_agent='Vodafone/1.0/V705SH (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)';

に変えると

Fatal error: Call to undefined function:  getcarrierlongname()

とエラーになってしまう。
自分で解析できないユーザーエージェントだと、無視せずにエラーを返して強制終了してしまう。
このバグは致命的。先々未知のユーザエージェントは続々と登場するわけで、その度にエラーが出ることになってしまう。
調べてみると、かなりの人が同じ症状で困っているし作者にバグ報告もされているが、その場しのぎで根本的な問題が修正がされることなくstableとなった。
対処方法

&#60;?
require_once('Net/UserAgent/Mobile.php');
$user_agent='Vodafone/1.0/V705SH (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)';
$agent = Net_UserAgent_Mobile::factory($user_agent);
if (method_exists($agent,'isNonMobile')){
	print "キャリア: ".$agent-&#62;getCarrierLongName()."\n";
	print "機種:".$agent-&#62;getModel();
}

のように

if (method_exists($agent,'isNonMobile')){
～
}

でラップしてスルーさせればOK
]]></description>
			<content:encoded><![CDATA[<p>携帯のユーザエージェントから様々な情報を引き出すことのできる<a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">PEAR::Net_UserAgent_Mobile</a><br />
とても便利で利用させてもらってます。<br />
結構ながいこと地味な開発が続いて、2009年にstableとなったんだけど、まだ致命的なバグがある。</p>
<p>例えば下記のスクリプト</p>
<pre class="brush:php">
&#60;?
require_once('Net/UserAgent/Mobile.php');
$user_agent = 'DoCoMo/2.0 N900iS(c100;TB;W24H12)';
$agent = Net_UserAgent_Mobile::factory($user_agent);
print "キャリア: ".$agent-&#62;getCarrierLongName()."\n";
print "機種:".$agent-&#62;getModel();
?&#62;
</pre>
<p>ユーザエージェントを</p>
<pre>
$user_agent='Vodafone/1.0/V705SH (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)';
</pre>
<p>に変えると</p>
<pre>
Fatal error: Call to undefined function:  getcarrierlongname()
</pre>
<p>とエラーになってしまう。<br />
自分で解析できないユーザーエージェントだと、無視せずにエラーを返して強制終了してしまう。<br />
このバグは致命的。先々未知のユーザエージェントは続々と登場するわけで、その度にエラーが出ることになってしまう。</p>
<p>調べてみると、かなりの人が同じ症状で困っているし作者にバグ報告もされているが、その場しのぎで根本的な問題が修正がされることなくstableとなった。</p>
<h1>対処方法</h1>
<pre class="brush:php">
&#60;?
require_once('Net/UserAgent/Mobile.php');
$user_agent='Vodafone/1.0/V705SH (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)';
$agent = Net_UserAgent_Mobile::factory($user_agent);
if (method_exists($agent,'isNonMobile')){
	print "キャリア: ".$agent-&#62;getCarrierLongName()."\n";
	print "機種:".$agent-&#62;getModel();
}
</pre>
<p>のように</p>
<pre>
if (method_exists($agent,'isNonMobile')){
～
}
</pre>
<p>でラップしてスルーさせればOK</p>
]]></content:encoded>
			<wfw:commentRss>http://pandora-lab.com/2010/02/04/net_useragent_mobile-%e3%81%ae%e3%83%90%e3%82%b0%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>はんにんさがし</title>
		<link>http://pandora-lab.com/2010/01/01/%e3%81%af%e3%82%93%e3%81%ab%e3%82%93%e3%81%95%e3%81%8c%e3%81%97/</link>
		<comments>http://pandora-lab.com/2010/01/01/%e3%81%af%e3%82%93%e3%81%ab%e3%82%93%e3%81%95%e3%81%8c%e3%81%97/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 16:47:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[バグ]]></category>

		<guid isPermaLink="false">http://pandora-lab.com/?p=100</guid>
		<description><![CDATA[数カ月前からウェブサーバのトラフィックの上がりが、ノコギリ状に増えている問題があった。
状況としては
NFSのreadが定期的に頻発している。

NFSのwriteも中長期で見ると右肩上がり

短期で見ると特徴的なノコギリ波形を示す

１時間に３～４回ペースで定期的に急激なNFS read/writeが生じている。
NFSの微々たるreadだし、放っておいてもサービスにはまったく問題ないんだけど、グラフが汚れて見辛いので原因追求。
長中期で見るとreadの回数は調子こいて右肩上がりのまま留まることを知らないので、このままエスカレートしていくのを放っておくわけにもいかない。
犯人の追跡開始。
・apacheのログ解析では不明だった
・mod_securityでPOSTを取ったが問題は見当たらなかった
そのため
・tcpdump port nfs -nxXs 6000 &#124; grep read -C 20
・sar -n NFS 1 0
を同時に記録して解析を進めていくことにした。
・sarで３０秒間ほど急激なreadが定期的に発生していることを確認。

・一時的にreadが急激に上がった時間をメモしておく
10時36分31秒
10時51分39秒
11時05分58秒
11時21分14秒
11時36分03秒
次に、上記時刻のtcpdumpのhexdumpをみてみる。
すると11時21分17秒に一意のデータである特定キーワード(メールアドレス)が確認できたので、これを鍵にすることにした。

・ファイルサーバーからこのメールアドレスを全ファイル検索
grep -r 'drfadsee3@yahoo.com' ./
その結果
バイナリー・ファイル./ユーザA/blog/db/comment.email.idxは一致しました
バイナリー・ファイル./ユーザA/blog/db/comment.dbは一致しました
とユーザAのウェブスペースにこのメールアドレスを含むファイルがあることが判明。
ユーザAのアクセスログからPOSTしている時間だけ抜き取ってみた。
するとメモした時間とアクセスログのPOSTの時間が一致した。

・apacheのログ
grep ユーザA apache_log &#124; grep blog &#124; grep POST
09:18:13 :31367: &#91;gw4.winserversecure.com&#93; 85.17.145.7 ユーザーA POST /blog/mt-tb.cgi/145 HTTP/1.0 500 -
09:20:20 :31153: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
09:35:41 :9147: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
09:50:56 :21595: &#91;93.174.93.58&#93; ]]></description>
			<content:encoded><![CDATA[<p>数カ月前からウェブサーバのトラフィックの上がりが、ノコギリ状に増えている問題があった。<br />
状況としては</p>
<p>NFSのreadが定期的に頻発している。</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client-day.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-126" title="before_nfs_client-day" src="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client-day.png" alt="" width="495" height="532" /></a></p>
<p>NFSのwriteも中長期で見ると右肩上がり</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client2-year.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-125" title="before_nfs_client2-year" src="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client2-year.png" alt="" width="495" height="484" /></a></p>
<p>短期で見ると特徴的なノコギリ波形を示す</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client2-day.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-124" title="before_nfs_client2-day" src="http://pandora-lab.com/wp-content/uploads/2010/01/before_nfs_client2-day.png" alt="" width="495" height="484" /></a></p>
<p>１時間に３～４回ペースで定期的に急激なNFS read/writeが生じている。<br />
NFSの微々たるreadだし、放っておいてもサービスにはまったく問題ないんだけど、グラフが汚れて見辛いので原因追求。<br />
長中期で見るとreadの回数は調子こいて右肩上がりのまま留まることを知らないので、このままエスカレートしていくのを放っておくわけにもいかない。<br />
犯人の追跡開始。</p>
<p>・apacheのログ解析では不明だった<br />
・mod_securityでPOSTを取ったが問題は見当たらなかった</p>
<p>そのため<br />
・tcpdump port nfs -nxXs 6000 | grep read -C 20<br />
・sar -n NFS 1 0<br />
を同時に記録して解析を進めていくことにした。</p>
<p>・sarで３０秒間ほど急激なreadが定期的に発生していることを確認。</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/WS000000.png" rel="lightbox[100]"><img class="alignnone size-thumbnail wp-image-112" title="WS000000" src="http://pandora-lab.com/wp-content/uploads/2010/01/WS000000-500x729.png" alt="" width="500" height="729" /></a><br />
・一時的にreadが急激に上がった時間をメモしておく<br />
10時36分31秒<br />
10時51分39秒<br />
11時05分58秒<br />
11時21分14秒<br />
11時36分03秒</p>
<p>次に、上記時刻のtcpdumpのhexdumpをみてみる。<br />
すると11時21分17秒に一意のデータである特定キーワード(メールアドレス)が確認できたので、これを鍵にすることにした。</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/WS000001.png" rel="lightbox[100]"><img class="alignnone size-thumbnail wp-image-113" title="WS000001" src="http://pandora-lab.com/wp-content/uploads/2010/01/WS000001-500x729.png" alt="" width="500" height="729" /></a></p>
<p>・ファイルサーバーからこのメールアドレスを全ファイル検索</p>
<pre>grep -r 'drfadsee3@yahoo.com' ./</pre>
<p>その結果</p>
<pre>バイナリー・ファイル./ユーザA/blog/db/comment.email.idxは一致しました
バイナリー・ファイル./ユーザA/blog/db/comment.dbは一致しました</pre>
<p>とユーザAのウェブスペースにこのメールアドレスを含むファイルがあることが判明。<br />
ユーザAのアクセスログからPOSTしている時間だけ抜き取ってみた。<br />
するとメモした時間とアクセスログのPOSTの時間が一致した。</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/WS000002.png" rel="lightbox[100]"><img class="alignnone size-thumbnail wp-image-119" title="WS000002" src="http://pandora-lab.com/wp-content/uploads/2010/01/WS000002-499x615.png" alt="" width="499" height="615" /></a></p>
<p>・apacheのログ</p>
<pre>grep ユーザA apache_log | grep blog | grep POST
09:18:13 :31367: &#91;gw4.winserversecure.com&#93; 85.17.145.7 ユーザーA POST /blog/mt-tb.cgi/145 HTTP/1.0 500 -
09:20:20 :31153: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
09:35:41 :9147: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
09:50:56 :21595: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
10:05:58 :24286: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
10:20:41 :29154: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
10:36:01 :32163: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
10:51:07 :3821: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
11:05:28 :6609: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
11:20:44 :8161: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
11:35:33 :21388: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
11:51:17 :30978: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
12:06:07 :6032: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
12:21:20 :13718: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
12:37:55 :25341: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
12:51:58 :5509: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
13:07:38 :14897: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
13:23:05 :21912: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
13:38:30 :31049: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
13:53:28 :9117: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
14:08:33 :20520: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
14:11:35 :12844: &#91;66.90.77.6&#93; 66.90.77.6 ユーザーA POST /blog/mt-tb.cgi/81 HTTP/1.0 200 79
14:23:46 :28173: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
14:34:18 :4474: &#91;xanhlacay.info&#93; 74.86.238.186 ユーザーA POST /blog/mt-tb.cgi/105 HTTP/1.0 500 -
14:39:20 :8180: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
14:54:36 :19139: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
15:09:06 :30925: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
15:24:28 :7162: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
15:39:50 :17200: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
15:54:30 :29185: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -
16:10:49 :6930: &#91;93.174.93.58&#93; 93.174.93.58 ユーザーA POST /blog/mt-comments.cgi HTTP/1.1 500 -</pre>
<p>原因はユーザAに定期的に訪れる掲示板SPAMのボットによるものであることがわかった。</p>
<p>一般的にこの手のボットからのアクセスはapacheのログ解析やmod_securityのログ解析だけで比較的簡単に発見できるものだけど、今回は特異なケースだった。<br />
SPAMをPOSTされて<strong>500エラーを返しているにもかかわらず、mt-comments.cgiは実際に書き込みを行っているんである</strong>(もちろんコメント自体にSPAMは表示されないし、ログにも500エラーしか残らない)。<br />
そもそも特定の変則的なメッセージのPOSTで500エラーが発生する時点でMTの不具合だろう。<br />
他でこんな変態ポストをされたら犯人特定は極めて困難だと思う。</p>
<h1>対策方法</h1>
<p>・GeoIPでアクセス規制を入れる</p>
<pre>GeoIPEnable On
Order deny,allow
deny from all
SetEnvIf GEOIP_COUNTRY_CODE JP AllowCountry
Allow from .googlebot.com
Allow from .yahoo.net
Allow from .msn.com
Allow from .naver.jp
Allow from env=AllowCountry
</pre>
<p>結果、下記のように問題は解決した。</p>
<p><a href="http://pandora-lab.com/wp-content/uploads/2010/01/after_nfs_client-day.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-122" title="after_nfs_client-day" src="http://pandora-lab.com/wp-content/uploads/2010/01/after_nfs_client-day.png" alt="" width="495" height="532" /></a><br />
<a href="http://pandora-lab.com/wp-content/uploads/2010/01/after_nfs_client2-day.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-121" title="after_nfs_client2-day" src="http://pandora-lab.com/wp-content/uploads/2010/01/after_nfs_client2-day.png" alt="" width="495" height="484" /></a><br />
<a href="http://pandora-lab.com/wp-content/uploads/2010/01/after_if_eth0-day.png" rel="lightbox[100]"><img class="alignnone size-full wp-image-120" title="after_if_eth0-day" src="http://pandora-lab.com/wp-content/uploads/2010/01/after_if_eth0-day.png" alt="" width="495" height="280" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://pandora-lab.com/2010/01/01/%e3%81%af%e3%82%93%e3%81%ab%e3%82%93%e3%81%95%e3%81%8c%e3%81%97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
