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

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

У обновления безопасности две цены: риск остаться с дырой и риск сломать сервис. Если проверки нет, администратор откладывает установку «до следующих выходных», и сроки из регламента нарушаются. Если проверка есть, обновления идут быстрее: страх падает, потому что известен откат. Ниже схема из трёх частей: стенд, кольца и откат, плюс скрипт смоук-теста, который можно применять к любому сервису.

Автоматическую установку обновлений мы описывали в статье про WSUS, Ansible и dnf-automatic. Как оформлять изменение и откат в заявке — в статье про управление изменениями. Сроки, до которых обновление должно быть установлено, — в основной статье.

Путь обновления

Путь обновления от выхода до раскаткиСхема решений плейбука: от сигнала по шагам и вопросам до закрытия инцидента; ответ «да» уходит вправо, «нет» идёт вниз.Вышло обновление безопасностиУязвимость из KEV на периметре?приоритет P1даУскоренный путь: стендза часы, затем сразупилотнетСмоук-тест на стенде пройден?службы, порты, ответ сервисадаНет: отложить,запросить вендора, мерывместо патчанетПилот прошёл без жалоб за 1–3 дня?журналы, обращения пользователейдаНет: остановитьраскатку, откат пилотанетРаскатать по окнам основных икритичных узловплан отката готов заранееУстановлено, смоук-тест зафиксированв заявке
Ускоренный путь сокращает выдержку, но не отменяет стенд и откат.

Схема показывает развилки, на которых обновление должно остановиться. Единственный случай, когда выдержку сокращают, — уязвимость из каталога 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
Ответственный: ИТ-отдел, согласовал владелец сервиса

Какие артефакты хранить

Что хранить Что показывает
Описание процесса: стенд, кольца, критерии, откат Тестирование обновлений обязательно и описано
Заявки на тестирование с датами и результатами смоук-теста Процесс выполняется, а не декларируется
Выводы смоук-теста до и после установки Проверка совместимости, функциональности и производительности проведена
Запись о проверке отката за квартал Откат не только задуман, но и работает

Диагностика

Симптом Причина и что делать
На стенде всё хорошо, в продуктиве сломалось Стенд не похож на боевую систему: другие данные, нагрузка или версии. Обновите клон и добавьте в смоук-тест сценарий, который сломался
Пилотное кольцо всегда «чистое» В пилот попали не те узлы. Включайте в него разные типы систем, а не только машины ИТ-отдела
Тесты занимают неделю, сроки горят Все обновления идут по полному пути. Разделите: срочные по ускоренному, плановые по полному
Откат не сработал Снимок не создали или не проверяли. Ввести проверку снимка в чек-лист до установки

Где это в модели зрелости

Материал относится к направлению «Управление уязвимостями» (хаб: уязвимости, карта: карта зрелости). На втором уровне обновления перед установкой тестируют на стендах: проверяются совместимость, функциональность и производительность. Этот процесс связывает управление уязвимостями с управлением изменениями.

Как проверить

  1. Для трёх последних обновлений критичных систем есть заявка с результатом стенда и записью об откате.
  2. Скрипт смоук-теста запускается на тестовом узле и ловит искусственно остановленную службу.
  3. В пилотном кольце есть узлы разных типов, а не только машины администраторов.
  4. Откат на стенде проводился за последний квартал, дата записана.

Источники

Комментарии закрыты.