2010年07月14日(水) << 前の日記 | 次の日記 >>
これまでの07月14日 編集

■1 続・クロールとDoSの違いと業務妨害罪と[http://www.nantoka.com/~kei/diary/?20100624S1][電子自治体][DoS][セキュリティ] このエントリーをはてなブックマークに追加

6月24日の日記[http://www.nantoka.com/~kei/diary/20100624.html] に追記。
日記の最後の方で、
確認した限りでは、岡崎市立図書館だけが、 件の謎の挙動[http://www.nantoka.com/~kei/diary/?20100621S1#T201006211S1] を示すようだ。
と書いたのだが、他の図書館でも、一度タイムアウトすると、同じCookieを持ってアクセスすると応答がなくなるという同様の現象が発生するところが見つかった。
気づいたのはたまたまだったのだが、 岡崎市立図書館と同じ、MELILを採用している図書館のリストが、 日本のソフト別OPACリスト[http://www.asahi-net.or.jp/~gb4k-ktr/indexjv.htm#melil] にあり、この中で検索ページが.aspになっているものでは同じ現象が発生する様で、発生条件もかなり緩く、
  1. 検索などでのタイムアウト発生
  2. 応答が遅かった場合のキャンセル
  3. 検索結果ページを閲覧していて、画面内の戻るボタン以外でページ遷移を行った場合
に、以降の応答がなくなるという症状が発生する様だ。
検索ページが.aspxになっているものでは、確認した範囲では発生を見ていないので、これは後に改修されたのだろう。
Cookieを削除してやればアクセスできるようになるから、1回程度確認しただけで即座にサーバが停止するということは無いことは確認したが、後述するように私は、 多数回にわたって繰り返せば、何らかの不具合が顕在化してサーバ停止につながるバグを抱えているのではないか と推測しているので、その推測を持っていながら繰り返すことは、それこそDoSとみなされる危険があるので、最低限の回数しか確認はしていない。
この挙動については、 岡崎市立図書館蔵書検索システムの謎[http://www.nantoka.com/~kei/diary/?20100621S1#T201006211S1] で書いたが、なぜこうなったかを、クライアント側でのtcpdumpでの観測からやや大胆に推察すれば、
  1. 「1クライアントからのリクエストを、同時に1つに制限する」というリクワイアメントがあって、Cookieでセッション管理をすることにした。
  2. 各ASP処理の最初で、Cookieに対して他のASP処理が「実行中」かどうかを調べる。「実行中」だったら、「実行終了」まで待つ。
  3. 実行中でなければ、そのCookieに対して「実行中」として処理を行う。
  4. 処理を完了したら、「実行終了」とする。
の様な構造になっていて、タイムアウトやクライアントからの切断等のエラーが発生したときに、エラー処理に何らかの不手際があって、4.の「実行終了」ができていないのでは無いかと推察される。 こうなると、2.が無限か恐らく相当に長いタイムアウトまで待ちに入ってしまう。
この作りは明らかにまずいし、そもそも最初のリクワイアメントが、単に負荷を考えたものならば分かるけれども、 全体が「同時に複数やられると困ったことになる」作りになっているために、それを防ぐためにこのリクワイアメントが出てきたのだとしたら、全体が相当にまずい *1 。 そうだとすると、 Cookieを食わないでアクセスしただけで、困ったことになる からだ *2 。 たいていのクローラはCookieを食わないから、つまりこれは、クロールされただけで困ったことになるということを意味している *3
インターネットに公開することを考えて作られたシステムであれば、最初からこんな設計にはしなかっただろうし *4つぶやいた[http://twitter.com/keikuma/status/16781256147] 様に、 汎用機端末→VB,Accessクラサバ→Webイントラと、実現手段が代替わりする間に、上位設計のやり直しをしないで来て、さらにこれを同じWebだと思ってインターネットにつないでしまったシステム という感じが激しくする。
だとすると、他のMELILを採用している図書館でも、定期的にダウンしたり、館内の検索端末から検索がしばらくできなくなったりという不具合が出ているのではないか。
もし、そうだとすれば、システムの欠陥をたまたま露呈させてしまったからと言って、逮捕される人が出るのは本当に気の毒であるし、そもそも逮捕者が出るのは許されることではない。

netcraftのuptime[http://uptime.netcraft.com/up/graph?mode_u=on&site=www.library.okazaki.aichi.jp&mode_w=off&avg_days=360&submit=Redisplay+Graph]:

netcraftによるuptimeグラフ
Netcraft[http://news.netcraft.com/] というところが、様々なサイトの連続稼働時間の調査を行っている。 定期的にサイトにアクセスをして、前回の起動からの日数 *5 をグラフ化しており、どの程度安定的にサーバが稼働しているのかを知る手がかりにすることができる。
Libra[http://www.libra.okazaki.aichi.jp/] のサーバもその調査対象にたまたま入っている。
残念ながら、今年の5月ごろからしか調査データが無いが、27回ほど計測して、その全てが「0日」という結果になっている。
この調査を信じればだが、そもそも毎日、再起動を行う運用になっているのかも知れない。

Cookieを食わないブラウザ:

世の中にはCookieを食わないブラウザもあるし、やたらとCookieは食べないことにしている人もいるのだけれども、そういう状況でアクセスするとどういう表示がされるのか確認してみた。
結果。何の表示も警告もなく使える。但し、例えば検索結果の一覧から詳細に移動して戻った時等に、検索結果を忘れてしまうという現象が発生する。パラメータを引き渡す術がないのだから挙動は理解できる。
ところが、例えば新着図書一覧等のリンクを辿った時に、 Cookieを食べない様にしていると、結果が表示されるのが遅い ことに気付いた。実測してみると、確かに100msec程余計に時間が掛かっていた。
Cookieを食べるようにした場合、初回の要求はCookieを食べない時と同じで、2回目以降は100msec程度短縮されることになる。
これを素直に解釈すれば、 セッション開始時にDB接続を行って、ページを移動してもそのセッションに紐付いたDB接続を使いまわしている ということだろう。100msecは新たなDB接続に掛かる時間だ *6
だとすると、 Cookieを食わずにアクセスするのは非常にまずい 。 毎回、新たなDB接続が行われて、使い終わったDB接続は、そのままタイムアウトまで解放されないことになることが予想されるからだ。
それでも、エラー処理が完全であれば、順次、セッションがタイムアウトしていって、いずれは定常状態に戻るはずだが、エラー処理に漏れがあって、途中まで構築したオブジェクトを破棄せずに終了してしまうといった何らかの問題があって、二次災害を引き起こすのかも知れない。
従って、 ASP版のMELILにアクセスする場合は、Cookieを受け付ける設定にしておかないとサーバ停止を招きかねない *7 。注意が必要だ。

念力デバッグ:

「念力デバッグ」という仕事があって、ごく稀にお仕事を頂く。
念力デバッグというのは、安楽椅子探偵に似たようなデバッグで、デバッガやデバッグ用のコードを使わずに、直観と論理に基づく推理だけでバグを探すデバッグだ。
通常のデバッグでは、デバッガを用いたり、デバッグ用のコードを走らせたりできるので、念力デバッグの出番はあまりないのだが、既に仕様書やソースコードが存在しなかったり、実機に触れることができなかったり、その全てがなくて、バグレポートだけでバグ解析して運用回避手段を見つける必要があったりという状況があって、そういう場合に、念力デバッグの登場となる様だ。
念力デバッグの結果は、材料が少ないときは特に占いめいていて、「午前2時に、おにぎりを大量に買ってみて下さい。日配品の集計モジュールを書いた人が、コードを書いた当時に経験が浅かったとしたら、集計タイミングに売上が発生する可能性を考慮しておらず、一貫性が保てなくなった可能性があります。推理が正しければ、件の現象が再現すると思われます。」といったレポートを書いて、推理が当たれば一件落着となる訳だ。
閑話休題。今回のケースを念力デバッグしてみると、
  • DB接続をCookieに基づくセッションによって管理する作りになっている。
  • Cookieを食わないクライアントからリクエストを受けると、リクエスト毎にDB接続が生成される。
  • DB接続を含めたサーバリソースは、タイムアウトによってセッションが破棄されるまで解放されず、確保されたままになる。
  • DB接続に必要なサーバリソース(DB接続の上限あるいはコネクションプールと思われる)が不足した状態でリクエストを受け付けると、リソース確保時にエラーが発生するが、このエラー処理が不完全なため、途中まで構築されたオブジェクト等の何らかの別のリソースの解放処理が行われない。
  • このため、エラーが発生している状況でさらにアクセスを行おうとすると、エラー処理の漏れによって、タイムアウトで解放されない形でサーバリソースが枯渇して、ASPの停止に至る。
ということだと思われる。
確認は容易だが、万が一、真似する人が出て「教唆だ」等と言われるとたまらないので、あえて書かない。しかし、その方法は、一般的なクローラの挙動そのものだ。
しかも、この推理が当たっていれば、DB接続の上限に達するまでは、ほとんどサーバの応答時間は変わらないであろうし、エラーが発生したとしても、順次タイムアウトで解放されていくリソースがあるために、散発的にしかエラーが観測されないということが起こり得る。まさに、最後の一アクセスがサーバダウンの引き金を引くロシアンルーレットだ。しかも、停止するのがASPサービスだけだったとしたら、こういう内部事情に気づけと言うのは、それこそ 魔法を要求している[http://twitter.com/rocaz/status/18508517455] に等しい。ネットは魔法使いの世界ではないはずだ。
まだこの結論を信じられない自分がいるのだが、もし本当に、 こんなバグを抱えているのだとしたら、これはもはや、インターネットにはつないではいけないレベルの製品だと言わざるを得ないだろう。
ASP版のMELILを導入していて、実証のためにサーバが停止する可能性があるアクセスを許容してくださる図書館の関係者の方がいらっしゃれば、日時等の実験条件は当然、指定に従うので、ぜひ連絡を頂けないだろうか。

7月23日追記[http://www.nantoka.com/~kei/diary/?20100722S1]:

その後の情報で、「念力デバッグ」の推察をアップデートした。
シリーズ・クロールとDoSの違いと業務妨害罪と(5) - その後の念力デバッグ[http://www.nantoka.com/~kei/diary/?20100722S1] を参照頂きたい。
*1: 例えば、ページを開くたびにDBに接続しに行っていては遅いから、ADOオブジェクトをSessionオブジェクトとして保持しているとか。
*2: 例えば、接続毎にADOオブジェクトを新規に作って、破棄の方はSession_OnEndに任せていたりすると、タイムアウト(デフォルトでは20分)まで、DBセッションが解放されないことになる。
*3: robots.txtが激しいのは、これを問題だと認識していたからだろうか。
*4: 館内検索端末など、台数と操作が限定された端末のみあれば、「例えば」と書いた実装でも、問題が表面化することなく動作するケースが多いだろう。
*5: 恐らくTCPのシーケンス番号を用いているのだと思われる。
*6: 素直でない解釈としては、Cookie食べることを控えめに要求するために、100msecのペナルティを与えているとか?
*7: 当然、この記事を読んで、「試しにCookie無しでアクセスしてみよう」というのは慎んで頂きたい。

■ 関連記事

今日のつぶやき

以上、1 日分です。

指定日の日記を表示

前月 2010年07月 翌月
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

最近の日記

2019年02月17日

#例のグラボを活用する

2019年01月03日

シリーズ5・myHomeAlexaで自分のCDをかける

2018年12月25日

シリーズ4・英語の楽曲・アルバム・アーティスト名をカタカナに直す

2018年12月23日

シリーズ3: Echo Dotがやってきた

2018年12月19日

続・Echo Dotがやってきた

2018年12月18日

続・Echo Dotがやってきた

分野別タイトル一覧


全て
CLIP
SYA!nikki
book
freebsd
hns
magic
おさけ
おしごと
お買いもの
ぐる
ごはん
アクセシビリティ
オープンソース
セキュリティ
音楽
地域情報化
電子自治体
日記

keikuma on Twitter

keikuma Name:前田勝之
Location:長崎市
Web:http://www.nantok...
Bio:前田勝之(まえだかつゆき)。長崎在住。コンサル、SE、プログラマー、 なんとか株式会社代表、非常勤講師(情報セキュリティ)。 セキュアド、テクニカルエンジニア(SV,NW)。サーバ管理とWeb日記を10年ほど。 ネットとリアルの接点に関心あり。食べること・歌うこと・愛すること・作ること・飲むこと。おいしいものがぜんぶすき。

サイト内検索

Google AdSense

Powered by hns-2.19.9, HyperNikkiSystem Project