PHP 8.0 on CentOS 8 and CentOS 7 now runs on two platforms that no longer get updates. CentOS Linux 8 stopped on 31 December 2021, CentOS 7 on 30 June 2024, and PHP 8.0 itself left upstream support on 26 November 2023. For PHP2Shell (CVE-2026-109618 and CVE-2026-109619) the two releases split. Remi’s EL8 build of PHP 8.0 carries the fix and still installs on CentOS 8, but the newest EL7 build dates from June 2024 and is vulnerable.
You’ll install PHP 8.0 from Remi with the repository fixes that the retired mirrors now force, check the build, and lock down CentOS 7, where no free patch exists. For a new server, skip CentOS and follow the PHP guide for Rocky Linux and AlmaLinux 9 and 8 instead. Every install command below was re-run in October 2026 on a CentOS Linux 8 test system using the 8.5.2111 vault and on CentOS 7.9, where Apache was started directly rather than through systemd and the php80 extension and pool steps were not run.
Install PHP 8.0 on CentOS 8 | CentOS 7
We’ll use the Remi repository to install PHP 8 on a CentOS 8 or CentOS 7 Linux system. There are two choices for the installation.
- Install PHP 8.0 as main PHP version
- Install PHP 8.0 alongside other PHP versions
Point CentOS at the vault repositories
Both releases still ship repo files that point at mirrorlist.centos.org, and that host no longer resolves, so the very first package command fails. On CentOS 8, dnf stops with Failed to download metadata for repo 'appstream'; on CentOS 7, yum prints Could not resolve host: mirrorlist.centos.org and then Cannot find a valid baseurl for repo: base/7/x86_64. Skip this step only if your server already uses vault.centos.org or a local mirror. On CentOS 8, switch the repos to the final 8.5.2111 tree in the vault:
sudo sed -i -e 's|^mirrorlist=|#mirrorlist=|' -e 's|^#baseurl=http://mirror.centos.org/$contentdir/$releasever|baseurl=https://vault.centos.org/8.5.2111|' /etc/yum.repos.d/CentOS-*.repo
sudo dnf -y makecache
CentOS 7 uses different repo file names and a different path layout, so it needs its own pattern pointing at the 7.9.2009 tree.
sudo sed -i -e 's|^mirrorlist=|#mirrorlist=|' -e 's|^#baseurl=http://mirror.centos.org/centos/$releasever|baseurl=https://vault.centos.org/7.9.2009|' /etc/yum.repos.d/CentOS-*.repo
sudo yum -y makecache fast
The vault is frozen. It lets you install packages, but nothing in it gets security fixes, including OpenSSL, the kernel and Apache, so a patched PHP on CentOS still leaves you on an unpatched OS. Treat everything below as a way to keep an old server running until you move it, not as a setup to build on.
Install PHP 8.0 as the default version
If you prefer to install and have PHP 8.0 as the default version then use the commands below. This means replacing base packages from the distribution with ones provided by PHP 8.0.
CentOS 8: the current remi-release-8.rpm refuses to install here because it requires redhat-release >= 8.10, and CentOS Linux stopped at 8.5. The older remi-release-8.5-3 package still installs and enables the same repositories, so the commands below use it. Remi only supports EL 8.10, which means CentOS 8 is outside its support even though the packages ran fine in our test:
sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo dnf -y install https://rpms.remirepo.net/enterprise/8/remi/x86_64/remi-release-8.5-3.el8.remi.noarch.rpm
sudo dnf -y install yum-utils
sudo dnf module reset php -y
sudo dnf module install php:remi-8.0 -y
sudo dnf install php -y
sudo dnf -y install php-{cli,fpm,mysqlnd,zip,devel,gd,mbstring,curl,xml,pear,bcmath,json}
CentOS 7: the epel-release-latest-7 link now returns 404 because EPEL 7 moved to the Fedora archive, so install the last epel-release package from there and point its repo file at the archive. Remi’s remi-release-7 needs that package (epel-release = 7), which is why the EPEL step can’t be skipped:
sudo yum -y install https://dl.fedoraproject.org/pub/archive/epel/7/x86_64/Packages/e/epel-release-7-14.noarch.rpm
sudo sed -i -e 's|^metalink=|#metalink=|' -e 's|^#baseurl=http://download.example/pub/epel/7|baseurl=https://dl.fedoraproject.org/pub/archive/epel/7|' /etc/yum.repos.d/epel.repo
sudo yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum -y install yum-utils
sudo yum-config-manager --disable 'remi-php*'
sudo yum-config-manager --enable remi-php80
sudo yum -y install php php-{cli,fpm,mysqlnd,zip,devel,gd,mbstring,curl,xml,pear,bcmath,json}
To install any additional PHP package, use this syntax. On CentOS 8, yum is an alias for dnf, so the same line works on both releases:
sudo yum install php-xxx
Check PHP version:
php --version
On our CentOS 8 box the build date reads 21 October 2026, which is the patched Remi build:
PHP 8.0.30 (cli) (built: Oct 21 2026 10:45:11) ( NTS gcc x86_64 )
Copyright (c) The PHP Group
Zend Engine v4.0.30, Copyright (c) Zend Technologies
with Zend OPcache v8.0.30, Copyright (c), by Zend Technologies
CentOS 7 prints the same 8.0.30 with built: Jun 4 2024, the last EL7 build Remi made. Both say 8.0.30, so the version string alone tells you nothing about PHP2Shell, and the package check further down is the one to trust.
Install PHP 8.0 alongside other PHP versions
Remi’s software collection packages install PHP 8.0 under /opt/remi/php80 with its own php80 command and php80-php-fpm service, and they never replace the system php. Pick this route when the server already runs another PHP version for other sites.
Install PHP 8.0 on CentOS 8
The repository setup is the same as above, including the older remi-release package and the vault repos.
sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo dnf -y install https://rpms.remirepo.net/enterprise/8/remi/x86_64/remi-release-8.5-3.el8.remi.noarch.rpm
sudo dnf -y install yum-utils
sudo dnf module reset php -y
sudo dnf -y install php80
The collection packages come from Remi’s remi-safe repository, which remi-release enables on its own, and they live beside whatever the module stream installs.
Install PHP 8.0 on CentOS 7
Install the archived EPEL package first, exactly as in the default-version steps, then enable remi-safe instead of remi-php80.
sudo yum -y install https://dl.fedoraproject.org/pub/archive/epel/7/x86_64/Packages/e/epel-release-7-14.noarch.rpm
sudo sed -i -e 's|^metalink=|#metalink=|' -e 's|^#baseurl=http://download.example/pub/epel/7|baseurl=https://dl.fedoraproject.org/pub/archive/epel/7|' /etc/yum.repos.d/epel.repo
sudo yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum -y install yum-utils
sudo yum-config-manager --disable 'remi-php*'
sudo yum-config-manager --enable remi-safe
sudo yum -y install php80
Use the command below to install additional PHP extensions:
sudo yum install php80-php-xxx
Example:
sudo yum install php80-php-{cli,fpm,mysqlnd,zip,devel,gd,mbstring,curl,xml,pear,bcmath,json}
Check the collection’s PHP version and list its loaded extensions:
php80 --version
php80 --modules
The first lines on CentOS 8 show the October 2026 build; on CentOS 7 the same command shows built: Jun 4 2024:
PHP 8.0.30 (cli) (built: Oct 21 2026 10:40:13) ( NTS gcc x86_64 )
Copyright (c) The PHP Group
Zend Engine v4.0.30, Copyright (c) Zend Technologies
As with the default install, the build date is the only visible difference, so you still need the package check in the next section to know where you stand.
Check PHP 8.0 for PHP2Shell (CVE-2026-109618, CVE-2026-109619)
PHP2Shell is two critical remote code execution bugs in PHP itself, which php.net rated CVSS v4.0 9.2 in its 20 October pre-announcement and fixed on 21 October 2026 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.0 gets no upstream release, so the fix only reaches it as a backport that keeps the 8.0.30 version number. Remi’s EL8 build 8.0.30-21 carries that backport, while EL7 stops at 8.0.30-6 from June 2024. The PHP security advisory also told rpms.remirepo.net users on release day to switch to distribution packages or build from source, because Remi had no update yet. Remi’s fixed EL8 builds, dated 21 October in their changelog, are in the repository now, but CentOS has no distribution packages left to switch to.
The table shows where each install route from this guide stands on 22 October 2026, taken from the Remi repository indexes and our own installs.
| Release and route | Newest package | PHP2Shell |
|---|---|---|
CentOS 8, php:remi-8.0 module | php-common 8.0.30-21 | Fixed |
| CentOS 8, php80 collection | php80-php-common 8.0.30-21 | Fixed |
| CentOS 7, remi-php80 | php-common 8.0.30-6 (June 2024) | Not fixed |
| CentOS 7, php80 collection | php80-php-common 8.0.30-6 (June 2024) | Not fixed |
The package changelog is the check you can trust, because Remi writes both CVE IDs into the 8.0.30-21 entry and the version string never moves. If you run the collection, query php80-php-common instead. Run both lines.
rpm -q php-common
rpm -q --changelog php-common | grep CVE-2026-10961
A patched CentOS 8 server prints the -21 release and the CVE line. A fresh install from this guide already looks like this, so you can stop here if that is your case.
php-common-8.0.30-21.module_php.8.0.el8.remi.x86_64
CVE-2026-109618, CVE-2026-109619
On CentOS 7 the first line reads php-common-8.0.30-6.el7.remi.x86_64 and the grep prints nothing. That means the build is vulnerable, and no yum update will change it, because there is nothing newer in any repository the server can reach. Your options are a migration or the interim settings further down.
Upgrade an existing CentOS 8 server
A CentOS 8 server that installed Remi’s PHP 8.0 earlier only needs the vault repos from the first step and an upgrade. Restart PHP-FPM afterwards and confirm the running service started after the upgrade, because the version string stays 8.0.30 either way:
sudo dnf -y upgrade 'php*'
sudo systemctl restart php-fpm
systemctl show -p ActiveEnterTimestamp php-fpm
We moved a test box from 8.0.30-19 to 8.0.30-21 at 20:09 UTC, and the timestamp landed just after it. A time earlier than your upgrade means the old code is still running.
ActiveEnterTimestamp=Thu 2026-10-22 20:09:22 UTC
The package restarted php-fpm on its own during that upgrade in our test, but restart anyway and compare the timestamp with the upgrade time from sudo dnf history list php-common. If you run the collection, restart php80-php-fpm as well, along with any long-running PHP CLI workers such as queue consumers under supervisor.
Reduce exposure on CentOS 7
We found no free patched PHP 8.0 for EL7. Remi’s EL7 trees end at 8.0.30-6, and both CentOS and EPEL 7 are frozen archives. The real fix is moving the site to a supported release, either the EL9/8 guide linked at the top or the PHP setup for RHEL, Rocky Linux and AlmaLinux 10. PHP also published minimal source backports for 8.0 for anyone who builds PHP from source. Until then, the settings from PHP’s advisory reduce exposure without closing it. With the default-version install, Apache runs PHP through mod_php, the case PHP rates highest risk, so set the limits where applications cannot override them:
sudo vim /etc/httpd/conf.d/php2shell.conf
Add these lines. If the site needs file uploads, use 32M for post_max_size and keep upload_max_filesize below it (we checked 32M and 16M through the web server):
<IfModule mod_php.c>
php_admin_value memory_limit -1
php_admin_flag session.upload_progress.enabled off
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 2M
</IfModule>
For PHP-FPM, append the same settings to the end of the pool file, /etc/php-fpm.d/www.conf for the default install or /etc/opt/remi/php80/php-fpm.d/www.conf for the collection:
sudo vim /etc/php-fpm.d/www.conf
The pool file takes the same four settings in bracket syntax.
php_admin_value[memory_limit] = -1
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 2M
PHP’s advisory says to restart every worker after changing these settings, and our PHP2Shell check and patch guide covers the same checks on current distributions. Restart only the units you actually run:
sudo systemctl restart httpd
sudo systemctl restart php-fpm
The CLI reads php.ini and ignores these settings, so php -i still shows the old values even when the web server has the new ones. That is why the check has to go through the web server, using a throwaway page.
sudo vim /var/www/html/php2shell-check.php
Paste this. It prints the version, the handler and the four values.
<?php
echo PHP_VERSION, ' ', PHP_SAPI, PHP_EOL;
foreach (['memory_limit', 'session.upload_progress.enabled', 'post_max_size', 'upload_max_filesize'] as $k) {
echo $k, '=', var_export(ini_get($k), true), PHP_EOL;
}
Request the page from the server itself.
curl -s http://localhost/php2shell-check.php
On our CentOS 7 box Apache answered through mod_php with every value applied. Through PHP-FPM on CentOS 8 the second word reads fpm-fcgi instead, with the same four lines:
8.0.30 apache2handler
memory_limit='-1'
session.upload_progress.enabled='0'
post_max_size='8M'
upload_max_filesize='2M'
If memory_limit still shows 128M, another php_admin_value line in a vhost or pool sets it again, so find and remove it. In our test an application’s ini_set('memory_limit', '128M') returned false with these settings in place. An unlimited memory limit lets one request eat all the RAM, so watch memory and restore the limit after you move the site. Delete the check page when you’re done:
sudo rm -f /var/www/html/php2shell-check.php
These settings block the confirmed attack paths only. The PHP2Shell mitigation guide covers request limits at the web server and the proxy, which help further, but none of it replaces a patched PHP on a supported OS.
Very Good article
Thanks and welcome