PHP2Shell CVE-2026-109618 на CentOS 7, Alma, Rocky: как исправить
АйТи Фреш
Серверы и инфраструктура

PHP2Shell CVE-2026-109618 и 109619 на CentOS 7, RHEL, AlmaLinux и Rocky: Remi, EOL и план миграции

Автор: , директор ООО «АйТи-Фреш» · · ~20 мин чтения
Старый сервер с янтарным предупреждающим индикатором и новый сервер с замком и щитом в тёмной серверной комнате
CentOS 7 в EOL не получает исправлений: временные меры держат оборону, пока идёт миграция.

На 21 октября 2026 апстрим PHP исправлен в 8.5.12, 8.4.27, 8.3.36 и 8.2.35, но номера исправленных пакетов для RHEL, AlmaLinux и Rocky в источниках не названы, а Remi обновлений не выпустит. CentOS 7 в EOL, и мы считаем, что исправления для него не будет. Проверяйте errata и changelog пакета, ставьте временные меры (в том числе блок multipart) и планируйте переезд на Alma или Rocky.

Что известно на 21 октября 2026 для CentOS 7, RHEL, AlmaLinux и Rocky

21 октября 2026 PHP выпустил исправления для двух критических уязвимостей ядра: CVE-2026-109618 и CVE-2026-109619 (обе CVSS v4.0 = 9.2, без аутентификации, из сети, конфигурация по умолчанию уязвима). Апстрим закрыт в версиях 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Для 8.1 и старше официального исправления нет. Общий разбор и план первого часа — в статье PHP2Shell: что делать за первый час, здесь только RHEL-семейство.

Главная честность этой статьи: в источниках, которые мы сверили на 21 октября, номера исправленных пакетов для RHEL, AlmaLinux и Rocky не названы. Мы не будем придумывать «нужна php-8.2.35-1.el9». Вместо этого дадим способ, которым проверяем сами: реестр errata, dnf updateinfo, changelog пакета и сравнение с апстримом. Статус по конкретному дистрибутиву нужно перепроверять сегодня и в ближайшие дни: вендоры собирают пакеты в разном темпе.

Второй факт: репозиторий Remi (rpms.remirepo.net) сообщил, что 21 октября обновлений не будет, и рекомендует брать пакеты дистрибутива или собирать из исходников. Если у вас на сервере стоит Remi или SCL-пакеты вроде php84-php-fpm, не ждите автоматического dnf update: он ничего не принесёт. Третий факт: CentOS 7 снят с поддержки, и для EOL-систем официальных обновлений не выходит. Это наш вывод из статуса системы, в источниках по PHP2Shell он напрямую не назван.

Для 40 рабочих мест и пары внутренних PHP-приложений это обычная ситуация: корпоративный портал, GLPI или самописная форма заявок живут на старой машине, про которую «все забыли». Начинаем с инвентаризации: что за ОС, откуда PHP, кто его перезапускает. Подход к учёту такой техники описан в статье инвентаризация IT-активов.

Не ищите в интернете «готовый rpm с исправлением» и не ставьте пакеты из случайных репозиториев. Для PHP на сервере с данными это худший вариант: вы не знаете ни сборку, ни набор патчей.

Как понять, под ударом ли вы: ОС, источник PHP и версия

Сначала отвечаем на три вопроса: какая ОС, откуда PHP и какие процессы его реально исполняют. Команды безобидные, только чтение.

cat /etc/redhat-release
rpm -q php-fpm php-cli
rpm -qa | grep -E '^(php|remi|scl)' | sort
php -v
systemctl list-units --type=service | grep -i php

Что смотрим в выводе. Если пакет называется php-fpm и версия вроде 8.0 или 7.4 — это пакет дистрибутива (RHEL 8 и 9 поставляют PHP модулями dnf). Если есть пакеты remi-release и версия 8.3 или 8.4 — PHP из Remi. Если пакеты называются php84-php-fpm, а php -v показывает другую версию — это SCL-сборка в /opt/remi/php84, и системный PHP живёт параллельно. Именно так на CentOS 7 часто и бывает: на сайте работает один PHP, в cron другой, а в панели управления третий.

