偽の gogglebot や bingbot に対処する

 googlebot や binbot を詐称してアクセスするものがあります。今まで放置していましたが、Internal Server Error を出してきたので対処していこうと思います。

データの収集

 googlebot や bingbot を UA(ユーザエージェント)から拾います。UA に Googlebot があるホストを調べることになります。

$ grep " Googlebot" ログファイル | sed -e 's/\(^.*\) - - \[.*/\1/'
66.249.68.30
crawl-66-249-68-1.googlebot.com
66.249.68.28
66.249.68.1
crawl-66-249-68-1.googlebot.com
94.177.118.93
94.177.118.93
・
・

 この中で、googlebot.com ドメインを取り除きます。

$ grep " Googlebot" ログファイル | sed -e 's/\(^.*\) - - \[.*/\1/' | grep -v "googlebot.com$"
66.249.68.30
66.249.68.28
66.249.68.1
94.177.118.93
94.177.118.93
・
・

 重複行をまとめ、整列させます。

$ grep " Googlebot" ログファイル | sed -e 's/\(^.*\) - - \[.*/\1/' | grep -v "googlebot.com$" | sort -u
66.249.68.1
66.249.68.10
66.249.68.28
66.249.68.30
66.249.68.7
94.177.118.93

 ずいぶん減りました。

IP アドレスを検証する

 IP アドレスをそれぞれ逆引きします。

$ dig -x 66.249.68.1

; <<>> DiG 9.11.5-P4-5.1+deb10u5-Raspbian <<>> -x 66.249.68.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21293
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 9

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 0d3bc36061f4af79a2f1a7186136a52dcc8e3a83de04036f (good)
;; QUESTION SECTION:
;1.68.249.66.in-addr.arpa.      IN      PTR

;; ANSWER SECTION:
1.68.249.66.in-addr.arpa. 59110 IN      PTR     crawl-66-249-68-1.googlebot.com.

;; AUTHORITY SECTION:
68.249.66.in-addr.arpa. 57159   IN      NS      ns1.google.com.
68.249.66.in-addr.arpa. 57159   IN      NS      ns3.google.com.
68.249.66.in-addr.arpa. 57159   IN      NS      ns2.google.com.
68.249.66.in-addr.arpa. 57159   IN      NS      ns4.google.com.

;; ADDITIONAL SECTION:
ns1.google.com.         35465   IN      A       216.239.32.10
ns2.google.com.         35465   IN      A       216.239.34.10
ns3.google.com.         35465   IN      A       216.239.36.10
ns4.google.com.         35465   IN      A       216.239.38.10
ns1.google.com.         35465   IN      AAAA    2001:4860:4802:32::a
ns2.google.com.         35465   IN      AAAA    2001:4860:4802:34::a
ns3.google.com.         35465   IN      AAAA    2001:4860:4802:36::a
ns4.google.com.         35465   IN      AAAA    2001:4860:4802:38::a

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 火  9月 07 08:33:01 JST 2021
;; MSG SIZE  rcvd: 381

 ネームサーバによって内容は違うと思いますが、ANSWER SECTION を見ると、このホストも googlebot.com のホストなので問題ないホストです。66.249.68.10 と 66.249.68.28、66.249.68.30、66.249.68.7 も googlebot.com のホストでした。

$ dig -x 94.177.118.93

; <<>> DiG 9.11.5-P4-5.1+deb10u5-Raspbian <<>> -x 94.177.118.93
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 43424
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: fe4f617275470e737a2007836136a728bb25ea085c403651 (good)
;; QUESTION SECTION:
;93.118.177.94.in-addr.arpa.    IN      PTR

;; AUTHORITY SECTION:
118.177.94.in-addr.arpa. 2618   IN      SOA     ns8.heficed.com. postmaster.ns8.host1plus.com. 2021072000 28800 7200 2419200 86400

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 火  9月 07 08:41:28 JST 2021
;; MSG SIZE  rcvd: 159

 このホストは逆引きできないので Google の bot ではありません。host1plus.com はクラウド事業をやっているようです。その中のホストが悪さをしているのでしょう。UA を偽装するのは悪質だと思います。

 偽装する IP を抽出する SHELL スクリプトを作りました。

fake-bot

#!/bin/bash

