mod_throttleによる転送量制限
以前から巨大MP3ファイルに対するしつこいリロードで帯域を占領されちゃう状況が結構あったんですが、さすがに複数IPから8時間以上連続で食らい続けるとなると(例え悪意が無いにしても)ちょっと迷惑なんで、とうとう重い腰を上げて
「サーバ側の仕掛けで自動的に対処出来る」
設定にしちゃう事にしました。
現状は転送量で課金される訳じゃない→どうしても帯域を絞らなきゃいけない訳でもないんすが、apacheが帯域をフルに使って転送してると、コレに帯域を食われて露骨に回線が「重く」なる→QoSの維持が難しくなるし。
apache1.3系で帯域制限となるとmod_bandwidthかmod_throttleなんですが、今回は
・httpリクエストは基本的に「可及的速やかに処理」したい
(apacheが帯域を100%占有しちゃう状態も基本的に許可)
・ただし、「量的に限度を越えてるヒト」のリクエストは弾きたい
という内容→「apacheが全ての帯域を食い潰さないように制限する」mod_bandwidthはちょっと違うようですので、mod_throttleを使ってみる事にします。
ココのサーバはaptを使えるようにしてますんで、早速aptで調べてみます。
$ apt-cache search mod_throttle
mod_throttle - A module which implements the bandwidth and request throttling for Apache.
$ apt-cache search mod_bandwidth
mod_bandwidth - A bandwidth-limiting module for use with Apache.
素晴しい。どちらもあるようです。aptばんざい!(笑)
aptにあるなら何も手間要りません。
# apt-get install mod_throttle
と、まさに一撃でインストール完了。
rpmでインストールしたんで、
<IfDefine HAVE_THROTTLE>
LoadModule throttle_module modules/mod_throttle.so
</IfDefine>
<IfDefine HAVE_THROTTLE>
AddModule mod_throttle.c
</IfDefine>
↑この辺の設定は、予め/etc/httpd.confに為されてました。
続いて、制限状況を把握出来るように
<Location /throttle-status>
SetHandler throttle-status
AuthType Basic
AuthUserFile /var/www/.htpasswd
AuthName "throttle-status"
</Location>
として/trottle-status(←mod_throttleの動作状況を表示するアドレス)を有効とし、BASIC認証で保護します。
肝心の転送量制限は、現在も様子見中なんですが
<IfModule mod_throttle.c>
ThrottleClientIP 100 volume 20M 1200
</IfModule>
いまはとりあえず↑こんな感じ。
「最近アクセスして来た100アドレスが監視対象。20分(=1200秒)を1区間とし、区間内に20MB以上の転送を行ったIPに対して503を返す」
という内容です。
最初「10MB/5分以上の転送を行ったIPからの接続を拒否。アドレスリストサイズ15」という制限としてみたんですが、
ってな感じで、1時間の間に4回の「赤信号点灯寸前」が→ちょっと制限される頻度が高すぎるし、監視リストサイズが15ではアクセス頻度の高い時間帯にすぐ対象が監視範囲外に溢れてしまったので、現在は上記のような条件で様子をみてます。
「とりあえずメガバイト級までは我慢しますけど、ちょっと10メガバイト超級の転送は勘弁してください(^^;)」
ってな感じですか(^_^;)
「制限を行なう期間」は、デフォルトで60秒となってます。制限時間を指定したい場合はThrottleMaxDelayで明示的にDelay秒数を指定するか、0にして「ポリシーで定めた期間に揃える」とかしとく必要があるみたい。
実際に転送量が規制されるか確認するため、サーバ上に10MBの巨大BMPファイルを置いてF5キーを連打して見たんですが、普通にF5を連打しても304(Not Modified)が返ってきて、実データは転送されないのにビックリ。
実験では「予めファイルを『名前を変えてコピー』し複数用意しておく」か、「ブラウザ側のキャッシュをそのたびに削除する」等の手順を踏まないとだめでした。
制限に引っかかると503エラーが出るんですが、標準の503エラーは
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
と「なぜ弾かれたのか解らない」内容だったので、httpd.confに
ErrorDocument 503 /503.phtml
を追記し、503.phtmlに
Probably, the amount of transmission exceeded the setting value.
たぶん、単位時間転送量が設定上限を越えました。
当サーバには転送量上限が設定されています。
とか書いとくことにしました。たぶん、コレなら弾かれた理由が解るんじゃないかと。
読まねぇ奴は何を書いても読まないみたいです。503エラーを返しても、そのまま300回以上クリックし続けた馬鹿がいました(^_^;)
UAを見るにダウンローダの類じゃなくてブラウザ→その度に(日本語/英語の両方で)エラーメッセージが返されてるハズなんですが、そんなものは読まない&気にしないんでしょうね、全然(^_^;)
まぁ、わざわざ手間ひまをかけて「こーゆーヒトを弾くため」に作った仕掛け&ルールなんで、別に何百回クリックしてもらっても、こっちは全然構いませんけど。