CentOS7でPHP8.2.35をコンパイルして使う
- 掲載日
CVE-2026-109618、 CVE-2026-109619では、パッチが配布されたのはPHP7.4以降になります。
比較的新しいOSやサポートの長い(redhatなら5年?)OSを使用していて、かつPHP8.2以上を使用していれば以下で対応は終わったと思います。バージョン同じなのでソフトに影響出る人もほぼほぼいないと思います。
dnf update phpよしんばPHPのバージョンが古くても、以下のコマンドでPHPのバージョンアップ自体はサクッと行けると思います。(※バージョン代わるとソフトにはがっつり影響出るので注意。)
dnf install epel-release
dnf module reset php
dnf module enable php:remi-8.4 # ここは入れたいPHPのバージョンに合わせる
dnf distro-sync phpPHPがちょっと古く(PHP8.1以前)、Cent OS8とか9くらいになるとちょっと怪しくてミラーサーバーのURL書き換えたりしましたがまだPHP本体の更新をdnfコマンドで行けるのでマシです。
# URL書き換え
sed -i 's/^mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
# 後は上と同じコマンドで大体いけると思う。問題はCent OS7で、これはリポジトリが止まっているのでもうミラーサーバーのURL書き換えたってどうにもならない。
dnfコマンドで良い感じにアップデートはできないので、php公式で配布しているソースコードをコンパイルして使用していきます。
コンパイル環境と前提
- Cent OS 7
- PHP7.4 から PHP8.2 に変更(PHP7.4はパッチ配布対象なので上げなくても良かったかも。tarが公式で配られているから8.2にしてますが、7.4も多分gitからインストールして来てやることは同じだと思います。)
- PHPで動かすソフトは気合でインストールするPHPバージョンに対応させていること
- OS7の中でも細かいバージョンの差分や、依存するライブラリの細かいバージョンの違いがあり、
必ずこの手順で上手く行くわけではないことをよくご認識頂き、一旦仮想マシンで試してください。
(実機でいきなり実行はNG。何かあっても責任は負いかねます。)
手順
ソースコードダウンロード
まずphpの公式からソースコードをダウンロードします。
リンクにアクセスして、「Old Stable PHP 8.2.35」の「php-8.2.35.tar.gz」と書いてあるリンクをクリックしてください。
(圧縮形式は自分のサーバー環境で解凍できればどれでもいいです。)
ダウンロードしたファイルはSCPなりrsyncなりWinSCPなりでサーバーの作業用ディレクトリに配置します。
ここでは仮に/tmpに配置します。
(サーバーによっては/tmp配下は自動でクリーンしてたりすると思うので、実際の作業ではどこかオープンでない場所に作業用ディレクトリ作ってやることを推奨します。)
とりあえずconfigure
まず間違いなく成功しませんが、とりあえず配置したディレクトリに移動して、configureを実行します。
なお、以下は恐らく必要な最小のオプションを付けていますが、実際は現在動いているphp.iniの設定などからextensionsを確認して、必要な拡張機能を追加する必要があります。
例えば、以下の場合使わないことはほぼないだろうという事でmbstringをONにするためにenable-mbstringを付けています。
(自分の実際の環境の場合、更にPostgresqlを使うために--with-pgsql=/usr/pgsql-XXや--with-pdo-pgsql=/usr/pgsql-XXオプションを追加する等しました。
どのextensionsにどのオプションが必要か都度調査する必要があるため、巨大なソフトであればあるほど移行の手間がかかると思います。)
cd /tmp/php-8.2.35/
./configure \
--prefix=/usr/local/php82 \
--with-apxs2=/usr/bin/apxs \
--with-config-file-path=/etc \
--enable-mbstringパッケージが無いというエラーが出るため、都度 yum install
上記コマンドを実行すると、「○○というパッケージが無いよ」というエラーが表示されますので、
都度パッケージと、そのパッケージ名の後ろに「-devel」を付けたパッケージをインストールしてください。
エラーメッセージだけだとそのパッケージがあればいいような気がしますが、コンパイルするために開発用のパッケージが必要になるため「-devel」付が必要になります。
例えば自分の場合、postgresql12のパッケージは元から入っていましたが、postgresql12-develのパッケージも必要になるため以下のコマンドを実行しました。
yum install postgresql12 postgresql12-develもうないパッケージを探しに行く
パッケージを入れる→configure実行するの繰り返しで最後までエラー無で通ればいいですが、パッケージが見つからないケースがあります。
自分の場合、postgresql12を使っており、使っているので実行用パッケージは入っていたのですが、postgresql12-develがないため、滅茶苦茶ググり回り、以下のサイトにて見つけました。
- RPM RedHat EL 7 postgresql12-devel 12.20 x86_64 rpm
以下をよく確認してください。- ELの後ろの数字が自分のOSのバージョンと合っていること
- パッケージのバージョンがあっていること
(自分の例で言うと、postgresql13がサーバーでは動いているのに上記を入れることは試しては無いですが出来ないと思います。)
ダウンロードが出来たら、これも作業用ディレクトリ(今回の自分の例であれば/tmp)に配置して、yum install /tmp/postgresqlXX-devel-XX-1PGDG.rhelXX.x86_64.rpmを実行します。
(postgresqlXX-devel-XX-1PGDG.rhelXX.x86_64.rpm部分は各自の環境に合わせて変更。)
これでエラーが出なければパッケージインストールが出来ているので、またconfigure実行に戻りましょう。
configureが通ってmakeでエラー
configureが通ったらあと少しです。続いて、makeコマンドを同じディレクトリ内で実行します。
すんなり通ればOKですが、エラーが出て来ることがあります。
エラーメッセージを見て、cスクリプトを修正と再実行を繰り返します。
自分の場合、/tmp/php-8.2.35/ext/openssl/xp_ssl.cというスクリプトの以下の点を修正しました。
// 修正前のコード
ASN1_STRING_get0_data(san->d.iPAddress)[0]
// 修正後のコード
ASN1_STRING_data(san->d.iPAddress)[0]
// 変更前(524行目付近)
EXPAND_IPV6_ADDRESS(ipbuffer, ASN1_STRING_get0_data(san->d.iPAddress));
// 変更後(行頭に // を付与してコメントアウト)
// EXPAND_IPV6_ADDRESS(ipbuffer, ASN1_STRING_get0_data(san->d.iPAddress));これでmakeが通ればOK。途中WARNINGが出ますがそれは無視します。
make installが通ったら実行ファイルを差し替える
上記makeが通ったらmake installを実行します。
ここでもエラーが出なければ、configureを実行した際にオプションで付けた--prefix=/usr/local/php82のパスにphpの実行ファイルが生成されているハズです。
まずは、実行できるかと目的のバージョンになっているかを確かめます。
/usr/local/php82/bin/php -v
# => バージョンが表示されるので、パッチ適用バージョンになっているか確かめること。
# PHP8.2の場合、PHP 8.2.35以上問題が無ければ、which phpを実行して出てきたパスと、今回作成したパスを入れ替えます。
# which phpの結果が/usr/bin/phpだと仮定して、以下のようにします。
mv /usr/bin/php{,.bk}
ln -s /usr/local/php82/bin/php /usr/bin/phpオプション設定等によっては、/usr/local/php82/lib/php/extensions/no-debug-non-zts-XXXXX/配下に.soファイルが作成されているので、php.iniで適切に読み込みます。
httpdの設定ファイル等も修正の上、サービスを再起動してください。
systemctl restart httpd.service
(ここはnginx等環境に合わせて変える必要があります。)これで動けば今回の延命は成功です。
ただ、延命は延命です。なるべく早めにOSのバージョンやPHPのバージョンを上げる方向に動きましょう。
おわりに
ここまでの手順で駄目でも他の方法はあるかもしれません。
ただ、これ以上頑張れない場合、以下の負債を返してなんとか公開までこぎつけるか、すっぱり諦めてサービス終了とかになると思います。
- OSを最新にする
- PHPもバージョンを最低限パッチ配信版(PHP7.4)まで上げる
- 自社サービスを最新版PHPに対応させる
(使ってるライブラリが古くて更新もしておらず、代替ライブラリも無さそうな場合更なる地獄が待ち受けています。vendorの中身を直接修正してサーバーにアップロードする力技でも行けなくはないですが、ライブラリの規模や依存度、修正範囲と内容によっては…。)
PHP以外にも言えることですが、OSも言語もバージョンもこまめに上げられるなら上げないといけない時代になってしまったのかもしれません。しかし、PHPだけならともかく、OSバージョンの場合サーバーも新しくする必要があると思うので、そこそこの費用が必須になるのがなんとも悩ましいです。