Номер версии сам по себе не говорит, что вы уязвимы или защищены. Здесь важна особенность RHEL-семейства: вендор переносит исправления в старую версию (бэкпорт), поэтому пакет может называться 8.2.x и быть уже исправленным, а может называться 8.2.35 и ничего не значить для вашей сборки. Поэтому версию мы сравниваем не с апстримом «в лоб», а с errata и changelog, как описано ниже.

Если PHP стоит в версии 8.1 и старше от Remi, а Remi 21 октября обновлений не выпускает, считайте систему уязвимой, пока не докажете обратное. То же для CentOS 7: даже при самой свежей собранной версии PHP сама ОС больше не получает исправлений ни для ядра, ни для openssl, и мы относимся к такой машине как к временной.

Не забываем про PHP, о котором никто не думает: встроенный в панели, веб-интерфейсы мониторинга и телефонии, старые установки с веб-интерфейсом администрирования. NCSC прямо рекомендует инвентаризацию всех PHP, включая встроенные в продукты. Для каждого такого узла по тем же командам определяем источник PHP.

RHEL, AlmaLinux, Rocky 8 и 9: пакеты дистрибутива и модули dnf

На 8 и 9 версиях PHP ставится потоком модуля dnf. Посмотрим, какие потоки доступны и какой включён.

dnf module list php
dnf updateinfo list --security | grep php
rpm -q --changelog php-fpm | head

Команда dnf updateinfo list --security | grep php показывает, есть ли среди доступных обновлений безопасности пакеты PHP. Пусто может значить две вещи: либо исправление ещё не опубликовано в вашем зеркале, либо метаданные устарели. Поэтому сначала dnf clean expire-cache, затем повторная проверка. Для конкретного CVE полезна выборка по идентификатору: dnf updateinfo info --cve CVE-2026-109618. Если dnf отвечает, что такой записи нет, это не доказательство отсутствия исправления, но на 21 октября это означает «подтверждения нет».

Если исправленный пакет в вашем потоке появился, обновляем только пакеты PHP и перезапускаем сервис. Если для вашего потока (например, php:7.4 или php:8.0 на RHEL 8) исправления нет, у вас два пути: перейти на поток, который вендор продолжает поддерживать, либо принять риск с временными мерами. Переключение модуля делается так, и перед ним обязательно снимок ВМ и копия конфигов.

dnf module reset -y php && dnf module enable -y php:8.2 && dnf distro-sync -y

Команда из проверенных нами материалов серии. Перед запуском проверяем, что расширения и приложение работают на новой ветке: между 7.4, 8.0 и 8.2 меняются поведение функций и список расширений. На тестовой копии прогоняем сайт, cron-скрипты и загрузку файлов. Список поддерживаемых потоков PHP в вашей версии системы смотрите по dnf module list php, он зависит от минорной версии RHEL.

Источники исправлений. У AlmaLinux есть реестр errata (errata.almalinux.org), у Red Hat — страница CVE в Customer Portal с таблицей «затронутые пакеты и статусы». Rocky Linux публикует свои обновления отдельно. Мы смотрим по очереди все, что относится к нашему дистрибутиву, и записываем в карточку клиента, какая именно запись подтвердила исправление, и какой пакет (NEVRA) в ней указан. Эти номера в этой статье мы намеренно не приводим: на момент проверки они в источниках не названы.

Если вы на RHEL с подпиской, статус по CVE сначала смотрите на странице самого вендора. Для клонов (Alma, Rocky) пакет появляется позже, чем у Red Hat, и это нормально, но следите за ним ежедневно.
Схема проверки исправления пакета: пакет, реестр errata, сравнение версий, подтверждение
Проверка бэкпорта: пакет, реестр errata, сравнение и подтверждение.

Remi, SCL-пакеты (php84-php-fpm) и бэкпорты: почему dnf update молчит и как читать changelog

