К основному содержимому

Аудит версий PHP и nginx на парке серверов: один скрипт

Безопасность · 27.10.2026 · 2 мин чтения

Зачем

Когда серверов больше трёх, вопрос «мы обновились?» перестаёт иметь однозначный ответ. Один сервер пропустили, на другом PHP-FPM не перезапустили, на третьем PHP в контейнере. Ниже — проверка, которая отвечает на этот вопрос списком.

Главная ловушка: номер версии врёт

В Ubuntu, Debian, AlmaLinux исправления переносят в старую версию, не меняя номер. На исправленном сервере php -v покажет 8.3.6 — ту же цифру, что и на уязвимом. Сравнивать номера версий бесполезно: нужен журнал изменений пакета.

Скрипт проверки

Положите список серверов в файл hosts.txt, по одному на строку, и запустите:

#!/usr/bin/env bash
set -uo pipefail

while read -r host; do
  [ -z "$host" ] && continue
  printf '%-28s ' "$host"
  ssh -o ConnectTimeout=5 -o BatchMode=yes "$host" '
    php_v=$(php -v 2>/dev/null | head -1 | awk "{print \$2}")
    ngx_v=$(nginx -v 2>&1 | grep -oE "[0-9]+\.[0-9]+\.[0-9]+")
    fixed=нет
    if zgrep -lq "CVE-2026-109618" /usr/share/doc/php*/changelog.Debian.gz 2>/dev/null; then
      fixed=да
    elif rpm -q --changelog php-cli 2>/dev/null | grep -q "CVE-2026-109618"; then
      fixed=да
    fi
    fpm_start=$(ps -eo lstart,cmd 2>/dev/null | grep -m1 "php-fpm: master" | cut -c1-24)
    echo "php=${php_v:-нет} заплата=$fixed nginx=${ngx_v:-нет} fpm_с=${fpm_start:-нет}"
  ' 2>/dev/null || echo 'недоступен'
done < hosts.txt

Как читать вывод

ПолеЧто означает
заплата=дав журнале пакета найдены номера уязвимостей — исправление установлено
заплата=нетлибо не обновлялись, либо PHP собран вручную или стоит из стороннего источника
fpm_свремя запуска главного процесса PHP-FPM; если оно раньше обновления, старый код ещё в памяти
nginx1.30.6 и новее в стабильной ветке — октябрьский набор закрыт

Что делать с результатом

  1. Сначала серверы с заплата=нет и открытым наружу портом 80 или 443.
  2. Затем те, где заплата есть, но PHP-FPM запущен раньше обновления — им достаточно перезапуска.
  3. Отдельно — контейнеры: скрипт их не видит, проверяйте через docker exec.

Чтобы не повторялось

Поставьте проверку в cron раз в сутки и отправляйте вывод себе. Молчаливый сервер и обновлённый сервер выглядят одинаково, пока их не спросить.

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

Почему не сравнивать просто номера версий?

Потому что при бэкпорте номер не меняется. Сравнение номеров даст ложную тревогу на исправленных серверах и ложное спокойствие — там, где PHP собран вручную.

Скрипт требует root?

Нет, чтение журналов изменений доступно обычному пользователю.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке