MAATRIX / Блог / Правило двух недель для обновлений: почему не стоит ставить релиз в день выхода

Правило двух недель для обновлений: почему не стоит ставить релиз в день выхода

MAATRIX

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

Почему день релиза — худшее время для обновления

Релиз, который вышел час назад, прошёл тестирование только у самого проекта — на его CI, на его тестовых стендах, в его наборе сценариев. У любого мало-мальски крупного open source или коммерческого продукта набор реальных конфигураций пользователей на порядки больше и разнообразнее, чем у команды разработки: другие версии ядра, другие файловые системы, другие сочетания зависимостей, другие паттерны нагрузки. Баг, который не проявился ни на одном стенде разработчиков, стабильно проявляется на пятой по счёту нестандартной конфигурации у кого-то из миллионов пользователей — и это неизбежное следствие масштаба, а не признак того, что проект делают плохо.

Хрестоматийный пример того, зачем вообще нужна пауза, — история 2024 года с бэкдором в liblzma/xz (CVE-2024-3094): вредоносный код несколько недель жил в тарболах пакета, прежде чем его случайно заметил инженер, которого насторожила лишняя пара сотен миллисекунд при SSH-логине. Это крайний случай — умышленный supply chain attack, а не обычный баг, — но он хорошо иллюстрирует тезис: сообщество обнаруживает проблемы не в момент релиза, а спустя дни и недели реальной эксплуатации, иногда по совершенно случайным косвенным признакам.

С обычными регрессиями всё проще и предсказуемее. У крупных дистрибутивов и популярных пакетов (ядро Linux, systemd, PostgreSQL, nginx, Docker, CMS и их плагины) периодически случаются минорные релизы, которые ломают конкретный edge case — не потому что тестирование плохое, а потому что покрыть тестами абсолютно всё невозможно. Если вы поставили обновление в день выхода, вы — часть той самой выборки, на которой баг впервые обнаруживается. Если подождали пару недель — проблему за вас уже нашли, обсудили в issue-трекере, и, скорее всего, к моменту вашего обновления уже вышел патч-релиз с исправлением.

Отдельно стоит сказать: это не аргумент в пользу того, чтобы не обновляться вообще. Устаревший, годами не обновляемый сервер — риск сам по себе, и цена отложенного обновления в виде накопленного техдолга обычно выше, чем риск свежего бага. Правило двух недель — это не «откладывать на потом», а «выдерживать разумный буфер между релизом и установкой на прод», после которого обновление всё равно происходит.

Как работает правило двух недель на практике

Логика простая: между датой публикации релиза и датой установки на прод-сервер выдерживается интервал — по умолчанию около двух недель, — за который успевают проявиться критичные регрессии, если они есть. За этот срок активные пользователи, которые обновляются сразу, успевают наткнуться на баги и завести issue; мейнтейнеры успевают подтвердить проблему и выпустить hotfix или хотя бы предупреждение «пока не обновляйтесь до x.y.1»; дистрибутивы успевают подхватить патч-релиз, если он появился — и в сумме в issue-трекере и на форумах накапливается достаточно сигнала, чтобы понять, «чистый» релиз или нет.

Важный нюанс: две недели — это дефолт для рядового обновления (минорная версия пакета, патч CMS, обновление рантайма), а не универсальная константа для всего подряд. Ниже в статье — таблица с эскалацией сроков в зависимости от критичности компонента, потому что «две недели» для плагина CMS и для мажорного обновления ядра гипервизора — это разные по цене решения.

Практически правило удобно оформить как процесс с двумя состояниями:

  1. Очередь на созревание. Как только вышел релиз, который вам интересен, он попадает в список отслеживания с датой выхода и расчётной датой установки (дата выхода + N дней в зависимости от критичности).
  2. Установка по готовности. По достижении расчётной даты — если за это время не всплыло ничего критичного — обновление ставится по обычному чек-листу (бэкап, тестовый стенд, окно обслуживания).

Если за время ожидания вышел патч-релиз (x.y.1 вместо x.y.0), это хороший сигнал: значит, кто-то уже словил и починил первые проблемы. Разумная практика — вообще не ставить .0-релизы в прод, а ждать первого патч-релиза либо истечения выбранного интервала, смотря что наступит раньше.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Исключения: когда ждать нельзя

Правило двух недель работает для планового цикла обновлений, но у него есть чёткое исключение — критичные патчи безопасности с признаками активной эксплуатации уязвимости. Здесь логика разворачивается на 180 градусов: чем раньше вы патчите, тем меньше окно, в котором ваш сервер уязвим для атаки, которая уже идёт в реальном мире.

