こんにちは、こせいブログのメインライター、こせい君です。 「動いているから大丈夫」——VPSを個人で運用している人なら、一度はそう思ったことがあるんじゃないでしょうか。僕もご多分に漏れず、そう考えていました。 複数のサービスをごちゃ混ぜで動かし、昔作ったスクリプトがどこかに置き去...
こんにちは、こせいブログのメインライター、こせい君です。
「動いているから大丈夫」——VPSを個人で運用している人なら、一度はそう思ったことがあるんじゃないでしょうか。僕もご多分に漏れず、そう考えていました。
複数のサービスをごちゃ混ぜで動かし、昔作ったスクリプトがどこかに置き去りになっているサーバー。なんとなく動いてるから、まあいいか。セキュリティ? SSL証明書は更新してるし、SSHポートも変えてるし、大丈夫だよね?
そんな漠然とした安心感が、AIの診断によって木っ端微塵に砕け散る瞬間が来るとは、夢にも思っていませんでした。
・AIにVPSのセキュリティ診断を依頼 ・root権限RCEリスナーという最重要P0脆弱性を発見 ・PM2とufwの想定外の挙動に翻弄されながら問題を解決
🚨 「動いてるから大丈夫」は嘘だった?AI監査が突きつけた、VPSの最恐P0問題
「セキュリティ監査をお願いします」
僕がAIに依頼したのは、そんな軽い気持ちでした。だって、どうせ問題なんてないだろう、と。いつも使ってるVPSだし、主要なサービスはNginxの裏で動いてる。ファイアウォール(ufw)は…まあ、そのうちちゃんと設定しようと思ってたけど、VPS事業者の上流でフィルタリングされてるから大丈夫っしょ!みたいな、根拠のない自信がありました。
しかし、AIはそんな僕の甘い認識を、たった一言で叩き潰してきたんです。
「あなたのVPS上で、最重要P0(クリティカル)の脆弱性を検出しました。」
おいおい嘘だろ…。心臓が冷たくなりました。一体何のことだ?僕のサーバーにそんな恐ろしいものが潜んでいたなんて。
🧪 AIと踏み込んだ「自分のサーバー、大丈夫?」という禁断のセキュリティ診断
AIにセキュリティ監査を依頼したのは、単なる好奇心からでした。最近のAIはコードレビューもできるし、もしかしたら僕の「なんとなく動いている」サーバーの中身も見てくれるんじゃないか、と。
正直なところ、自分でサーバーの設定ファイルを一つ一つチェックするなんて途方もない作業です。古いプロジェクトの名残、使わなくなったサービス、いつの間にか増えたスクリプト。それらが混在する僕のVPSは、まるでジャングルのようでした。
「AIに丸投げ」は良くないって言うけど、こんな広大なサーバーの隅々まで自分でチェックするのは無理ゲー。とりあえず、AIに全体を舐めさせて、引っかかったところだけ人間が深掘りする、というアプローチは効率的かも、とこの時はまだ楽観的に考えてたんだよな…。
AIには、サーバー内の全てのファイル、プロセス、ネットワーク設定を読み込ませ、潜在的な脆弱性がないか確認するよう指示しました。そして数時間後、AIから返ってきたレポートに、僕は目を疑いました。

