本番サーバーのNginxアクセスログを読み解き、不正アクセスや攻撃の予兆を早期に発見する方法と、発見後の初動対応手順を実案件ベースで解説します。
「ログって見たほうがいいのはわかるんだけど、何を見ればいいの?」
こんな悩みを抱えていませんか?
- サーバーのログファイルはあるけど、何が書いてあるか読み方がわからない
- 「不正アクセスがあった」と聞いて焦ったが、自分のサーバーが狙われているかどうか確認する方法を知らない
- インシデントが起きてから慌てて対応するのではなく、事前に兆候を掴んでおきたい
Nginxのアクセスログは、**サーバーに何が起きているかを正直に記録し続けている「現場の目撃者」**です。読み方さえ知っていれば、攻撃の兆候・不審なスキャン・脆弱性探索の試みを、被害が出る前に発見できます。
弊社でも過去に、WordPress案件のクライアントから「サイトが重い気がする」という連絡を受けてログを確認したところ、海外IPからの大規模なパスワードクラッキング攻撃(ブルートフォース)が進行中だったことがありました。異常に気づいた時点で即座にIPブロックとレート制限をかけ、被害ゼロで収束させることができましたが、もしログを見ていなければアカウント乗っ取りに発展していた可能性は十分ありました。
本記事では、Nginxのログを「実際に読める状態」にしたうえで、怪しいアクセスのパターン別見分け方と初動対応の手順をお伝えします。
なぜNginxログは重要なのか:攻撃の前には必ず「偵察」がある
Webサーバーへの本格的な攻撃は、いきなり始まるわけではありません。多くの場合、以下のフェーズを経て進行します。
flowchart TD
A[🔍 偵察・スキャン] --> B[🎯 脆弱性の特定]
B --> C[💥 攻撃の実行]
C --> D[🚪 バックドア設置]
D --> E[📤 情報窃取・改ざん]
style A fill:#FEF3C7,stroke:#F59E0B
style B fill:#FEF3C7,stroke:#F59E0B
style C fill:#FEE2E2,stroke:#EF4444
style D fill:#FEE2E2,stroke:#EF4444
style E fill:#FEE2E2,stroke:#EF4444Nginxのアクセスログは、この偵察・スキャンのフェーズを確実に記録しています。/wp-adminへの連続アクセス、存在しないパスへの大量リクエスト、ユーザーエージェントを偽装したクローラー——これらはすべてログに残ります。
逆に言えば、ログを定期的に確認する習慣があれば、攻撃の「準備段階」で検知できるのです。Nginxのデフォルトのアクセスログは通常 /var/log/nginx/access.log に保存されており、エラーログは /var/log/nginx/error.log にあります。
Nginxログの基本構造を理解する
まずはログの1行が何を意味するのかを把握しましょう。デフォルトの combined フォーマットでは、以下のような形式で記録されます。
203.0.113.42 - - [15/Jun/2025:03:17:42 +0900] "GET /wp-login.php HTTP/1.1" 200 3542 "-" "Mozilla/5.0 (compatible; Googlebot/2.1)"
各フィールドの意味は次のとおりです。
| フィールド | 内容 |
|---|---|
203.0.113.42 |
クライアントIPアドレス |
[15/Jun/2025:03:17:42 +0900] |
アクセス日時 |
GET /wp-login.php HTTP/1.1 |
HTTPメソッド・リクエストパス・プロトコル |
200 |
HTTPステータスコード |
3542 |
レスポンスのバイト数 |
"-" |
リファラー(どこからアクセスしてきたか) |
"Mozilla/5.0..." |
ユーザーエージェント |
この7つの要素をセットで読む癖をつけると、怪しいアクセスのパターンが見えてきます。
怪しいアクセスのパターンと見分け方
実際に遭遇しやすい攻撃パターンを3種類に分けて解説します。
パターン①:ブルートフォース攻撃(総当たり)
同一IPから短時間に/wp-login.phpや/adminへ大量のPOSTリクエストが来ている場合、パスワードの総当たり攻撃が疑われます。
以下のコマンドで、アクセス数が多いIPを抽出できます。
# 特定パスへのアクセス数をIP別に集計
grep 'POST /wp-login.php' /var/log/nginx/access.log \
| awk '{print $1}' \
| sort | uniq -c | sort -rn | head -20
出力例で1つのIPが数百〜数千件を記録していれば要注意です。さらに、ステータスコードが 401(認証失敗)や 200(成功)を繰り返している場合は緊急性が高いと判断してください。
# 特定IPのアクセスとステータスコードを時系列で確認
grep '203.0.113.42' /var/log/nginx/access.log \
| awk '{print $4, $9}' | tail -50
パターン②:パス探索・脆弱性スキャン
404エラーが短時間に大量発生しているときは、存在しないパスを片っ端から叩いて脆弱なエンドポイントを探す「スキャン」が行われている可能性があります。
# 404エラーが多いリクエストパスのランキング
grep ' 404 ' /var/log/nginx/access.log \
| awk '{print $7}' \
| sort | uniq -c | sort -rn | head -20
典型的な探索パスの例を示します。
/phpMyAdmin/index.php
/.env
/config/database.yml
/wp-config.php.bak
/shell.php
/admin/config.php
これらのパスは正常なユーザーが踏むことはありません。同一IPからこうした404が連続している場合は、スキャンツールによる自動探索と断定して問題ありません。
パターン③:不審なユーザーエージェント
正規のブラウザやGooglebotを装いながら、実際には攻撃ツールや脆弱性スキャナーであるケースもあります。以下のUAは注意が必要です。
# ユーザーエージェントの種類と件数を確認
awk -F'"' '{print $6}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -30
以下のキーワードを含むUAは悪意ある探索ツールである可能性が高いです。
sqlmap → SQLインジェクションスキャナー
Nikto → Webサーバー脆弱性スキャナー
Masscan → ポートスキャナー
zgrab → プロトコルスキャナー
python-requests → スクリプトによる自動アクセス(文脈次第)
発見後の初動対応:焦らず順番に対処する
不審なアクセスを確認したら、以下の手順で対応します。
ステップ1:該当IPを一時ブロック
Nginxの設定ファイルに deny ディレクティブを追加するか、iptables/ufw でブロックします。
# /etc/nginx/conf.d/blocklist.conf
geo $blocked_ip {
default 0;
203.0.113.42 1; # ブルートフォース攻撃元
198.51.100.77 1; # スキャン元
}
server {
# ...
if ($blocked_ip) {
return 403;
}
}
# 設定反映
nginx -t && systemctl reload nginx
ステップ2:レート制限を設定する(再発防止)
1件ブロックしても、別のIPから同様の攻撃が来ることがあります。根本的な対策として、Nginxのレート制限を導入します。
# /etc/nginx/nginx.conf(httpブロック内)
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
limit_req_status 429;
# 既存のproxy_pass等はそのまま
}
}
これにより、1つのIPからのログイン試行を1分間に5回までに制限できます。ブルートフォースツールは通常1秒に数十リクエストを送るため、これだけで攻撃効率を大幅に落とせます。
ステップ3:ログを証拠として保全する
対応と並行して、攻撃の証拠となるログを保全します。サーバーの再起動やログローテーションで消えてしまう前に退避させましょう。
# 該当日のアクセスログをバックアップ
cp /var/log/nginx/access.log /home/backup/incident_$(date +%Y%m%d_%H%M%S).log
# 攻撃元IPのアクセス履歴だけ抽出して保存
grep '203.0.113.42' /var/log/nginx/access.log \
> /home/backup/attacker_203.0.113.42.log
よくある失敗パターンと対処法
現場でよく見かけるミスを共有しておきます。
① Googlebotを無条件に信用してしまう
ユーザーエージェントに Googlebot と書いてあっても、実際にGoogleのサーバーから来ているとは限りません。本物のGooglebotは逆引きDNSで確認できます。
# IPを逆引きして"google.com"ドメインか確認
host 66.249.79.10
# 結果例: 10.79.249.66.in-addr.arpa domain name pointer crawl-66-249-79-10.googlebot.com.
逆引きした際に googlebot.com や google.com が返らないIPは偽Googlebotです。
② 404の大量発生をサーバーエラーと混同する
「404が大量に出ている=サーバーが壊れた」と勘違いして、不必要にサーバーを再起動してしまうケースがあります。404は「ページが見つからない」という正常なレスポンスです。問題はその発生元とパターンです。慌てて再起動すると、ログが消えて証拠が失われることもあるため注意してください。
③ ブロック後の確認を怠る
IPをブロックして満足してしまい、その後も同じパターンの攻撃が別IPから継続しているのを見落とすケースがあります。初動対応後は24〜48時間、通常より高い頻度でログを確認する習慣をつけましょう。
サーバー管理、丸ごとお任せください
サーバー保守・運用
監視・障害対応・パフォーマンス改善まで、安定稼働をサポートします
※ 通常1営業日以内にご返信します
まとめと次のステップ
Nginxのアクセスログは、一度読み方を覚えてしまえば、サーバーの「異変」を早期に察知するための最も強力なツールになります。特別なセキュリティ製品を導入しなくても、コマンドライン上で数分確認するだけで、攻撃の兆候を発見できるケースは少なくありません。
弊社が管理するサーバーでは、週次のログレビューと自動アラートの組み合わせにより、過去2年間でインシデントによる実害ゼロを継続しています。「異常が起きてから対処する」から「兆候を掴んで先手を打つ」運用に切り替えることで、対応コストも精神的な負担も大幅に下がります。
もし「ログを見ても何が正常かわからない」「そもそもサーバーにssh接続できる人間がいない」という状況であれば、定期的なログレビューや監視体制の構築をご支援することも可能です。お気軽にご相談ください。