Критерии, по которым обновление стоит выводить из-под паузы и ставить в приоритетном порядке: в бюллетене явно указано active exploitation / «эксплуатируется в дикой природе» (формулировка, которую используют CISA KEV и советы безопасности вендоров); высокий CVSS-балл (условно от 9.0) и компонент торчит наружу — публичный веб-сервер, VPN-шлюз, панель управления с доступом из интернета; есть публичный PoC-эксплойт или уязвимость уже фигурирует в зафиксированных атаках; затронутый сервис хранит чувствительные данные — платежи, персональные данные, доступы.

Для таких патчей разумный SLA — часы, максимум сутки-двое: протестировать на стенде по сокращённой схеме (smoke-тест ключевого функционала, а не полный регресс) и выкатить в прод вне обычного окна обслуживания. Именно поэтому в конфигурации автообновлений безопасность обычно выделяют отдельным потоком — например, через unattended-upgrades с фильтром по origin, который ставит security-патчи автоматически и сразу, а всё остальное — по общему расписанию:

# /etc/apt/apt.conf.d/50unattended-upgrades — только security-репозиторий
Unattended-Upgrade::Origins-Pattern {
    "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};
Unattended-Upgrade::Automatic-Reboot "false";

Обычные же обновления (${distro_codename}-updates) в этот список сознательно не включаются — они идут через выдержанную паузу и ручной или полуавтоматический процесс. Подробный разбор автообновлений безопасности и частых ошибок в их настройке — в отдельной статье про автообновления безопасности на сервере.

Исключение — не индульгенция ставить security-патч мгновенно и без тестов: даже срочный патч стоит прогнать через быстрый smoke-тест на staging, потому что бывают случаи, когда сам патч содержит регрессию — и тогда вы просто меняете один инцидент на другой.

Как организовать отслеживание созревания версии

Ручное «погуглить, не жалуется ли кто на новую версию» не масштабируется дальше пары серверов. Рабочий подход — выстроить несколько источников сигнала и завести привычку (или автоматизацию) их проверять к расчётной дате установки.

Источники сигнала, которые стоит мониторить:

  • Issue-трекер проекта на GitHub/GitLab. Фильтр по меткам regression, bug, отсортированный по дате открытия. У GitHub есть встроенный «Watch → Custom → Releases» — уведомление только на новые релизы, без шума от каждого коммита.
  • Security advisories. GitHub Security Advisories, NVD (nvd.nist.gov) и CISA KEV — проверить, не входит ли новая версия сама по себе в патч для уязвимости с активной эксплуатацией (тогда это уже исключение из предыдущего раздела).
  • Списки рассылки дистрибутива. debian-security-announce, ubuntu-security-announce и аналоги — бюллетени там появляются раньше, чем новость расходится по остальным каналам.
  • Форумы и changelog. Reddit, Hacker News, форум проекта — сигнал зашумлённее, чем в трекере, но раньше всего всплывают формулировки вида «после обновления до X начались проблемы»; в release notes проекта стоит смотреть раздел «Known issues» следующего патч-релиза.

Как не делать это вручную каждый раз:

У Renovate есть настройка minimumReleaseAge (в старых версиях — stabilityDays) — она не даёт боту предлагать merge request на обновление зависимости, пока не пройдёт заданное число дней с момента публикации версии. По сути, правило паузы, встроенное прямо в пайплайн:

{
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "minimumReleaseAge": "14 days"
    },
    {
      "matchPackagePatterns": ["*"],
      "matchCurrentVersion": "!/^0/",
      "vulnerabilityAlerts": {
        "minimumReleaseAge": "0 days"
      }
    }
  ]
}

Для системных пакетов без внешних сервисов: apt-mark hold фиксирует пакет на текущей версии, пока вы явно не снимете hold:

# зафиксировать версию, чтобы обновление не встало случайно
sudo apt-mark hold nginx

# посмотреть, что зафиксировано
apt-mark showhold

# снять фиксацию, когда пауза выдержана и версия «созрела»
sudo apt-mark unhold nginx
sudo apt-get install --only-upgrade nginx

Для Docker-образов аналог — не гнаться за тегом latest, а пиннить конкретную версию и переключать её вручную по расписанию, а не через Watchtower с автоприменением на каждый push; если Watchtower используется, держите его в режиме уведомлений без автообновления — сначала узнать, что вышло, и только потом решать, когда ставить.

Практический минимум для небольшой инфраструктуры — таблица (Trello, Notion, markdown-файл в репозитории) с колонками «пакет / версия / дата релиза / плановая дата установки / статус проверки источников». Это требует не инструмента, а привычки заносить релиз в очередь в момент, когда его увидели, а не когда решили ставить.