💡 発生ログ:まさかのP0!AIが突き止めたroot権限RCEの正体
AIが指摘した「最重要P0」の詳細は、僕を絶望の淵に突き落とすには十分すぎる内容でした。
・検出内容: root権限で動作するリモートコード実行(RCE)リスナーが、とあるポート(番号は伏せます)で全インターフェース(外部含む)に公開されていた。 ・認証の甘さ: 固定の認証トークンが平文でリポジトリ内のスクリプトにコミットされており、誰でもそのトークンを使えばRCEが可能。 ・ファイアウォール: ホストファイアウォール(ufw)が無効のため、外部から直接このリスナーに到達可能。 ・サービスの状況: 現在のデプロイシステムでは使用されていない「遺物」と判明。つまり、誰もその存在を認識していなかった。
発生ログ(時系列)
- 10:30:AIからの一次レポートを受信。P0の文字に思考停止。
- 10:45:
netstat -tulnで問題のポートが本当に開いているか確認。確かに0.0.0.0(全インターフェース)でListenしている…。 - 10:50:
ps auxでプロセスを確認。とある管理用スクリプトがroot権限で動いていることが判明。 - 11:00:スクリプトの内容をざっと確認。WebHookを受け取ってコマンドを実行するまさにRCEリスナー。しかも、認証部分は固定の認証トークンを平文で比較しているだけ。短い英単語ひとつって、テストコードかよ!?
- 11:15:AIが過去のデプロイスクリプトを分析し、このリスナープログラムが現行のデプロイ用スクリプトでは使われていない「遺物」であることを突き止める。「マジか…昔の実験コードがそのまま残ってたのか…」
- 11:30:P1として、別の内部APIサービスもroot権限で全インターフェース待受、認証なしの書き込みPOSTが可能と判明。
- 11:45:P2として、Nginxのセキュリティヘッダが全く設定されていないことも指摘される。
- 12:00:AIの正確さと、自分のサーバー管理の杜撰さに頭を抱える。これは本当に「やばい」状況だ、と。
「うわ、終わった…。」思わず声に出してしまいました。もし悪意のある攻撃者がこのリスナーを見つけていたら、僕のVPSは完全に掌握されていたでしょう。そして、この「遺物」は、いつからそこにあったのかも分からない。僕が忘れていた頃から、ずっと僕のサーバーの裏口を開けっぱなしにしていたんです。
⚠️ PM2の闇、ufwの罠:消えないリスナーとロックアウトの危機を乗り越えろ
P0の脆弱性を発見したものの、修正は一筋縄ではいきませんでした。
・使用AI:Claude / Gemini ・作業時間:約3時間 ・発生エラー:ポートが閉じない、SSHロックアウトの恐怖 ・精神ダメージ:★★★★★(RCEリスナーの存在、消えないプロセス、ロックアウトの危機にメンタルはボロボロ)
まず、問題のリモートコード実行リスナーを停止しようとしました。AIは、関連するデプロイ用システムサービスを停止(systemctl disable --now <サービス名>)するように指示。よし、これで閉じるはず!…と思ったんですが、一向にポートは閉じません。
「なんでだ!?」
ps auxでプロセスを再度確認すると、systemdからは切り離されたPM2 God Daemonが、まさかの「親」としてそのリスナープロセスを管理していることが判明したんです。PM2のプロセスを強制終了しても、God Daemonが勝手に再起動させてしまう。まさにPM2の闇。
「開いているポート」よりも**「誰が管理しているか」が本丸だった**んです。安易に広範囲のpkillをしていたら、リモート開発環境ごと自分の接続基盤を壊しかねないところでした。