Remi в этом случае ничего не выпустил, и по заявлению репозитория 21 октября выпускать не будет. Рекомендация — пакеты дистрибутива либо сборка из исходников. Для типичной схемы «CentOS 7 или Alma 8 плюс Remi SCL плюс php84-php-fpm» это означает: на дату статьи исправления у вас нет, и ждать его из этого канала вы не можете.

Что делаем у клиентов. Первое — определяем, что именно запущено: systemctl status php84-php-fpm и ls /opt/remi. На сервере может быть несколько SCL-версий, и «забытая» php74-php-fpm тоже принимает запросы от виртуального хоста. Второе — выясняем, можно ли перевести сайт на пакет дистрибутива (поток модуля dnf на RHEL 8 и 9). Третье — если нельзя, ставим временные меры из пятого раздела и готовим миграцию.

Проверка, что вы изменили не то. Обновление системного php-fpm не лечит SCL: это отдельные пакеты и отдельные сервисы. Верно и обратное. После обновления нужно перезапустить именно тот сервис, который обслуживает сайт: systemctl restart php-fpm для пакета ОС или systemctl restart php84-php-fpm для SCL. Если на сервере mod_php, то перезапускаем httpd целиком: reload и graceful не подходят.

Проверка changelog у SCL-пакета: rpm -q --changelog php84-php-fpm | head. Если в верхних строках нет записи о CVE-2026-109618 или о версии 8.4.27, значит исправления в пакете нет. Отсутствие номера CVE в changelog не всегда означает отсутствие правки, поэтому смотрим ещё и php84 -v (версию), но, повторим, для бэкпортов номер версии не показатель. Смотрим на дату сборки пакета: rpm -qi php84-php-fpm | grep -i 'build date'. Если она раньше 21 октября 2026, исправления в пакете быть не может.

Сборка из исходников как крайняя мера: она возможна для 8.2, 8.3, 8.4 и 8.5 из релизов 21 октября, а Patchstack отмечает, что минимальные бэкпорты для 7.4, 8.0 и 8.1 существуют только при сборке из исходников. Мы советуем делать это только на сервере, у которого есть владелец, мониторинг и окно обслуживания: самосборка означает, что дальше все обновления безопасности вы собираете сами.

Бэкпорт — это когда вендор вносит исправление в старую версию пакета и не повышает основную версию PHP. Для RHEL-семейства это норма: пакет php-8.0.x может содержать исправление, полученное из 8.2.35. По версии это не видно, поэтому нужна проверка по документам.

Порядок проверки у нас такой. Шаг один — реестр: errata AlmaLinux, страница CVE Red Hat или запись Rocky. Ищем два идентификатора, CVE-2026-109618 и CVE-2026-109619, и фиксируем пакет, в котором исправление заявлено. Шаг два — сравниваем с установленным: rpm -q php-fpm, сверяем NEVRA с записью в реестре. Если установленный пакет новее или равен указанному — хорошо. Шаг три — changelog: rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961[89]'. Строка найдена — исправление заявлено мейнтейнером. Не найдена — смотрим по датам и по реестру.

Что делать, когда changelog без CVE. Случается, что запись в changelog общая: «rebase to 8.2.35» или «security fix» без номеров. Тогда ориентируемся на реестр errata и на дату сборки. Если в реестре записи нет, а changelog общий, фиксируем статус «не подтверждено» и ставим временные меры. Лучше честно записать «не подтверждено», чем тихо поставить «закрыто».

Ещё одна ловушка: исправленный пакет установлен, а процесс работает на старом. После dnf update файлы на диске новые, а воркеры PHP-FPM или httpd остаются в памяти со старой библиотекой. Проверка из наших материалов: sudo grep -lE ' /(usr|lib|opt).*\(deleted\)$' /proc/[0-9]*/maps. Пустой вывод означает, что старых библиотек в памяти нет. Если процессы перечислены, перезапускаем соответствующие сервисы. Утилита needrestart в RHEL-семействе — не штатная, поэтому на этих системах мы пользуемся командой выше, а утилиту dnf needs-restarting проверьте у себя: она входит в пакет dnf-utils.

