WAF は有効にしただけでも一定の効果がありますが、
自分のサイトに実際に来ている攻撃に合わせると、精度が大きく上がります。
まずログを見る
推測でルールを書かず、実際のアクセスログを集計します。
# 404 が多いパス = 攻撃の試行
awk '$9==404 {print $7}' access.log | sort | uniq -c | sort -rn | head -30
公開直後のサイトでも、次のようなリクエストがすぐ並びます。
/.env
/wp-login.php
/.git/config
/phpmyadmin/
/actuator/health
存在しないパスへの執拗なアクセスは、すべて探索行為です。
存在しないものへのアクセスをブロックする
自サイトが PHP を使っていないなら、.php へのアクセスは100%攻撃です。
(http.request.uri.path contains ".php")
or (http.request.uri.path contains "/wp-")
or (http.request.uri.path contains "/.git")
or (http.request.uri.path contains "/.env")
誤検知の心配が無いため、迷わずブロックできます。
これだけで不正アクセスのログが大幅に減ります。
管理画面を国とIPで絞る
(http.request.uri.path contains "/dashboard"
and ip.geoip.country ne "JP")
国内からしか運用しないなら、これで大半の総当たりが届かなくなります。
固定IPがあるなら、IPで絞るほうがさらに確実です。
ログイン試行にレート制限をかける
パス: /login/
メソッド: POST
しきい値: 10リクエスト / 1分 / 同一IP
アクション: 1時間ブロック
アプリ側の制限と二重にかけるのが要点です。
WAF 側で止まれば、アプリまで到達しません。
誤検知を確認してからブロックする
いきなりブロックにすると、正規のユーザーを弾く危険があります。
段階1: ログのみ(1週間) → 何が引っかかるか確認
段階2: チャレンジ表示 → 疑わしいものに確認を求める
段階3: ブロック
特に検索エンジンのクローラーを弾かないよう注意します。
User-Agent だけでの判定は偽装されるので、正規のクローラーは
IPの逆引きで検証する仕組みを使います。
オリジンへの直接アクセスを塞ぐ
WAF を通さずにサーバーへ直接アクセスされたら意味がありません。
オリジン側でも WAF の IP レンジ以外を拒否します。
ufw default deny incoming
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
ufw allow from $ip to any port 443 proto tcp
done
これを忘れると、実IPが判明した時点で WAF が迂回されます。
効果を測る
導入前: 1日あたりの不正アクセス試行 約2,400件
導入後: オリジンに到達した試行 約30件
ブロック数の推移を記録しておくと、ルールの効果が判断できます。
まとめ
- 推測せず、自分のログから実際の攻撃を見る
- 使っていない技術のパス(
.php/wp-.env)は迷わずブロック - 管理画面は国・IPで絞る
- ログイン試行のレート制限はWAFとアプリで二重に
- ログのみ → チャレンジ → ブロックの順で慎重に上げる
- オリジンへの直接アクセスを必ず塞ぐ