Ubuntu 26 / PHP 8.5 移行で発生したトラブルと対処方法|Failed to get boot ID・ProcSubset=pid

Ubuntu 26 と PHP 8.5 への移行作業中に、従来環境では発生しなかった問題をいくつか確認した。本記事では hash 仕様変更や systemctl status 実行時の「Failed to get boot ID」など、実際に遭遇したトラブルと対処方法をまとめる。
※移行はまだ完了していないので、随時追加更新していきます

Ubuntu26・PHP8.5移行で発生した問題

PHP 8.5のhash仕様変更で発生した問題 hashのデフォルト動作変更、php内の内部処理、仕様の変更

軽く受け流せば、すぐに解決出る問題かもしれないが、対処の過程でGPTの修正案がセキュリティ脆弱性を引き起こすものだったので、参考のために書いておく。
GPTは安易に、セキュリティ対策実装をもっともらしい理由をつけて消す。それで、何とか動くケースだったらもしかしたら見逃していたかもしれないが、その修正では動かなかった。じっくりコードを見直したところ、除去してはいけないセキュリティ対策実装であったというものだ。 別な対処方法で解決できた。
 直接原因は、hash値に使用される文字の種類が拡張されたことです。詳細についてはセキュリティにまつわる話なので非公開とします。このようにセキュリティ関係の情報は非公開であることが多いのか、GPTも弱いようです。脆弱性の検出に使うのはよいとしても、セキュリティ確保には十分ではないというか、セキュリティ周りの実装は丸投げするのは危険だろう。

ブラウザ経由の PHP exec()「Failed to get boot ID」が出る systemctl statusでFailed to get boot IDが発生

実装修正で、比較的簡単に回避はできたが、これが発生する原因特定には時間を要している。

# systemctl cat apache2.service
# /usr/lib/systemd/system/apache2.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=https://httpd.apache.org/docs/2.4/

[Service]
Type=notify
Environment=APACHE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/sbin/apachectl start
ExecStop=/usr/sbin/apachectl graceful-stop
ExecReload=/usr/sbin/apachectl graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true
Restart=on-abnormal
OOMPolicy=continue
RemoveIPC=yes

DevicePolicy=closed
KeyringMode=private
LockPersonality=yes
MemoryDenyWriteExecute=yes
PrivateDevices=yes
ProtectClock=yes
ProtectControlGroups=yes
ProtectHome=read-only
ProtectHostname=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes


# systemctl show apache2.service | grep -E 'ProtectProc|ProcSubset|ProtectKernelTunables|ProtectKernelModules|RestrictNamespaces|ProtectSystem|ProtectHome|ReadOnlyPaths|InaccessiblePaths|PrivateTmp|RestrictAddressFamilies'
InaccessiblePaths=/boot /root -/etc/sudoers -/etc/sudoers.d -/etc/ssh -/etc/apt -/etc/.git -/etc/.svn
PrivateTmp=no
PrivateTmpEx=no
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectHome=read-only
ProtectSystem=full
RestrictNamespaces=yes
ProtectProc=invisible
ProcSubset=pid

ProcSubset=pid これが設定されていると、プロセスから見える /proc が自分のPID関連だけに絞られ、/proc/sys/ 配下がまるごと見えなくなりますsystemctl status は内部で /proc/sys/kernel/random/boot_id を読もうとするので、Apache配下のPHPから実行したときだけ「Failed to get boot ID: No such file or directory」が出ていた、というわけです。

対処方法
いろいろな対処方法がありますが、
statusのかわりに showを使うように見直しました。
具体的には次のよう感じです

修正前
$command = "systemctl status NetworkManager.service 2>&1";

変更後
$command = "systemctl show NetworkManager.service -p ActiveState,SubState,ActiveEnterTimestamp 2>&1";

whoコマンドの挙動変化

挙動変化に伴いログイン状態のチェックができなくなっています

# 旧
who | grep tty2

# 新
pgrep -t tty2 2>/dev/null | xargs -r -I{} ps -p {} -o comm= 2>/dev/null | grep -v "^agetty$" | grep -v "^$" | wc -l
# 旧
who

# 新
loginctl list-users
# または
loginctl list-sessions