Одно и то же приложение может исполнять несколько PHP: web — php84-php-fpm, cron — системный php, CLI-скрипты — другой. Проверяйте и меняйте все, а не только тот, что виден в phpinfo().

Временные меры на EOL и без исправления: конфиг, multipart, WAF, изоляция

Предупреждение: это не замена патчу. Эксперт PHP Gina Peter Banyard прямо говорит, что надёжных обходных мер нет, единственное исправление — патч. Мы применяем меры, чтобы снизить вероятность эксплуатации на время миграции, и фиксируем это в карточке клиента как риск с датой пересмотра.

Конфигурация PHP. Отключаем session.upload_progress.enabled=0 на уровне php.ini или пула FPM (не через ini_set() и не через .user.ini) и перезапускаем все воркеры. Для PHP 8.5 дополнительно fatal_error_backtraces=0. В пуле FPM это выглядит так.

php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1

Про memory_limit = -1: Sansec предлагает такой вариант, потому что триггером служит исчерпание лимита памяти. Риск понятен: один запрос может съесть всю память сервера, поэтому ставим лимиты в cgroup или systemd (MemoryMax) и смотрим за RAM. Patchstack дополнительно советует ограничить post_max_size (8M без загрузок, 32M с загрузками) и upload_max_filesize и не использовать RLIMIT_AS и RLIMIT_DATA. После правки пула перезагружаем конфигурацию PHP-FPM.

Блок multipart/form-data на веб-сервере. Все известные триггеры — запросы multipart/form-data, потому что PHP разбирает тело до кода приложения. Если на сайте нет загрузок, закрываем их. Для nginx: if ($http_content_type ~* "multipart/form-data") { return 403; }. Для Apache: RewriteCond %{HTTP:Content-Type} multipart/form-data [NC] и RewriteRule ^ - [F]. Это ломает загрузку файлов и часть форм, например корзину и оформление заказа, поэтому после включения обязательно тестируем заказ и отправку формы.

Если загрузки нужны, ограничиваем размер запроса, число полей и multipart на прокси и веб-сервере. Если сайт не критичен, пропускаем только GET и HEAD (на nginx отдаём 503 на остальные методы) или останавливаем PHP-FPM и отдаём статическую страницу. Режимы обслуживания CMS не помогают: PHP разбирает запрос раньше.

WAF и Cloudflare. Cloudflare выкатил аварийные правила во всех тарифах, включая бесплатный, но называет их временной мерой. Работают они, только если origin принимает трафик исключительно от Cloudflare: если сервер доступен по прямому адресу, защиту обходят. Закрываем входящие на 80 и 443 для всех, кроме адресов Cloudflare. Sansec Shield RCE и утечку не закрывает.

Изоляция. Для машины, которую нельзя обновить сразу, убираем её из интернета: доступ только из внутренней сети или по VPN, наружу — через прокси с блокировкой multipart. NCSC советует: если и меры не помогают надолго, рассмотрите отключение системы. Это нормальное решение для забытого портала.

Не ставьте плагины-заплатки и сниппеты с форумов, о чём предупреждает Patchstack. Они не меняют ядро PHP, а сам сниппет может стать новой дырой.

План миграции CentOS 7 на AlmaLinux или Rocky: ELevate и сборка из исходников

На CentOS 7 исправления не ожидается, поэтому постоянное решение — уходить с системы. Есть два пути: переустановка на новую ОС с переносом данных (чище и надёжнее) и обновление «на месте» через ELevate. Мы предпочитаем переезд на новую виртуальную машину, потому что старая остаётся как откат. Если переезд невозможен, используем ELevate на копии сервера.

