(78) BOTのアクセスを拒否する。

投稿者: | 2020年1月31日

2,187 views

1. やりたいこと

レンタルサーバーにWEBサイトを設置している。

たまたま アクセス統計画面 を見てみたら、結構なアクセス数がある。

1日に 17万回もリクエスト?!

そんなはずがない。
何かがおかしい…

と思い…
アクセス解析ログを参照してみた。

すると…

ログから確認できただけで BOTからのリクエストが 1日に 1万回以上 もある。
おそらくこのログで漏れている BOTが他にもたくさんあるはず。

で、今回は…
WEBサイトの負荷を軽減するため
Google以外の BOTによる WEBサイトへのアクセスを拒否(除外、遮断)したい。

これを実現する手段をツラツラと記録しておく。

2. やってみる

対策1:Apacheの .htaccessでBOTを除外する。

以下の .htaccess ファイルを作成し WEBサイトのルートディレクトリに置いておく。
HTTPプロトコルのデータに含まれるブラウザ情報 User-Agent に特定の BOT名が含まれていればアクセス拒否できる。

BrowserMatchNoCase : HTTP User-Agent に基づいて大文字小文字を区別せずに 環境変数を設定する。

大文字小文字を区別したい場合は、BrowserMatchを使用する。
BrowserMatch : HTTP User-Agent に基づいて環境変数を設定する。

BrowserMatchNoCase bingbot IsBOT    # ブラウザ情報に bingbot が含まれているならば、環境変数 IsBOT をセット
BrowserMatchNoCase SemrushBot IsBOT # ブラウザ情報に SemrushBot が含まれているならば、環境変数 IsBOT をセット
BrowserMatchNoCase ccbot IsBOT      # ブラウザ情報に ccbot が含まれているならば、環境変数 IsBOT をセット
BrowserMatchNoCase Twitterbot IsBOT # ブラウザ情報に Twitterbot が含まれているならば、環境変数 IsBOT をセット
BrowserMatchNoCase Applebot IsBOT   # ブラウザ情報に Applebot が含まれているならば、環境変数 IsBOT をセット

order Allow,Deny      # 許可、禁止の順に記述する。
Allow from all        # すべて許可する。
Deny from env=IsBOT   # でも、環境変数 IsBOTが定義されているならば拒否する。

BrowserMatchNoCase の代わりに SetEnvIf User-Agent と書いてもよい。

SetEnvIf : リクエストの属性に基づいて環境変数を設定する。

SetEnvIf User-Agent bingbot IsBOT # ブラウザ情報に bingbot が含まれているならば、環境変数 IsBOT をセット
 :

※自分で正直に名前を名乗ってくれる正統派BOTにしか効かない対策ではある…

対策2:PHPプログラムで BOTを除外する。

以下のような BOT判定関数を作成する。

function is_BOT(){
  $isBot = TRUE;
  $agent = $_SERVER['HTTP_USER_AGENT'];
  $ary_bot = array('bingbot','ccbot','SemrushBot','Twitterbot','Applebot');
  foreach($ary_bot as $bot){
    if(preg_match("/{$bot}/i",$agent) === 1){   // マッチしたならば 1を返す
      goto tagEND;     // BOTであると判断
    }
  }
  $isBot = FALSE;
tagEND:
  return $isBot;
}

呼び出し側では TRUE判定が返されたら exit()して HTMLコードを出力しなければよい。

if(TRUE === IsBOT()){
  exit();
}

3. どの対策がよいのか?

まず、PHPで出力される WEBページを開く場合の流れを簡単に書くと、以下の通り。
1) WEBブラウザ : URLを指定して HTTPリクエストを WEBサーバーへ送る。
2) WEBサーバー : PHPプログラムを実行して HTMLを生成し、WEBブラウザへ返却する。
3) WEBブラウザ : HTML文に書かれた画像や CSS, JavaScriptなどのファイル取得のために HTTPリクエストを繰り返し発行する。

対策1を採用すると?

〇 メリット
・何よりも実装が楽だ。
・上記2)の PHP実行前の早い段階でアクセスを拒否できる。(PHPを実行させない。)

× デメリット
・アクセスを拒否しない正常系処理でパフォーマンス低下の懸念あり。
 PHPプログラムが出力する HTML文に画像が数百枚あるなど、HTTPリクエストを多数発行するHTMLコードの場合、.htaccess上の照合処理がHTTPリクエストの数だけ発生するため、WEBサーバー側の処理負荷が上がる。「塵も積もれば…」でアクセス数の多いサイトほど影響が大きい。

対策2を採用すると?

上述の対策1の裏返しになる。

どうするか?

よって…
基本的には、対策1を採用する。
画像多数など、通常の閲覧で HTTPリクエストを多発するような WEBサイトの場合、対策2を採用する。

にしようと思う。

4. 参考情報

Apache モジュール mod_setenvif


カテゴリー: BOT

コメントを残す

メールアドレスが公開されることはありません。


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)