CentOS 7でRemiのPHP 8.1を使っている環境は、yumで待っていても脆弱性の修正版は届きません。ただしRemiは8.1のソースRPMにセキュリティ修正を入れ続けているので、CentOS 7上でビルドし直せば修正版を入れられます。必要な変更はICUの要求バージョンを1か所下げることだけでした。
この記事では、2026年10月のPHPの緊急修正(CVE-2026-109618 / CVE-2026-109619)を例に、ビルドから入れ替えまでの手順と、入れ替え時に止まる箇所をまとめます。
修正版がyumで届かない理由を確認する
PHP 8.1は2025年12月に公式サポートが終了していて、今回の修正版も8.2以降にしか出ていません。CentOS 7向けのRemiリポジトリも2024年6月の8.1.29で更新が止まっているため、yum updateをしても何も入りません。
一方で、Remiが公開しているソースRPMの置き場には、EL8/EL9向けに作られた8.1のソースRPMが今も更新されています。今回は2026年10月21日付けのphp81-php-8.1.34-6.remi.src.rpmが該当し、変更履歴に次の記載がありました。
* Wed Oct 21 2026 Remi Collet <remi@remirepo.net> - 8.1.34-6
- Mitigation fix Avoid state corruption via bailout
CVE-2026-109618, CVE-2026-109619
中に入っているパッチは、PHPのセキュリティチームが8.1向けに公開したソースパッチと同じ内容です。8.1.29以降に出た他のCVEの修正も含まれているので、古い8.1から一度に追いつけます。
CentOS 7のビルド環境を用意する
本番サーバーにビルド用のパッケージを入れたくないので、ローカルのDockerでCentOS 7のコンテナを使います。CentOS 7のミラーは閉鎖されているため、リポジトリの参照先をvaultとEPELのアーカイブに書き換えます。
docker run -it --platform linux/amd64 --name el7build centos:7 bash
sed -i -e "s|^mirrorlist=|#mirrorlist=|" -e "s|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|" /etc/yum.repos.d/CentOS-*.repo
yum -y install epel-release yum-utils rpm-build
cat > /etc/yum.repos.d/epel.repo <<'REPO'
[epel]
name=epel7 archive
baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch/
enabled=1
gpgcheck=0
REPO
yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-safe remi
yum -y install scl-utils-build php81-build php81-scldevel
ソースRPMを展開してICUの要求だけ下げる
ソースRPMはrpm -iで展開しようとすると、署名を検証できずに止まります。rpm2cpioで展開すればこの検証は行われません。
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS
cd ~/rpmbuild/SOURCES
curl -LO https://rpms.remirepo.net/SRPMS/php81-php-8.1.34-6.remi.src.rpm
rpm2cpio php81-php-8.1.34-6.remi.src.rpm | cpio -idm
mv php.spec ../SPECS/php81.spec
specはICU 74以上を要求していますが、CentOS 7向けのRemiにあるのは73までです。そのまま依存関係を入れようとするとNo Package found for pkgconfig(icu-i18n) >= 74で止まるので、73に下げます。変更はこの1か所だけで、他の依存はCentOS 7向けのRemiとEPELですべてそろいました。
sed -i -E "s/(pkgconfig\(icu-(i18n|io|uc)\)) *>= *74/\1 >= 73/" ~/rpmbuild/SPECS/php81.spec
yum-builddep -y --define "scl php81" ~/rpmbuild/SPECS/php81.spec
RPMをビルドする
distには自前ビルドだと分かる値を入れておくと、後でrpm -qを見たときに区別できます。PHP自体のテストを省くと、30分ほどでRPMがそろいます。
rpmbuild -bb --without tests --define "scl php81" --define "dist .el7.local" ~/rpmbuild/SPECS/php81.spec
ls ~/rpmbuild/RPMS/x86_64/
cronなどで/usr/bin/phpを使っている場合は、SCLではない方のphpも同じ手順でビルドします。ソースRPMはphp-8.1.34-6.remi.src.rpm、中のspecはphp81.specという名前で、--define "scl php81"を付けずにビルドします。
入れ替えで止まる箇所と対処
サーバーにphp81-php-develが入っていると、更新はこのエラーで止まります。develは同じバージョンのcliを要求しているので、転送するRPMにdevelも含めます。
エラー: パッケージ: php81-php-devel-8.1.18-1.el7.remi.x86_64 (@remi)
要求: php81-php-cli(x86-64) = 8.1.18-1.el7.remi
あわせて次の3点を押さえておきます。
- ICUを73に下げたので、Remiの
libicu73のRPMも一緒に転送します。 - サーバー側のミラー参照は死んでいるので、
yum --disablerepo='*' localinstall *.rpmのようにリポジトリを全部無効にしてローカルのRPMだけで入れます。 - 古い8.1のRPMはもう入手できず、
yum downgradeでは戻せません。事前にtar czf /path/to/backup/php81.tgz /opt/remi/php81 /etc/opt/remi/php81のように丸ごと固めておき、戻すときはこれを展開します。
php-fpmはRPMの更新時に自動で再起動されたため、手動での再起動は不要でした。設定ファイルは変更済みのものが残り、新しい既定値は.rpmnewとして横に置かれます。
入れ替え前に確認できたことと、できなかったこと
本番と同じ構成(CentOS 7、Apache 2.4.6、Remiのphp-fpm)を再現したコンテナでEC-CUBE 4.2を動かし、更新の前後で同じリクエストを流して比べました。フロント・管理画面・カートの150件ほどの応答コードと、画面の表示金額は更新前と一致しました。apcu・mcrypt・ssh2のような後から入れた拡張も、PHPのAPI番号が8.1の間は変わらないため、作り直さずにそのまま読み込まれました。
確認していないのは、PHP自体のテストスイートと、攻撃コードで脆弱性が塞がったかの確認です。パッチがPHP公式のものと同一であることと、ビルドログで適用されたことまでを確認しています。
この方法はOSのサポート切れを解決するものではありません。サーバーを移すまでの時間を稼ぐ手段として使い、移設先ではディストリビューションが修正を配布しているPHPを選んでください。