こんにちは、趣味や業務で大手ポータルサイトのサービスで稼働しているいくつかのクローラの開発とメンテナンスを行っているmalaです。
さて先日、岡崎市立中央図書館Webサイトをクロールしていた人が逮捕、勾留、実名報道されるという事件がありました。
関連URL: http://librahack.jp/
電話してみた的な話
- http://www.nantoka.com/~kei/diary/?20100622S1
- http://blog.rocaz.net/2010/06/945.html
- http://blog.rocaz.net/2010/07/951.html
この件につきまして法的なことはともかくとして技術者視点での私見を書きたいと思います。法的なことは差し置いて書きますが、それは法的なことを軽んじているわけではなく、法律の制定やら運用やらは、その法律によって影響が出る全ての人々の常識やら慣例やらも含めた実態に即していなければ意味が無いばかりか害悪になると考えるからです。また技術的に解決できる問題については、先ずは技術的な解決を試みるべきであって、特にインターネットの世界では、人間や機械がアクセス先のサービスの利用規約や、アクセス先のサーバーが置いてある国の法律を解釈することが必ずしも期待できないため、性善説もクソもない、機械が読めない法律や利用規約など、そもそも全く配慮されることを期待すべきではない!と考えるべきであり、また人間や機械がそのサービスに固有の利用規約やその国に固有の法律などを理解していたとしても、必ずしもそのルールが尊守されるとは限らないし、ルールが守られることを前提としたシステムの設計は技術的な欠陥が放置されることにつながり、結果として人々の安全やプライバシーを脅かす危険な存在であると言える。つまり、技術者の世界においては、地域や民族に固有のローカルルールや常識や慣例や風習に従わずに、技術的に解決すべきことは技術的に解決すべきであるというのが常識や慣例であり、そういったポリシーを法律家も含めて理解していただく必要があると考えています。
話を戻して、もし意見を聞かせてくれと言われたならば
- クローラには問題ない(刑事責任も民事責任もない)
- サービスの運用に支障をきたしているのであればアクセス拒否して終わり
- 処理能力の向上やバグの修正などの改善を求めるのは図書館と開発ベンダーで相談して勝手にやればいい
- 警察の対応が特別におかしい
と答えるでしょう。
もし自分が同様のクローラを書いたらどうなるか
個人的な感覚では、librahackさんが書いたクローラは当然悪意があるものだとは思わないし「特別に行儀が悪い」とも思わない。自分が同じ目的のプログラムを書いたならば、おそらく大差ない内容になるでしょう。
具体的には
- robots.txtを無視します
- metaタグを無視します
- ウェイトを入れません(入れるとしてもごく短い)
- 一部500エラーが出てもクロールの中止やプログラムの見直し等は行わない
- むしろ適切なウェイトと最大試行回数を設定した上でリトライすることを検討する
- 一度取得したページについてはキャッシュしてしばらくアクセスしないような制限を加えるが、開発中ならその限りではない
- 開発中、あるいは自分専用サービスとして作っている限りは、UserAgentを変えない(使用しているライブラリのデフォルト)
もちろん事前にアクセス先のサービスに対して何らかの知識があるなら、多少加味するだろうが、同様の事例であれば逮捕される可能性が高い。俺じゃなくてよかった。
なぜrobots.txtやmetaタグを無視しても良いと考えるのか
robots.txtやmetaタグによるbotの拒否は、ロボット型の検索エンジンのクローラが際限なく動的に生成されるリンクを辿っていって双方のサーバーリソースに過大な負荷をかけたり、公開されるべきでないコンテンツが検索エンジン経由で公開されたりといった事故を防ぐのが目的(という認識)なので、特定サービス向けに特定パターン以外のリンク先を探索しない個人的な使用目的の巡回ツールに対してまで、robots.txtやmetaタグの規定するルールを適用するのは適切ではないと考えているからです。
なぜウェイトを入れる必要がないと考えるのか
リクエストを並列して投げない(前回のリクエストの完了を待ってから次のリクエストを発行するようになっている)ならば、相手先のサーバーに対して与える負荷は限定的であり、一般ユーザーが通常の利用目的でブラウザを使ってかける負荷の上限と大差がないと考えるからです。更新チェックなどの目的で同一の(更新されている確率が低い)URLに対してウェイトを入れずに数秒、数分の間隔で自動アクセスするのは、非常識であると考えます。しかし、同じURLに対する重複したアクセスがなく、同一ドメインのリンク先をn段階辿ってまとめて保存するような機能は、本来ブラウザに備わっていてもおかしくないようなもので、自前で書いたツールを使っているだけで通常のブラウジング行為の延長線上であると捉えるべきです。古いIEには実際そういう機能がありました(ウェイト入れてたかどうかとかは調べてない)。
なぜ500エラーが出てもクロールを中止する必要がないと考えるのか
自分のリクエストが原因でエラーが出ているのか区別がつかないので、単に時間をおいて再試行すれば良いと考えるからです。全てのレスポンスがエラーを返すようになったならば、その段階で目的が達成できないのでプログラムの見直しを行うことになるでしょう。500レスポンスは単にそのリクエストに対してエラーが出ているというだけなので、自分のリクエストに原因があるとは考えません。なのでこの場合の適切なエラーハンドリングはクロールの停止やプログラム開発の停止ではありません(適切なウェイトを入れた上で再試行します)。もし403エラーが返ってきているのであれば、自分のリクエストが何らかの理由で拒否されているだろうから、処理内容を見直す必要があると考えます。403レスポンスが返ってきたら、別のUAや別の回線からのアクセスを試して、何らかの自動的な制限に引っかかったのか、あるいは自分の書いたプログラムが決め打ちでアクセス拒否されているかどうかを判断したうえで、サービス運営者に問い合わせるなどするでしょう(アクセス拒否されないためにはどうすればいいか聞く)。気軽に問い合わせできる感じでなかったら開発を中止する。
botがサービス運営に支障を来す場合にサービス運営者の取るべき行動について
- 使用しているhttpdのマニュアルとにらめっこして該当のbotに対して403を返すようにしましょう
- もし過剰なアクセスにより金銭的な負担が発生しているのであれば402 payment requiredを返すのも良いでしょう。youtubeが使っています。
- 手動でルールを追加するのが面倒であればIPアドレス毎の帯域制限やアクセス回数の制限を行ないましょう。大抵のhttpdで適切なモジュールがあるはずです。
- 403を返すだけの処理だけでもサーバーのリソースを大量に消費してサービス運営に支障が出るレベルのアクセス回数であるのなら、iptablesで拒否するなどしましょう。
- アクセス拒否されていることを検知して自動的に複数のIPアドレスからのアクセスを行って来たり、UserAgentを偽装してアクセス拒否することを困難にしていたり、帯域の消費だけでサービス運営に支障をきたすようなレベルであれば攻撃とみなしましょう。警察の出番だ。
行儀の良いbotの話
- ウェイトを入れるのは良い慣習だ。
- エラーが返ってきたらクロール頻度を調整するのは良い慣習だ。
- botの目的や連絡先が分かるようにするのは良い慣習だ。
botの世界には実効性があるのかどうか不明な慣習があります。これらを守ってなくても大した問題ではないと考えています。
- Fromヘッダにメールアドレスを入れる → アクセスログに残らない、自称しているだけで確実にそのメールアドレスの持ち主とは限らない
- 過負荷時のRetry-Afterヘッダ → 守ってくれなければ意味が無い、行儀の悪いbotはそもそも守らない、処理能力改善することを考えたほうがマシ
これらはあくまで良い慣習であって、守っていないからと言って悪意があるものだとは言えない。ライブラリの機能を叩いて3分で作れるような書き捨てのスクリプトでいちいちそのようなことが配慮されることを期待すべきではない。攻撃目的で作られたツールというものは、もっと行儀が悪いものであることを知るべきだ。
攻撃目的で作られたツールではなくても問題になることはある。困ったことになる代表例は
- ab(Apache Bench)を管理外のサーバーに対して行う → 普通に落ちたり帯域使い尽くしたりする
- 脆弱性スキャンツールの類 → 脆弱性ある無しに関係なく大量のリクエストを投げるし場合によっては何かデータ書き込んだりする
これでサービスを落とした人の実例を何件か知っている。
まとめ
403返して終わりって事例でポリス沙汰にするな。