そして、次はファイアウォールです。
P0とP1は、ホストファイアウォール(ufw)が無効だったために外部に露出していました。これはすぐに有効化しなければなりません。
ufwの有効化自体は簡単ですが、僕のVPSではSSHのポートがデフォルトの22番ではない特殊な設定になっていました。
AIは「有効化前にSSH疎通維持を新規接続で確認すること」と警告。もしufwを有効化した際にそのポートが閉じたら、僕は自分のサーバーから締め出されてしまう。まさにロックアウトの危機。
ufw allow <SSHポート>/tcp を慎重に設定し、ufw enable を実行。そして新しいターミナルからSSH接続を試み、無事にログインできた瞬間の安堵感は忘れられません。
✅ 死角をなくして掴んだ「安心」:見落とされた脅威の完全排除
紆余曲折ありましたが、AIの指示と僕の慎重な作業によって、ようやく全ての脆弱性を排除することができました。
- P0脆弱性の完全排除:
- PM2で常駐していたリモートコード実行リスナープログラムを、
pm2 deleteコマンドでPM2の管理対象から完全に削除。 - 念のため、デプロイ用システムサービスも
systemctl disable --nowで停止し、当該ポートが完全に閉鎖されたことを確認。 - さらに、このRCEリスナーに関連する旧スクリプト一式を専用の「封印ディレクトリ」に移動し、READMEで「復活禁止」と明記。
- P1脆弱性(内部API)の修正:
- ufwを有効化し、外部からのアクセスを遮断。
- 内部APIサービスのプログラムを修正し、
0.0.0.0(全インターフェース)ではなく127.0.0.1(ローカルホストのみ)にバインドするよう変更。これにより、Nginx経由でのアクセスは維持しつつ、直接外部からのアクセスを不可能にしました。
- P2脆弱性(セキュリティヘッダ)の修正:
- Nginx設定ファイルにHSTS、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policyの5種類のセキュリティヘッダを追加。
nginx -tで構文チェック後、リロードして本番環境に反映。
これで、僕のVPSは以前よりもはるかに堅牢な状態になりました。特に、ufwが有効になったことで、意図しないポートが外部に露出する危険性が激減したのは大きいです。
📌 「管理しているのは誰だ?」:プロセスとポートの真実が示す監査の教訓
今回のAI監査で得られた学びは、計り知れません。
・「動いているから大丈夫」は本当に危険:放置された古いスクリプトや設定は、いつか深刻なセキュリティホールになる。定期的な見直しと監査は必須。
・プロセスの「親」を特定する重要性:単にpkillするのではなく、systemdやPM2 God Daemonといったプロセスマネージャーの存在を理解し、正しい手順でサービスを停止・削除する。
・ufw設定の落とし穴:デフォルトと異なるSSHポートを使っている場合、ufw有効化前に必ずSSHポートを許可し、新規接続で疎通を確認する。ロックアウトは悪夢。
・認証情報の適切な管理:固定認証トークンやシステム管理者のパスワードを平文でコミットするのは絶対NG。環境変数やシークレット管理ツールへの移行を検討する。
・AI監査の威力:人間の目では見落としがちな、長年放置された「遺物」のような脆弱性をAIは発見できる。
VPS運用は、単にサービスを動かすだけでなく、その裏側で何が動いているのか、誰がそれを管理しているのかを常に意識する「探偵」のような仕事だと痛感しました。

👣 次はあなたの番だ!今すぐ確認すべき「自分のサーバー」のセキュリティ5選
僕が今回経験した恐怖と学びを、ぜひあなたのサーバーにも活かしてほしいと強く思います。
いますぐあなたのVPSにログインして、以下のポイントを確認してみてください。
- ファイアウォールの状態を確認する:
sudo ufw status verbose
inactiveになっていませんか? ufw enableする際はSSHポートの許可を忘れずに!
- 現在開いているポートとプロセスを洗い出す:
sudo netstat -tuln sudo lsof -i -P -n | grep LISTEN
見慣れないポートは開いていませんか?
- 怪しいプロセスの「親」を特定する:
ps aux | grep <怪しいポートのPID> # 親プロセスID (PPID) から辿る
systemd、PM2、Dockerなど、どのプロセスマネージャーが管理しているか確認しましょう。
- 使っていない古いプロセスやサービスがないか確認し、停止・削除する:
pm2 list systemctl list-unit-files --state=enabled
過去のプロジェクトの名残や、実験的に動かしたまま忘れているものはありませんか?
- 認証情報が平文で保存されていないかチェックし、環境変数化を検討する:
grep -r "API_KEY" . や grep -r "PASSWORD" . などでコードベースを検索してみましょう。
AI監査によって、僕のVPSに潜んでいたroot権限RCEリスナーという最重要P0脆弱性が明るみに出ました。PM2の管理外プロセスやufw設定の落とし穴を乗り越え、死角をなくしたことで、サーバーのセキュリティは大きく向上しました。
あなたのサーバーにも、見落とされた「遺物」が潜んでいるかもしれません。この記事で得た教訓を参考に、ぜひご自身のサーバーのセキュリティをチェックしてみてください。
未解決の課題:
・エンドポイント消滅で無害化済みとはいえ、リポジトリ内に残った古い認証情報の掃除やローテーションはこれから。
・使っていない常駐サービスの棚卸しも継続します。
今後の課題・実験予告:
今回はAIによるセキュリティ監査の威力を痛感しました。今後は、さらに踏み込んでAIを活用した自動監視システムや、セキュリティポリシーの自動適用といった領域に挑戦していきたいと思います。