Эскалация сроков по критичности компонента

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

Критичность компонентаПримерыПауза
Низкая — легко откатитьDev-окружения, второстепенные утилиты0–3 дня
Средняя — внутренние сервисыStaging, дашборды, CI-раннеры3–7 дней
Стандартная — прод с резервированиемВеб-приложение, API, CMS-плагины за балансировщиком~14 дней (базовое правило)
Высокая — тяжёлый blast radiusСУБД (мажорные версии), гипервизор, ядро под нагрузкой, сетевой стек21–30 дней, через промежуточный стенд
Критичная безопасность с активной эксплуатациейCISA KEV, публичный PoC, компонент торчит в интернетЧасы — 1–2 дня

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

Как встроить правило в процесс, а не держать в голове

Правило, которое существует только как устная договорённость, забывается при первом же дедлайне. Чтобы оно реально работало, его стоит закрепить в трёх местах: в регламенте — письменно, даже одним абзацем в внутренней wiki: дефолтный интервал, таблица эскалации, явное исключение для security-патчей с активной эксплуатацией; в таск-трекере — каждый релиз, взятый в очередь на созревание, это карточка с датой релиза, расчётной датой установки и чек-листом источников для финальной проверки; в окне обслуживания — если у вас уже есть регулярное техническое окно, синхронизируйте его с недельным циклом проверки очереди: например, по понедельникам смотрите, что «созрело» к текущей неделе. Без письменной фиксации решение «ждать или не ждать» каждый раз принимается заново, под давлением текущей ситуации — а именно этого правило и должно избегать.

Отдельно стоит держать под рукой быстрый путь назад на случай, если пауза не спасла и регрессия всё же добралась до прода — снапшот или бэкап перед установкой и заранее прописанный runbook отката. Как организовать быстрый откат, если обновление всё же уронило прод, подробно разобрано в статье обновление положило прод — как откатиться. Двухнедельная пауза резко снижает вероятность такого сценария, но не обнуляет её — и рассчитывать процесс стоит на оба исхода.

Типичные ошибки при внедрении правила

Пауза применяется ко всему одинаково. Взять «две недели» как жёсткую константу и применить её и к критичному security-патчу, и к обновлению внутреннего дашборда — первое опасно затягивает окно уязвимости, второе избыточно тормозит безобидные изменения. Таблица эскалации выше как раз для того, чтобы не сводить решение к одному числу.

Автообновления включены без разделения потоков. Если unattended-upgrades или аналог настроен ставить все обновления без разбора origin, правило паузы просто не работает — сервер обновляется в тот же день, когда пакет попал в репозиторий, независимо от плана. Разделение на «security — сразу» и «остальное — по расписанию» описано в разделе про исключения выше.

Очередь есть, но источники никто не проверяет. Завести список с датами — половина дела; если к расчётной дате никто не смотрит issue-трекер и advisories, обновление ставится «потому что подошёл срок», без учёта того, что реально произошло за эти две недели.

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

Нет отдельного канала для срочных security-релизов. Если единственный процесс — общая очередь с двухнедельной паузой, критичный патч рискует попасть туда же по инерции. Быстрый путь для патчей с активной эксплуатацией должен существовать отдельно от основного потока.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

Правило двух недель — это универсальный стандарт индустрии?

Нет, это практический эвристический подход, а не формальный SLA. Конкретный срок адаптируйте под критичность компонента — таблица эскалации задаёт ориентиры, а не жёсткие цифры.

А если конкурент уже поставил обновление и получил новую фичу раньше?

Для большинства инфраструктурных и security-обновлений выигрыш в две недели ничтожен по сравнению с риском простоя из-за непротестированной регрессии. Если речь о фиче, критичной для бизнеса именно сейчас, — это осознанное решение, а не дефолт «свежее лучше».

Нужно ли ждать две недели даже для низкорисковых компонентов вроде dev-окружений?

Нет, пауза для них может быть минимальной или нулевой — см. таблицу эскалации.

Как быть с обновлениями, у которых нет публичного issue-трекера (закрытое ПО)?

Ориентируйтесь на бюллетени вендора и статус-страницы поддержки. Если сигнала мало, увеличьте паузу и добавьте промежуточный шаг — сначала staging с реальными данными.

Что делать, если обновление критично по безопасности, но активная эксплуатация ещё не подтверждена?

Промежуточный случай: сокращённая, но не нулевая пауза — несколько дней вместо часов, с приоритетным мониторингом advisories и KEV-каталога.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →