Тестирование обновлений перед установкой: стенд, кольца, откат

У обновления безопасности две цены: риск остаться с дырой и риск сломать сервис. Если проверки нет, администратор откладывает установку «до следующих выходных», и сроки из регламента нарушаются. Если проверка есть, обновления идут быстрее: страх падает, потому что известен откат. Ниже схема из трёх частей: стенд, кольца и откат, плюс скрипт смоук-теста, который можно применять к любому сервису.
Автоматическую установку обновлений мы описывали в статье про WSUS, Ansible и dnf-automatic. Как оформлять изменение и откат в заявке — в статье про управление изменениями. Сроки, до которых обновление должно быть установлено, — в основной статье.
Путь обновления
Схема показывает развилки, на которых обновление должно остановиться. Единственный случай, когда выдержку сокращают, — уязвимость из каталога KEV на системе, доступной из интернета. Но даже тогда стенд и откат остаются.
Стенд: как сделать копию, на которой не страшно
Стенд не должен быть красивым, он должен быть похожим на боевую систему. Самый дешёвый способ: восстановить боевую виртуальную машину из резервной копии в изолированной сети. Заодно вы проверите саму копию: проверка восстановления. Для небольшой компании рабочая схема такая.
- Для каждого типа критичной системы (сервер приложения, база данных, почта, файловый сервер, контроллер домена) есть эталонная копия на изолированном стенде, обновляемая раз в квартал.
- Стенд не видит боевую сеть и не может отправить письмо клиенту. Для этого достаточно отдельного VLAN без маршрута наружу.
- Данные на стенде обезличены или искусственные. Если нужны боевые данные, стенд считается системой с теми же требованиями защиты: тестовые данные и ПДн.
Что проверять на стенде
Три группы проверок, которые стоит записать в виде короткого списка и выполнять для каждого обновления.
| Группа | Вопрос | Как проверить |
|---|---|---|
| Совместимость | Установилось ли обновление без ошибок, стартуют ли службы, не сломались ли зависимости | Код выхода установки, systemctl --failed, версии критичных пакетов до и после |
| Функциональность | Делает ли система то, ради чего существует | Смоук-тест: вход в приложение, одна транзакция, один запрос к базе, отправка письма |
| Производительность | Не стала ли система медленнее | Время ответа и нагрузка по тому же сценарию до и после; отклонение более 20% требует разбора |
Смоук-тест скриптом
Ручной тест забывают. Скрипт ниже проверяет службы, порты, ответ веб-сервиса, время ответа и свежие ошибки в журнале. Его надо адаптировать под ваш сервис: список служб и адрес проверки задаются в начале.
#!/usr/bin/env bash
# Смоук-тест после обновления: код 0, если всё в порядке, иначе 1.
# Использование: smoke.sh [URL] [максимальное время ответа в секундах]
set -u
SERVICES="nginx postgresql" # ваши службы
PORTS="443 5432" # порты, которые должны слушаться
URL="${1:-https://localhost/health}"
MAXT="${2:-2}"
fail=0
for s in $SERVICES; do
systemctl is-active --quiet "$s" || { echo "ПРОВАЛ: служба $s не активна"; fail=1; }
done
for p in $PORTS; do
ss -ltn | grep -q ":$p " || { echo "ПРОВАЛ: порт $p не слушается"; fail=1; }
done
read -r code t < <(curl -ksS -o /dev/null -w '%{http_code} %{time_total}' "$URL")
[ "$code" = "200" ] || { echo "ПРОВАЛ: $URL вернул $code"; fail=1; }
awk -v t="$t" -v m="$MAXT" 'BEGIN{exit !(t > m)}' && { echo "ПРОВАЛ: время ответа $t с больше $MAXT"; fail=1; }
errs=$(journalctl -p err --since "-30 min" --no-pager | wc -l)
[ "$errs" -le 5 ] || { echo "ПРОВАЛ: $errs ошибок в журнале за 30 минут"; fail=1; }
systemctl --failed --no-legend | grep -q . && { echo "ПРОВАЛ: есть упавшие службы"; systemctl --failed --no-legend; fail=1; }
[ "$fail" = 0 ] && echo "OK: смоук-тест пройден"
exit "$fail"
Ожидаемо: на исправном узле строка «OK», код 0. На узле, где остановлена одна из служб, строка «ПРОВАЛ» и код 1. Запустите скрипт до обновления, сохраните вывод, затем после обновления и сравните: «до» нужен, чтобы отличать новые ошибки от привычных. Пороги (5 ошибок, 2 секунды) подберите по вашим цифрам, у каждого сервиса они свои.
Кольца раскатки
Стенд ловит большинство проблем, но не все: на боевой системе есть данные и нагрузка, которых на стенде нет. Поэтому обновление идёт по кольцам, и между кольцами выдерживается время, за которое проблемы успевают проявиться.
| Кольцо | Кто входит | Выдержка | Что должно быть в порядке |
|---|---|---|---|
| 0. Стенд | Клон боевой системы | Несколько часов | Смоук-тест, замер времени ответа |
| 1. Пилот | ИТ-отдел, узлы-«канарейки» (5–10% парка) | 1–3 суток | Нет обращений и новых ошибок в журналах |
| 2. Основное | Остальные узлы | По окнам обслуживания | Смоук-тест после каждой партии |
| 3. Критичные | Серверы с ПДн, базы, контроллеры домена | В согласованное с владельцем окно | Откат подготовлен, владелец знает время |
Если срочная уязвимость (P1) требует сжатия, сокращайте выдержку между кольцами, а не количество колец. Минимум для срочного случая: стенд за час-два, затем пилот и сразу основное кольцо.
Откат: подготовьте до установки
Откат должен быть записан в заявку до начала работ. Способы зависят от системы.
| Система | Способ | Команды |
|---|---|---|
| Виртуальная машина | Снимок до обновления | Средствами гипервизора; снимок живёт сутки-двое, потом его удаляют |
| Linux, LVM | Снимок тома перед установкой | sudo lvcreate --size 5G --snapshot --name root_pre /dev/vg0/root, возврат через lvconvert --merge и перезагрузку |
| Debian и Ubuntu, один пакет | Установка предыдущей версии и запрет обновления | apt-cache policy ПАКЕТ, затем sudo apt install ПАКЕТ=ВЕРСИЯ и sudo apt-mark hold ПАКЕТ |
| RHEL, Rocky, Alma | История транзакций dnf | sudo dnf history list, затем sudo dnf history undo НОМЕР |
| Windows, одно обновление | Удаление и скрытие в WSUS | wusa /uninstall /kb:НОМЕР_KB /quiet /norestart, в консоли WSUS отклонить обновление |
Риск: возврат снимка LVM или состояния машины откатывает и данные. Для базы данных отката «целиком» недостаточно: сначала остановите приложение и сделайте дамп. Нужно также проверить, что откат вообще работает: один раз в квартал проведите его на стенде, иначе в плохой день вы узнаете, что снимок не создавался.
Просмотр, что именно было установлено, нужен для отката и для разбора:
# Debian и Ubuntu
grep -E "Start-Date|Upgrade:" /var/log/apt/history.log | tail -n 6
# RHEL, Rocky, Alma
sudo dnf history info last
Заявка на тестирование и установку
Чтобы тестирование оставляло след, заводите по нему задачу. Шаблон:
Тема: Обновление openssl, кольцо 1 (пилот), 12.11
Что обновляем: openssl на узлах пилота (список приложен)
Причина: находка скана, приоритет P2, срок до 26.11
Результат стенда: смоук-тест пройден 10.11, время ответа 180 мс (было 175 мс)
Откат: снимок ВМ, пакет предыдущей версии в локальном репозитории
Критерий успеха пилота: за 48 часов нет новых ошибок в журналах и обращений
Окно основного кольца: 19.11, 22:00–24:00
Ответственный: ИТ-отдел, согласовал владелец сервиса
Какие артефакты хранить
| Что хранить | Что показывает |
|---|---|
| Описание процесса: стенд, кольца, критерии, откат | Тестирование обновлений обязательно и описано |
| Заявки на тестирование с датами и результатами смоук-теста | Процесс выполняется, а не декларируется |
| Выводы смоук-теста до и после установки | Проверка совместимости, функциональности и производительности проведена |
| Запись о проверке отката за квартал | Откат не только задуман, но и работает |
Диагностика
| Симптом | Причина и что делать |
|---|---|
| На стенде всё хорошо, в продуктиве сломалось | Стенд не похож на боевую систему: другие данные, нагрузка или версии. Обновите клон и добавьте в смоук-тест сценарий, который сломался |
| Пилотное кольцо всегда «чистое» | В пилот попали не те узлы. Включайте в него разные типы систем, а не только машины ИТ-отдела |
| Тесты занимают неделю, сроки горят | Все обновления идут по полному пути. Разделите: срочные по ускоренному, плановые по полному |
| Откат не сработал | Снимок не создали или не проверяли. Ввести проверку снимка в чек-лист до установки |
Где это в модели зрелости
Материал относится к направлению «Управление уязвимостями» (хаб: уязвимости, карта: карта зрелости). На втором уровне обновления перед установкой тестируют на стендах: проверяются совместимость, функциональность и производительность. Этот процесс связывает управление уязвимостями с управлением изменениями.
Как проверить
- Для трёх последних обновлений критичных систем есть заявка с результатом стенда и записью об откате.
- Скрипт смоук-теста запускается на тестовом узле и ловит искусственно остановленную службу.
- В пилотном кольце есть узлы разных типов, а не только машины администраторов.
- Откат на стенде проводился за последний квартал, дата записана.
Источники
- NIST SP 800-40 Rev. 4, управление корпоративными исправлениями: csrc.nist.gov.
- Microsoft Learn, развёртывание обновлений Windows по кольцам: learn.microsoft.com.
- CIS Control 7: cisecurity.org/controls.


















