不正アクセスが疑われる状況では、最初の1時間の判断が被害範囲を左右します。
慌てて対応すると、原因究明に必要な情報を消してしまうことがあります。
最初にやってはいけないこと
- サーバーの再起動(メモリ上の情報が消える)
- ログの削除・ローテーション(証跡が失われる)
- 不審なファイルの削除(何をされたか分からなくなる)
「とりあえずきれいにする」が、最も避けるべき対応です。
初動の順序
1. 影響範囲を止める(被害の拡大防止)
サービス全体を止めるかは、影響の大きさで判断します。
# 疑わしいIPを遮断
ufw insert 1 deny from <IP>
# 侵害された疑いのあるアカウントを無効化
python manage.py shell -c "
from django.contrib.auth import get_user_model
u = get_user_model().objects.get(email='...'); u.is_active = False; u.save()"
# 全セッションを破棄(乗っ取りが疑われる場合)
python manage.py shell -c "
from django.contrib.sessions.models import Session; Session.objects.all().delete()"
2. 証跡を保全する
削除より先にコピーを取ります。
mkdir -p /var/incident/$(date +%Y%m%d_%H%M)
cp -a /var/log/nginx /var/log/myapp /var/incident/.../
pg_dump -Fc mydb > /var/incident/.../db.dump
last -F > /var/incident/.../logins.txt
ps auxf > /var/incident/.../processes.txt
ss -tunap > /var/incident/.../connections.txt
別のディスクか別ホストに保存します。同じ場所に置くと、
攻撃者に消される可能性があります。
3. 侵入経路を推定する
# 認証の成功・失敗
grep -E "Accepted|Failed" /var/log/auth.log | tail -50
# 管理画面への成功アクセス
awk '$9==200 && $7 ~ /dashboard|admin/' /var/log/nginx/access.log
# 最近変更されたファイル
find /srv/app -mtime -2 -type f -ls | head -50
最後のコマンドが有効で、身に覚えのない更新日時のファイルが
見つかることがあります。
4. 認証情報を入れ替える
侵入が確認できたら、関連する秘密情報をすべて再発行します。
- DBのパスワード
- APIキー、トークン
- SSH鍵
SECRET_KEY(セッションが無効化される)
「どれが漏れたか分からない」場合は、全部入れ替えるのが正解です。
5. 記録を残す
発生検知: 2025-04-21 14:32(監視アラート)
初動開始: 14:35
遮断実施: 14:41(IP: xxx.xxx.xxx.xxx)
証跡保全: 14:50 完了
推定経路: 管理画面への総当たり(14:02〜14:30、約1,800回)
影響範囲: 管理者アカウント1件のログイン成功を確認
時系列で記録します。後から報告を求められたとき、これが無いと答えられません。
事前に決めておくこと
事故の最中に決めようとすると必ず遅れます。
- 誰が判断するか(サービス停止の決定権)
- 誰に連絡するか(顧客・関係者)
- どこまでを「インシデント」とするか
- 証跡の保存先
紙1枚でよいので、事前に書いておくと初動の速度が変わります。
再発防止まで含めて終わり
復旧しただけでは終わりません。
- 侵入経路を塞いだか
- 同じ経路が他に無いか
- 検知は早かったか、遅かったならなぜか
「検知までにかかった時間」を短くすることが、
次の被害を小さくする最大の要素でした。
まとめ
- 再起動・削除の前に、必ず証跡をコピーする
- 遮断 → 保全 → 経路推定 → 認証情報の入れ替え → 記録の順
- 漏洩範囲が不明なら秘密情報は全部入れ替える
- 時系列の記録を残す
- 判断者・連絡先・保存先は事前に決めておく