Что подтверждает документация AlmaLinux (wiki.almalinux.org/elevate): путь CentOS 7 на AlmaLinux 8 выполняется в несколько шагов. Хранилища CentOS 7 отключены, поэтому первым шагом подключается зеркало el7.repo.almalinux.org, затем полное обновление и перезагрузка, установка elevate-release и пакетов leapp, предварительная проверка и сам апгрейд. На странице сказано, что путь с CentOS 7 нужно разбивать на этапы, а дальше с 8 на 9 переходят отдельным обновлением. Последовательность этапов в схеме мы не смогли прочитать целиком, поэтому проверьте актуальный порядок на странице проекта перед стартом.

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://el7.repo.almalinux.org/centos/CentOS-Base.repo
sudo yum update -y
sudo reboot
sudo yum install -y http://repo.almalinux.org/elevate/elevate-release-latest-el$(rpm --eval %rhel).noarch.rpm
sudo yum install -y leapp-upgrade leapp-data-almalinux
sudo leapp preupgrade

После preupgrade читаем отчёт /var/log/leapp/leapp-report.txt. По документации, на стандартной установке проверка не пройдёт без правок: часть пунктов требует ответов в файле /var/log/leapp/answerfile, а в базовом руководстве упомянуты типовые правки (выгрузка модуля pata_acpi, ответ про pam_pkcs11 и PermitRootLogin yes). Последнее ослабляет SSH: если вы это делаете, верните настройку после обновления. Когда отчёт чист, запускаем leapp upgrade и перезагрузку, система загрузится через пункт GRUB ELevate-Upgrade-Initramfs, после чего проверяем /etc/redhat-release и логи leapp.

Грабли ELevate. Нужны снимок ВМ и бэкап. Пакеты из сторонних репозиториев, которых нет для новой ОС, останутся в системе как «осиротевшие» (документация отдельно предупреждает про это). SCL-пакеты Remi php84 на новой системе вам не помогут: после перехода PHP надо ставить заново из пакетов дистрибутива, перенести конфиги пулов и проверить расширения. Панели управления и приложения со специфичными зависимостями проверяйте на тестовой копии.

Сборка PHP из исходников, как крайняя мера. Берём релиз 8.2.35, 8.3.36, 8.4.27 или 8.5.12 с официальной страницы PHP, собираем в отдельный префикс (например, /opt/php-8.4.27), не перезаписывая системные файлы, прописываем свой unit для php-fpm и пулы, повторяем набор расширений из php -m старой версии. Минус очевиден: обновления вы будете делать вручную каждый раз. Для 7.4, 8.0 и 8.1 бэкпорты по данным Patchstack существуют только при сборке из исходников, и мы не рекомендуем это для рабочего контура без отдельного решения владельца.

Мини-кейс. Условная производственная компания «Литейный Двор», 40 рабочих мест. На одном сервере с CentOS 7 живут внутренний портал заявок и интерфейс учёта оборудования на php84-php-fpm из Remi SCL. Исправления для этой связки нет и не будет. Мы делаем так: закрываем доступ снаружи (только VPN), ставим меры в пул FPM и блок multipart там, где загрузки не нужны, а параллельно поднимаем новую виртуальную машину на AlmaLinux с PHP из пакетов дистрибутива, переносим приложение и проверяем загрузку файлов. Старую машину оставляем выключенной как откат. Вы можете заказать такую работу у нас: обслуживание и миграция серверов.

Сервер с CentOS 7 остаётся без обновлений ОС, даже если PHP на нём вы починили. План миграции с датой должен появиться в день, когда вы поставили временные меры.
Схема миграции: старый сервер, шестерёнки переноса и новый сервер со щитом и чек-листом
Миграция с CentOS 7: перенос на новую систему с откатом на старую машину.

Проверка после работ, рестарты и типичные ошибки

Порядок проверки у нас стандартный. Ставим обновление или правку конфигурации, перезапускаем сервис, проверяем, что работает новый процесс, и тестируем бизнес-сценарии. Рестарты: PHP-FPM — systemctl restart php-fpm (для SCL — systemctl restart php84-php-fpm), reload тоже подходит. mod_php — systemctl restart httpd, reload и graceful недостаточно. LiteSpeed — обновить lsphpXY и выполнить pkill lsphp. Очереди Laravel — php artisan queue:restart. Для Octane перезапускаем процесс целиком, octane:reload недостаточно. FrankenPHP не лечится обновлением пакета: нужен новый релиз или образ.

