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

投稿者: | 2020年1月31日

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


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