trap 'rm -f ${tmpfile}; exit 1' 1 2 3 15

tmpfile=/tmp/fake_bot$$
if [ -f "${tmpfile}" ]; then
    rm -f "${tmpfile}"
fi

apache_log="ログファイル名"
safe_domain="googlebot.com"
ua="Googlebot"

if [ $# -eq 2 ]; then
    ua=$1
    safe_domain=$2
elif [ $# -ne 0 ]; then
    echo "Usage: $0 [<ua> <safe domain>]"
    exit
fi

for log in ${apache_log}
do
    grep "${ua}" /var/log/apache2/${log} | sed -e 's/\(^.*\) - - \[.*/\1/' | gre
p -v "${safe_domain}$" >> ${tmpfile}
done

for ip in $(sort -u ${tmpfile})
do
    ptr=$(dig -x ${ip} | grep "^[^;].*PTR")
    domain=${ptr##*PTR  }
    if [ "${domain}" != "" ]; then
        if
            ! echo ${domain} | grep "${safe_domain}.$" >/dev/null
        then
            echo "Fake $ua ${ip} ${domain}"
        fi
    else
        echo "Fake $ua ${ip}"
    fi
done

if [ -f "${tmpfile}" ]; then
    rm -f "${tmpfile}"
fi

 apache_log は抽出したいファイル名を書きます、複数あれば、空白で区切って指定します。

 抽出した IP を弾くには、ファイヤーウォールで弾くか、Apache の .htaccess で弾くかのどちらかになります。

 今回は、.htaccess で弾くことにしました。.htsccess で弾くと、403 が返るので、何度もアクセスがあるようなら、fail2ban で拒否できます。

.htsccess で対処する

 .htsccess に次を追加します。

<RequireAll>
  Require all granted
  Require not ip 94.177.118.93
</RequireAll>

自動化する

 自動で行うには、.htaccess を編集しなければなりません。 SHELL スクリプトを作成しますが、自分の環境でしか動くことを確認していないので、そのまま使うことは避けたほうがいいと思います。

 前提として、.htaccess に RequireAll があるものとしています。fake_bot に追加します。

(2021.10.03 追記)
 スクリプトの内容に不具合があり修正しました。スクリプトは以下の記事を参照してください。

fake-bot

(追記ここまで)

!/bin/bash

trap 'rm -f ${tmpfile}; exit 1' 1 2 3 15

tmpfile=/tmp/fake_bot$$
if [ -f "${tmpfile}" ]; then
    rm -f "${tmpfile}"
fi

edit_htaccess () {
    newip=$1
    htaccess_list="フルパス/.htaccess"

    for htaccess in ${htaccess_list}
    do
        target="${htaccess}"
        if
            ! grep "${newip}" "${target}" > /dev/null
        then
            echo "Add new deny ${newip} to ${htaccess}."
            sed -e "s/^\(<\/RequireAll>\)$/  Require not ip ${newip}\n\1/" -i "${target}"
        fi
    done
}

apache_log="ログファイル名"
safe_domain="googlebot.com"
ua="Googlebot"

if [ $# -eq 2 ]; then
    ua=$1
    safe_domain=$2
elif [ $# -ne 0 ]; then
    echo "Usage: $0 [<ua> <safe domain>]"
    exit
fi

for log in ${apache_log}
do
    grep "${ua}" /var/log/apache2/${log} | sed -e 's/\(^.*\) - - \[.*/\1/' | grep -v "${safe_domain}$" >> ${tmpfile}
done

for ip in $(sort -u ${tmpfile})
do
    ptr=$(dig -x ${ip} | grep "^[^;].*PTR")
    domain=${ptr##*PTR  }
    if [ "${domain}" != "" ]; then
        if
            ! echo ${domain} | grep "${safe_domain}.$" >/dev/null
        then
            echo "Fake ${ua} ${ip} ${domain}"
            edit_htaccess ${ip}
        fi
    else
        echo "Fake $ua ${ip}"
        edit_htaccess ${ip}
    fi
done

if [ -f "${tmpfile}" ]; then
    rm -f "${tmpfile}"
fi

 htaccess_list には、フルパスで .htaccess を書いてください。複数あれば空白で区切って書きます。

 これを cron に登録すれば自動で追加してくれます。

サーバ設定

Posted by sirius