sudo systemctl restart php-fpm
php -v
sudo grep -lE ' /(usr|lib|opt).*\(deleted\)$' /proc/[0-9]*/maps

После рестарта проверяем три вещи: версия и дата сборки пакета, пустой вывод проверки «(deleted)», а также нормальная работа сайта (вход, загрузка файла, отправка формы). Если вы включили блок multipart, отдельно проверяем оформление заказа. Результат записываем: дата, пакет, запись в errata или причина, по которой мы считаем «не подтверждено».

Признаки эксплуатации по Patchstack — не доказательство ни в ту, ни в другую сторону: необычные multipart-запросы с последующей ошибкой memory_limit или повторяющимися HTTP 500, аномально большие или битые куки PHPSESSID, необъяснимые перезапуски воркеров PHP. Как искать эти следы в логах nginx и Apache, разобрано в статье признаки взлома в логах nginx и Apache. При признаках мы обновляем систему, считаем сервер возможно скомпрометированным и передаём владельцу список ключей и паролей на ротацию; сами пароли живых учётных записей мы не меняем.

Типичные ошибки. Первая: обновили системный php, а сайт работает на SCL. Вторая: пакет обновлён, сервис не перезапущен. Третья: поставили блок multipart и сломали заказ. Четвёртая: оставили PHP за Cloudflare, но origin доступен напрямую. Пятая: считают, что обновление плагинов CMS защищает, хотя ошибка в интерпретаторе и затронуты WordPress, Drupal, Joomla, Magento и другие. Если у вас на машине стоят панели или контейнеры, посмотрите наши материалы про панели с несколькими версиями PHP и PHP в Docker-образах; про Debian и Ubuntu — обновление PHP из Sury и PPA.

Частые вопросы

Выйдет ли исправление PHP2Shell для CentOS 7?

Скорее всего нет. CentOS 7 снят с поддержки, а EOL-системы официальных обновлений не получают. В источниках по PHP2Shell это прямо не названо, это наш вывод. Планируйте переезд на AlmaLinux или Rocky, а до него закройте доступ снаружи и поставьте временные меры.

Почему dnf update не принёс исправление из Remi?

Remi сообщил, что 21 октября обновлений для PHP не будет, и рекомендует пакеты дистрибутива или сборку из исходников. SCL-пакеты вроде php84-php-fpm тоже в этой схеме. Проверьте `rpm -q --changelog php84-php-fpm` и дату сборки пакета, а затем решайте: переход на пакеты ОС или сборка.

Как проверить, что в пакете RHEL, Alma или Rocky есть исправление?

Сравните установленный пакет с записью в errata вашего дистрибутива по CVE-2026-109618 и CVE-2026-109619, затем `rpm -q --changelog php-fpm`. Версия PHP сама ничего не доказывает из-за бэкпортов. Номера исправленных пакетов на 21 октября в источниках не названы, поэтому записи в реестре нужно смотреть самим.

Хватит ли отключить session.upload_progress?

Нет. По словам Gina Peter Banyard из PHP, одного отключения мало и надёжных обходных мер нет, единственное исправление — патч. Отключение session.upload_progress.enabled вместе с блоком multipart, лимитами и закрытием доступа лишь снижает риск. Обязательно перезапустите все воркеры PHP.

Можно ли обновить CentOS 7 на месте через ELevate?

Да, AlmaLinux документирует ELevate для CentOS 7 на AlmaLinux 8 через leapp-upgrade. Нужны снимок ВМ, полное обновление, разбор отчёта preupgrade и учёт сторонних пакетов. Дальнейшие шаги проверьте на wiki.almalinux.org/elevate. Мы чаще переезжаем на новую ВМ, чтобы сохранить откат.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи