ボット、クローラのアクセスを除外する方法を調べてみた | Monotalk で、mitchellkrogza/apache-ultimate-bad-bot-blocker の存在を知りました。
実際に設定を施して、ボット、クローラのアクセスをブロックしてみました。
結果を以下に記載します。
apache-ultimate-bad-bot-blocker について
Apache でボット、クローラのアクセスをブブロックするための 設定ファイルを提供する github リポジトリです。
Apache 本体の設定ファイル以外にも以下が含まれます。
fail2ban
の Addon- Google Analytics のフィルタ定義
- Google Search Console の リンク否認用のアップロードファイル
- robots.txt
前提
以下の環境で実施しています。
-
OS
cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core)
-
Apache の Version
httpd -V Server version: Apache/2.4.29 (CentOS)
インストール、設定、定期的な更新
インストール
以下、Apache2.4 向けにインストールスクリプトが用意されています。
apache-ultimate-bad-bot-blocker/install-apacheblocker.sh at master · mitchellkrogza/apache-ultimate-bad-bot-blocker
このスクリプトを使用してインストールを実施していきます。
-
スクリプトの取得
cd ~ sudo wget https://raw.githubusercontent.com/mitchellkrogza/apache-ultimate-bad-bot-blocker/master/install-apacheblocker.sh chmod +x ~/install-apacheblocker.sh
-
設定値の変更
スクリプト内のApacheのディレクトリ、設定ファイルの格納ディレクトリを必要があれば書き換えます。
#Generally /etc/apache2 or /etc/httpd depending on OS # Apacheのディレクトリは /etc/httpd APACHE_CONF='/etc/httpd' #location of Apache blocker files BLOCKER_URL="https://raw.githubusercontent.com/mitchellkrogza/apache-ultimate-bad-bot-blocker/master/Apache_${APACHE_VERSION}/custom.d" # ディレクトリの指定は custom.d sudo mkdir -p "${APACHE_CONF}/custom.d"
-
スクリプト実行
幾つかファイルがダウンロードされ、最後に、sudo ~/install-apacheblocker.sh
Manually edit vhost to include globalblacklist.conf
とメッセージが出力されます。
メッセージの通り、VirtualHost の設定を変更する必要があります。 -
設定ファイルの説明
以下の、設定ファイルがダウンロードされました。
それぞれ内容を説明します。ls -1 /etc/httpd/custom.d/ ---------------------------------- bad-referrer-words.conf blacklist-ips.conf blacklist-user-agents.conf globalblacklist.conf whitelist-domains.conf whitelist-ips.conf ----------------------------------
-
bad-referrer-words.conf
リファラーspam に設定されているリファラーの文字列を定義するファイルです。
デフォルトは、コメントのみで末定義で、使用者側で必要があれば追記します。 -
blacklist-ips.conf
アクセスをブロックする ip が定義されています。
デフォルトで、幾つかip が定義されています。 -
blacklist-user-agents.conf
アクセスをブロックする ユーザーエージェントを定義するファイルです。
デフォルトは、コメントのみで末定義で、使用者側で必要があれば追記します。 -
globalblacklist.conf
メインの設定ファイルになります。各confファイルはこのファイルから読み込まれています。
ブラックリストのユーザーエージェント、リファラー文字列が大量に記載されています。 -
whitelist-domains.conf
アクセスを許可する、domain 文字列を定義します。
デフォルトはコメントのみです。 -
whitelist-ips.conf
アクセスを許可する、ip を定義します。
デフォルトはコメントのみです。
設定
-
VirtualHost定義の編集
VirtualHost の定義箇所に、globalblacklist.conf
の Include 記述を追加します。
複数 VirtualHost があれば複数記述する必要があります。<Directory /var/www/site> Include custom.d/globalblacklist.conf Order Deny,Allow Deny from env=ng_host Deny from env=ng_referer Deny from env=ng_lang <IfModule mod_rewrite.c> # domain rewrite rules RewriteEngine On
-
設定ファイルの読み込み、とテスト
設定ファイルを読み込み、curl でテストを実施します。-
ファイル読み込み
sudo apachectl configtest sudo apachectl graceful
-
curl でテスト
ユーザーエージェントを指定して、curl を実行レスポンスコードを確認します。
curl -A "googlebot" https://www.monotalk.xyz -o /dev/null -w '%{http_code}\n' -s 200
curl -A "masscan" https://www.monotalk.xyz -o /dev/null -w '%{http_code}\n' -s 403
レスポンスコード から 適用できていることが確認できました。curl -I https://www.monotalk.xyz -e http://zx6.ru -o /dev/null -w '%{http_code}\n' -s 403
-
定期的な更新
適用はできましたので、globalblacklist.conf
の更新を定期的に取り込むようにします。
mitchellkrogza/apache-ultimate-bad-bot-blocker に更新用のスクリプトが用意されていますので、それを使用します。
-
更新スクリプトの取得
sudo wget https://raw.githubusercontent.com/mitchellkrogza/apache-ultimate-bad-bot-blocker/master/update-apacheblocker.sh chmod +x update-apacheblocker.sh
-
更新スクリプトを編集
スクリプト内の、筐体依存、環境依存の箇所を変更します。
当ブログだと、APACHE_CONF
、EMAIL
、CURL_TEST_PROTOCOL
、CURL_TEST_URL_NAME
を変更しました。
#Major Apache version e.g. 2.2, 2.4 APACHE_VERSION='2.4' #Directory where bad bot configs are located. APACHE_CONF='/etc/apache2/custom.d' #location of globalblacklist BLACKLIST_URL="https://raw.githubusercontent.com/mitchellkrogza/apache-ultimate-bad-bot-blocker/master/Apache_${APACHE_VERSION}/custom.d/globalblacklist.conf" #Address to send update notifications EMAIL='email@example.com' #Make backup of globalblacklist.conf when updating true or false. MAKE_BACKUP=false #Run apachectl test before reload true/false TEST_BEFORE_RELOAD=true #Curl test to ensure blocking still working after reload true/false. CURL_TEST_AFTER_RELOAD=true #Specify if your site uses http or https CURL_TEST_PROTOCOL=http #domain name to test against. CURL_TEST_URL_NAME=localhost
-
crontab でスケジュール設定
crontab で定期実行の設定をします。
私は以下のように設定しました。
SCRIPT_HOME="/root/script" LOG_DIR="/var/log/blog_jobs" 00 02 * * * /bin/sh $SCRIPT_HOME/update-apacheblocker.sh $>> $LOG_DIR/update-apacheblocker.log # update-apacheblocker
-
スクリプトの動作について
スクリプトの動作は以下のような動きになっています。-
globalblacklist.conf が スクリプトの実行環境に存在するか確認し、なければ処理中断。
-
github リポジトリから globalblacklist.conf を取得、スクリプトの実行環境の globalblacklist.conf と差分をとり、差分がなければ処理中断。
-
差分がある場合は、バックアップを取得し globalblacklist.conf を更新。
-
更新後に、テストを実施、テストが失敗した場合はメール送付。
-
ブロック状況をレポートする
悪質なbotのアクセスをNginxでバッサリ切り捨てる に記載がありますが、良いボットがブロックされてしまう場合もあります。mitchellkrogza/nginx-ultimate-bad-bot-blockeに、日次でアクセスログを結果をメールで送付するワンライナーのスクリプトが記載されています。
このスクリプトを参考に以下のような、スクリプトを作成しました。
- monitor_access_log.sh
上記を cron から 定期実行するようにしました。#!/bin/sh MAIL=your@gmail.com LOG_DIR=/var/log/httpd # Monitoring Daily Referers tail -10000 $LOG_DIR/ssl_access_log | awk '$11 !~ /google|bing|yahoo|yandex|www.monotalk.xyz|mutter.monotalk.xyz|monotalk.xyz/' | awk '{print $11}' | tr -d '"' | sort | uniq -c | sort -rn | head -1000 | mail -s "Top 1000 Referers on ssl_access_log for montalk.xyz" $MAIL # Monitoring Daily User Agents tail -50000 $LOG_DIR/ssl_access_log | awk '{print $12}' | tr -d '"' | sort | uniq -c | sort -rn | head -1000 | mail -s "Top 1000 Agents on ssl_access_log for monotalk.xyz" $MAIL # Monitoring Daily Referers tail -10000 $LOG_DIR/access_log | awk '$11 !~ /google|bing|yahoo|yandex|www.monotalk.xyz|mutter.monotalk.xyz|monotalk.xyz/' | awk '{print $11}' | tr -d '"' | sort | uniq -c | sort -rn | head -1000 | mail -s "Top 1000 Referers on access_log for montalk.xyz" $MAIL # Monitoring Daily User Agents tail -50000 $LOG_DIR/access_log | awk '{print $12}' | tr -d '"' | sort | uniq -c | sort -rn | head -1000 | mail -s "Top 1000 Agents on access_log for monotalk.xyz" $MAIL
レポートの集計
Gmail に送信したレポートのデータ集計のため、Google スプレッドシート で 以下のような、Container Bound Script を作成し、ブロック状況のレポートを集計するようにしました。
function pollMail() {
var strTerms = "xxxxx@gmail.com AND Top 1000 AND is:unread";
var numMailMax = 20000; //取得するメール総数
var numMail = 500; //1度に取得するメール数
var myThreads; //条件にマッチしたスレッドを取得、最大500通と決まっている
var myMsgs; //スレッドからメールを取得する →二次元配列で格納
var valMsgs;
var flattenMsgs;
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("report")
var i = sheet.getLastRow();
if(i < numMailMax) {
valMsgs = [];
myThreads = GmailApp.search(strTerms, i, numMail); //条件にマッチしたスレッドを取得、最大500通と決まっている
myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納
/* 各メールから日時、送信元、件名、内容を取り出す*/
for(var j = 0; j < myMsgs.length; j++){
rows = convertBody2Array(myMsgs[j][0].getBody());
for (var k = 0; k < rows.length; k++) {
elem = [];
elem.push(myMsgs[j][0].getFrom());
elem.push(myMsgs[j][0].getReplyTo());
elem.push(myMsgs[j][0].getTo());
elem.push(myMsgs[j][0].getDate());
elem.push(myMsgs[j][0].getSubject());
elem.push(rows[k][0]);
elem.push(rows[k][1]);
valMsgs.push(elem);
}
}
/* スプレッドシートに出力 */
if(valMsgs.length > 0){
sheet.getRange(i + 1, 1, valMsgs.length, 7).setValues(valMsgs); //シートに貼り付け
}
for(var i = 0; i < myThreads.length; i++){
// 既読にする
myThreads[i].markRead();
// ゴミ箱に移動する
myThreads[i].moveToTrash();
}
}
}
function convertBody2Array(body) {
var lines = body.split("\r\n");
var results = [];
for (var i = 0; i < lines.length; i++) {
if (lines[i] == "") {
continue;
}
tempLine = lines[i].replace(/\s\s+/g, "");
results.push(tempLine.split(" "));
}
return results;
}
参考
以下、参考になりました。
-
よく見かけるクローラの説明。当サイトによく巡回にくるクローラ Top 11 より。 | かきしちカンパニー Web Magazine
-
私がメインサイトでアクセス拒否しているBOT一覧を紹介!(.htaccess用の拒否サンプル付き!) | Wordpress初心者な技術屋の忘備録
設定、定期更新、モニタリングまでの設定を行いました。
実運用で使用する場合、変更があったからいきなり更新ではなく、開発環境は自動更新しばらく様子見、本番環境は手動での更新をする等、影響を考えながらの適用になるかと思われました。
以上です。
コメント