PHPの重大な脆弱性(通称PHP2Shell)の修正版が出た夜、私がまずやったのは、管理しているサーバーで動いているPHPのバージョンを全部書き出すことでした。
修正版を当てる作業そのものより、どのサーバーのどのサイトが、どのPHPで動いているかを調べるほうに時間がかかりました。台数が少なくても、コマンドを打つPHPと、Webページを返しているPHPのバージョンが違う、といった落とし穴があるからです。
この棚卸しを、Claude CodeでPHPのサーバーを読むだけの作業として任せた手順を紹介します。Claude Codeは、日本語で頼むとAIがプログラムを書いて動かすところまでやる道具です。
先に決めたこと 本番のサーバーには書き込ませない
最初に、AIに任せる範囲を決めました。任せるのは、情報を読んで集めるところまで。PHPの更新やサービスの再起動は、人がやります。
前提として、手元のパソコンから各サーバーにSSH(離れたサーバーに安全に接続する仕組み)でログインできる状態にしてあります。そして、この「読むだけ」を、Claude Codeの設定ではなくサーバーの側で守らせることにしました。棚卸し専用に、管理者の権限(sudo)を持たないユーザーを各サーバーに作り、そのユーザーでだけ接続するようにしたのです。このユーザーでは、PHPのバージョンを表示することはできても、更新や再起動はできません。
ここは、私が最初に間違えかけたところです。Claude Codeには、実行してよいコマンドと禁止するコマンドを決める許可の設定があり、はじめは sudo や systemctl restart を禁止するルールを書いて安心していました。ところが公式ドキュメントには、このルールはClaude Codeが書いたコマンドの文字に対して照合されるもので、プログラムの周りの安全の境界ではないと書かれています。ssh で接続した先のサーバーで実行する命令は、手元から見ると ssh というコマンドの一部なので、この禁止のルールでは止まりません。
禁止のルールは、うっかりを減らす補助としては役に立ちます。ただ、本番のサーバーを守る歯止めは、接続するユーザーの権限で作る。これが今回の一番の学びでした。許可の設定の詳しい書き方は、別の記事にあります。
Claude CodeにPHPの棚卸しを頼む
Claude Codeを起動するフォルダ(作業フォルダ)には、サーバーの一覧だけを置きました。接続先の名前を1行に1つ書いた、hosts.txt という文字のファイルです。そのうえで、Claude Codeにこう頼みました。
「hosts.txt に書いたサーバーそれぞれにSSHで接続して、PHPのバージョンを集めて表にしたい。コマンドで使うPHPと、PHP-FPMやApacheのモジュールで動いているPHPの両方を調べること。読むだけのコマンドだけを使って、設定の変更や再起動はしないこと。結果は inventory.csv(Excelで開ける、カンマ区切りの表のファイル)に書き出して」
SSHは、手元のパソコンから離れたサーバーに安全に接続する仕組みです。読むだけ、と明示しておくのが大事でした。
Claude Codeが組み立てたもの
Claude Codeは、サーバーごとに次のような確認を行うスクリプトを書きました。スクリプトは、決まった手順をまとめて実行する小さなプログラムです。
while read -r host; do
cli=$(ssh -n "$host" 'php -v 2>/dev/null | head -1')
fpm=$(ssh -n "$host" 'for f in /usr/sbin/php-fpm*; do [ -x "$f" ] && "$f" -v | head -1; done')
pkg=$(ssh -n "$host" "dpkg -l 'libapache2-mod-php*' 2>/dev/null | awk '/^ii/{print \$2, \$3}'")
echo "$host,\"$cli\",\"$fpm\",\"$pkg\""
done < hosts.txt > inventory.csv
実行の前に、Claude Codeは各コマンドが何をするかを日本語で説明し、許可を求めてきました。どれも情報を表示するだけのコマンドだったので、許可しました。ssh -n は、1台目の接続が一覧のファイルを読み込んでしまい、2台目以降が飛ばされるのを防ぐための指定です。私の最初の版ではこれが抜けていて、1台目しか表に載りませんでした。Apacheに組み込む方式(mod_php)のPHPは、パッケージ(サーバーに入れるソフトの単位)の一覧からバージョンを読んでいます。Red Hat系(Red Hat Enterprise LinuxやAlmaLinuxなど)のサーバーなら、この部分は rpm -q php に変えます。
出てきた表と、見つかった落とし穴
できあがった表を見て、1台で手が止まりました。コマンドで使うPHPは8.3の修正版なのに、Webページを返しているPHP-FPMは別の系統の8.2で、しかも修正前のバージョンでした。php -v だけを見ていたら、修正済みだと思い込んでいたところです。
Claude Codeには続けて、「修正版より古いものだけに印を付けて、PHPの公式の修正版の番号(8.5.12、8.4.27、8.3.36、8.2.35)と比べた列を足して」と頼みました。これで、手を付ける順番が一目でわかる表になりました。
更新は人がやる
表ができたら、PHPの更新は自分で行いました。Claude Codeに更新までやらせることもできますが、本番のサーバーで、しかも夜中に、確認の画面を流し読みしながら許可を押すのは危ないと判断しました。
更新の手順書を書かせるところまでは、Claude Codeに手伝ってもらっています。サーバーごとに、どのパッケージを更新し、どのサービスを再起動し、最後に何で確かめるかを並べた手順書です。それを見ながら、自分の手でコマンドを打ちました。
Claude Codeを業務で使うときの社内ルールの作り方は、別の記事にひな形付きでまとめています。
棚卸しの表は、次のためにも残しておく
今回作った inventory.csv は、そのまま残してあります。次に重大な欠陥が出たとき、最初の1時間を棚卸しに使わずに済むからです。月に1回、同じ頼み方でClaude CodeにPHPの一覧を作り直させるようにしました。
PHPのバージョンを確かめる手順を、手作業で1台ずつやる場合は、こちらの記事が参考になります。



