構成するファイル群
Apacheバーチャルサイト
<VirtualHost *:80>
ServerName your-domain.com
# HTTPでアクセスが来たらHTTPSにリダイレクト
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.com
DocumentRoot /var/www/your-domain/public
# --- ログ設定 ---
# 特定のIPからのアクセスをログに記録しない例
SetEnvIf Remote_Addr "192.168.0.100" dontlog
SetEnvIf Remote_Addr "192.168.0.101" dontlog
# 特定のUser-Agent(Googlebotなど)をログに記録しない例
SetEnvIfNoCase User-Agent "Googlebot" dontlog
# botのアクセスリストを外部ファイルから読み込む
Include /etc/apache2/conf-enabled/bad-bot-list.conf
# dontlogが設定されていないアクセスのみログに記録
CustomLog /var/log/apache2/your-domain.access.log combined env=!dontlog
ErrorLog /var/log/apache2/your-domain.error.log
<Directory /var/www/your-domain/public>
Options -MultiViews
AllowOverride All
# アクセス拒否時に記録されるAH01630エラーを抑制
LogLevel authz_core:crit
<IfModule mod_rewrite.c>
RewriteEngine On
# IPベースのブロックリストを読み込む
Include /etc/apache2/conf-enabled/ip-blacklist.conf
</IfModule>
<RequireAll>
# bad_bot変数がセットされていたらアクセスを拒否
Require not env bad_bot
# それ以外は許可
Require all granted
</RequireAll>
</Directory>
# アクセス拒否時(403)に404ページを表示する
ErrorDocument 403 /404.html
# --- セキュリティヘッダー ---
Header always set Strict-Transport-Security "max-age=63072000"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
# --- SSL/TLS設定 ---
SSLEngine on
Protocols h2 http/1.1
# 推奨プロトコル設定 (TLS 1.3を優先)
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
SSLSessionTickets off
SSLCertificateFile /etc/ssl/certs/your-domain.com.pem
SSLCertificateKeyFile /etc/ssl/private/your-domain.com.key
# --- ModSecurity設定 ---
<IfModule security2_module>
SecRuleEngine On
# ファイルアップロードの上限設定
SecRequestBodyLimit 524288000
SecRequestBodyNoFilesLimit 524288000
# CRS(Core Rule Set)の例外ルール
# 特定のルールIDを無効化する例
SecRuleRemoveById 920420
SecRuleRemoveById 200004
# IPアドレスのブラックリスト(テキストファイル)を読み込み、
# 一致した場合はログも残さず接続を拒否する
SecRule REMOTE_ADDR "@pmFromFile /etc/modsecurity/ip-blacklist.txt" \
"phase:1,id:1001,status:404,msg:'IP Blacklisted',nolog,noauditlog"
</IfModule>
</VirtualHost>
この意図は
- インターネット環境で必須となっている
- 常時SSL化
- 適切なセキュリティヘッダーの付与
- 自宅など、自分のアクセスログを残さない
- 過剰なクローラーを排除し、サーバの負荷を抑える。
- クローラーのエージェントすら無視するアクセス元はアクセスさせない
- Mod_Securityが検知したIPアドレスをリスト化し、再攻撃をさせない
仕組みです。
そして、重要なのは、403(Forbidden)に対して404(Not Found)を返す処置です。
これを行わず403としてしまうと、攻撃者は「ここには『そうまでして守りたい貴重な情報がある』に違いない。なら別の手段を試みよう」という心理が働きます。そのため「ここには何もない」と示すことで、追及の手を緩めさせる意図があります。
bad-bot listの例
以下に示すのは、筆者が実際に出会った「robots.txtを無視し、過剰なまでのクローリングを繰り返す」リストです。
SetEnvIfNoCase User-Agent "facebookexternalhit/1\.1" bad_bot dontlog
SetEnvIfNoCase User-Agent "SemrushBot/7~bl" bad_bot dontlog
SetEnvIfNoCase User-Agent "AhrefsBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "MJ12bot" bad_bot dontlog
SetEnvIfNoCase User-Agent "DotBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Baiduspider" bad_bot dontlog
SetEnvIfNoCase User-Agent "YandexBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Sogou web spider" bad_bot dontlog
SetEnvIfNoCase User-Agent "Exabot" bad_bot dontlog
SetEnvIfNoCase User-Agent "MegaIndex\.ru" bad_bot dontlog
SetEnvIfNoCase User-Agent "SeznamBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "BLEXBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Bytespider" bad_bot dontlog
SetEnvIfNoCase User-Agent "DataForSeoBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "serpstatbot" bad_bot dontlog
SetEnvIfNoCase User-Agent "SeekportBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "index\.community crawler" bad_bot dontlog
SetEnvIfNoCase User-Agent "PetalBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "BacklinksExtendedBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "meta-externalagent/1\.1" bad_bot dontlog
SetEnvIfNoCase User-Agent "ICC-Crawler" bad_bot dontlog
SetEnvIfNoCase User-Agent "bingbot" bad_bot dontlog
SetEnvIfNoCase User-Agent "msnbot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Applebot" bad_bot dontlog
SetEnvIfNoCase User-Agent "DuckDuckBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Majestic-SEO" bad_bot dontlog
SetEnvIfNoCase User-Agent "cognitiveSEO" bad_bot dontlog
SetEnvIfNoCase User-Agent "archive\.org_bot" bad_bot dontlog
SetEnvIfNoCase User-Agent "CCBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "Custom-AsyncHttpClient" bad_bot dontlog
SetEnvIfNoCase User-Agent "ImagesiftBot" bad_bot dontlog
SetEnvIfNoCase User-Agent "GPTBot/1\.2" dontlog
SetEnvIfNoCase User-Agent "Barkrowler/0\.9" bad_bot dontlog
SetEnvIfNoCase User-Agent "ClaudeBot/1\.0" bad_bot dontlog
SetEnvIfNoCase User-Agent "Cypex" bad_bot dontlog
SetEnvIfNoCase User-Agent "^$" bad_bot dontlog
これらは「ログ汚染」レベルで執拗なアクセスを繰り返す、AI時代ならではの頭痛の種。これは名指しで非難しますが、facebookのbotは何かのDDoSと見まがうまでのアクセスでした。
SetEnvIfNoCase User-Agent "^$" bad_bot dontlog
最終行は、エージェント(ブラウザやクローラー)すら書いていない初歩的で機械的なクローラー/スクレイパーへの対処です。
ip-blacklist.confの内容
以下のような内容です。一部は実在のものを交えています。
#
# IPアドレスベースのアクセスブロックリスト
# -------------------------------------------------
# このファイルは、Apacheの mod_rewrite を使用して、
# 特定のIPアドレスからのアクセスを拒否するために使われます。
#
# 各行の末尾には [OR] フラグを付けます。
# ただし、ファイル全体の最後の条件となる行には [OR] を付けません。
#
# ローカルホストからのアクセスは常に許可する (ブロック対象から除外)
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
# ─── 正規表現の書き方ガイド ───
#
# 例1: 単一のIPアドレスをブロック (完全一致)
# --> ^192\.0\.2\.1$
# ^ は行の先頭、 $ は行の末尾を意味します。
# ドット(.)は正規表現では特殊な意味を持つため、
# バックスラッシュ(\)を付けて「\.」と記述します。
#
# 例2: 特定のネットワーク範囲(/24)をブロック
# --> ^192\.0\.2\.
# 行の末尾を示す $ を付けないことで、「192.0.2.」で始まる
# 全てのIP (192.0.2.0 ~ 192.0.2.255) をブロックします。
#
# 例3: 複数のネットワーク範囲(/23)をブロック
# --> ^198\.51\.(100|101)\.
# ( | ) を使うことで、「198.51.100.」と「198.51.101.」の両方を
# ブロックの対象にできます。
#
# 例4: 少し複雑な範囲をブロック
# --> ^203\.0\.113\.(1[6-9]|2[0-9]|3[0-1])\.
# [ ] を使うことで、より複雑な範囲指定が可能です。
# この例では「203.0.113.16」から「203.0.113.31」までをブロックします。
#
# ─── 汎用的なブロックルール (サンプル) ───
# 特定のクラウドプロバイダーからのスキャン活動 (例: AbuseIPDB等で報告多数)
# 例: 203.0.113.0/24
RewriteCond %{REMOTE_ADDR} ^203\.0\.113\. [OR]
# 特定のホスティングサービスからの広範囲な偵察活動
# 例: 198.51.100.0/23
RewriteCond %{REMOTE_ADDR} ^198\.51\.(100|101)\. [OR]
# 過去に攻撃が確認された単一のIPアドレス
RewriteCond %{REMOTE_ADDR} ^192\.0\.2\.123$ [OR]
RewriteCond %{REMOTE_ADDR} ^192\.0\.2\.234$ [OR]
# ─── ここから下に新しいルールを追記します ───
# (新しいルールには行末に [OR] を付けてください)
# ─── ここより下は編集しないでください ───
#
# ファイル内の最後のルールになります。
# この行には [OR] を付けないでください。
RewriteCond %{REMOTE_ADDR} ^192\.0\.2\.99$
このリストをエージェントと別に設定するのは「実在のブラウザ(Chrome, Firefox, Safali)を偽装して過剰なアクセスや不審な攻撃」を仕込むためのものです。
/etc/modsecurity/ip-blacklist.txt の例
# ModSecurity用 IPブラックリスト
# -------------------------------------------------
# 1行に1つのIPアドレス、またはネットワーク範囲(CIDR形式)を記述します。
# コメント行は # で始めます。
#
# 単一のIPアドレス
192.0.2.1
198.51.100.200
これは、単にIPアドレスを羅列したテキストファイル…… ですが、別項で記述する「Mod_Security等が検知したアクセス元」を追記することで、「一度でも攻撃を試みたアドレスの再侵入を許さない」仕組みにしています。
コメントを残す