「ログは出している」で満足していないか?— 侵入者が見ているのは、君たちが無視した「ノイズ」だ
現場でインシデント対応をしていると、必ず耳にするフレーズがある。「ログは全部取っています」。だが、そのログを誰が、どうやって見ているのかと問うと、途端に言葉が詰まる。
攻撃者は、君たちが「ただのアクセスエラー」と見過ごすそのログの隙間を縫って侵入してくる。今日は、教科書的な「ログを取れ」というアドバイスの先にある、「攻撃者の足跡を確実に検知し、SIEMで自動排除する」ための泥臭い実務の話をしよう。
—
1. 攻撃者はどこで「テスト」をしているのか
攻撃者は、いきなり本丸を突くことはない。まずは自動スキャンツール(ffufやNucleiなど)を使って、ディレクトリの探索やパラメータのファジングを行う。ここで出力される「404 Not Found」や「403 Forbidden」の連続は、まさに「これから攻撃します」という宣戦布告だ。
これを放置しているのは、自宅のドアをガチャガチャと全開で回されているのに、「鍵がかかっているから大丈夫」と寝ているのと同じだ。
ログに出力すべき「最低限の項目」
単なるアクセスログでは不十分だ。以下の項目が欠けているなら、今すぐ追加実装せよ。
- セッションIDの断片(セッションハイジャック検知用)
- リクエストボディのハッシュ値(改ざん検知)
- X-Forwarded-For(プロキシ経由の真のIP特定)
- 処理時間(ms単位)(DoSや重いクエリの検知)
—
2. ログを「武器」に変える実装サンプル
ただログをファイルに書き出すだけでは意味がない。SIEMが食いつきやすい構造化データ(JSON)で出力するのが鉄則だ。
Python (Flask/FastAPI) での構造化ロギング例
構造化ログにすることで、SplunkやCloudWatch Logsで「特定のIPからの403エラーが1分間に10件以上」といったクエリを瞬時に叩けるようになる。
import logging
import json
import time
from flask import request
JSON形式でログを吐き出すための設定
logger = logging.getLogger(“security_logger”)
logger.setLevel(logging.INFO)
def log_security_event(event_type, details):
log_payload = {
“timestamp”: time.time(),
“event_type”: event_type,
“client_ip”: request.headers.get(“X-Forwarded-For”, request.remote_addr),
“user_agent”: request.headers.get(“User-Agent”),
“path”: request.path,
“details”: details
}
# SIEMが解析しやすいJSON文字列で出力
logger.info(json.dumps(log_payload))
利用イメージ:認証失敗時に呼び出す
log_security_event(“AUTH_FAILURE”, {“username”: “admin”, “reason”: “invalid_password”})
—
3. SIEM連携:インシデント検知を自動化する
ログを溜め込む「墓場」にするな。CloudWatch Logsの「メトリクスフィルター」を使って、異常な挙動を自動的にアラートに変える。
設定例:CloudWatch Logs メトリクスフィルター
- フィルターパターン: `[timestamp, event_type=”AUTH_FAILURE”, ip, …]`
- メトリクス値: `1`
- アラーム設定: 1分間に閾値(例: 5回)を超えたら、Slackのセキュリティチャンネルに通知し、同時にLambdaをキックして該当IPをWAFのブロックリストに自動追加する。
これができれば、深夜3時に君が叩き起こされる回数は劇的に減るはずだ。
—
4. WAFとNginx:水際で防ぐための設定
ログ監視だけでなく、攻撃者の手口を無効化する設定も共有しておく。Nginxの`limit_req`を使えば、総当たり攻撃に対する簡易的なレートリミットをかけられる。
nginx.conf: 攻撃者のアクセスを制限する設定
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
server {
location /login {
# 1秒間に5回以上のアクセスは429(Too Many Requests)を返す
limit_req zone=one burst=10 nodelay;
proxy_pass http://app_server;
}
}
この設定のポイントは、`burst`を適切に設定することだ。正当なユーザーの操作を阻害せず、攻撃ツールの高速なリクエストだけを確実に弾く。
—
最後に:セキュリティは「監視」から始まる
いいか、完璧な防御など存在しない。だが、「攻撃に気づくまでの時間」を短縮することは可能だ。
君たちが書く一行のログが、将来の重大インシデントを防ぐ証拠になるかもしれない。SIEMへのログ送信は、単なる監視業務ではなく、君たちのシステムを守るための「防衛戦の最前線」だ。
まずは今すぐ、手元のWebアプリのログを確認してくれ。もし「200 OK」以外のログを無視しているようなら、そこが君のシステムの最大の弱点だ。現場からは以上だ。また何かあればいつでも聞きに来てくれ。

コメント