Автоматизация установки обновлений: WSUS, Ansible и dnf-automatic

Пока обновления ставят вручную по памяти администратора, срок на устранение из регламента остаётся пожеланием: сервер забыли, окно пропустили, администратор в отпуске. Автоматизация решает три вещи: обновления ставятся по расписанию, их состояние видно, а у узла, который не обновился, есть повод попасть в список. Ниже для каждой платформы, что ставить, как настроить и как получить отчёт.
Если вы выбираете инструмент для Debian и Ubuntu, подробный разбор в статье про unattended-upgrades. Как тестировать обновления до массовой установки — стенд, кольца, откат. Откуда берутся сроки: управление уязвимостями.
Что чем обновлять
| Платформа | Средство | Что оно делает | Чего не умеет |
|---|---|---|---|
| Windows-серверы и рабочие станции в домене | WSUS и групповые политики | Хранит обновления, позволяет одобрять по группам, показывает, кто что установил | Сторонние приложения: для них нужно другое средство |
| Debian, Ubuntu | unattended-upgrades | Ставит обновления безопасности по таймеру | Не координирует парк: не знает, что узлы нужно обновлять по кольцам |
| Rocky, Alma, RHEL | dnf-automatic | Скачивает и ставит обновления безопасности по таймеру | Та же причина: каждый узел сам по себе |
| Весь парк Linux | Ansible | Кольца, очередность, проверки до и после, перезагрузка, отчёт | Без расписания не работает: запуск нужен из планировщика или CI |
Для критичных систем выбор простой: автоматика ставит обновление на тестовом и пилотном кольце, а на основных узлах его запускает администратор через Ansible или одобрение в WSUS в согласованное окно. Для остальных узлов допустимо полностью автоматическое обновление безопасности.
Windows: WSUS и групповые политики
Microsoft объявила WSUS устаревающим решением (новых функций не будет), но существующие установки продолжают работать и получать исправления. Для инфраструктуры без доступа к облачным службам обновления он остаётся основным вариантом. Установка на сервере с Windows Server:
Install-WindowsFeature -Name UpdateServices -IncludeManagementTools
# после установки роли: каталог для хранения обновлений
& "C:\Program Files\Update Services\Tools\wsusutil.exe" postinstall CONTENT_DIR=D:\WSUS
Ожидаемо: в диспетчере сервера появится роль «Службы WSUS», команда postinstall завершится без ошибок. Для хранения обновлений нужен отдельный диск: каталог быстро занимает сотни гигабайт. Риск: не ставьте WSUS на контроллер домена и не оставляйте каталог на системном диске.
Дальше два шага. В консоли WSUS создайте группы компьютеров: «Тест», «Пилот», «Основные», «Критичные». Затем групповой политикой направьте клиентов на сервер: Computer Configuration → Administrative Templates → Windows Components → Windows Update.
| Параметр политики | Значение | Зачем |
|---|---|---|
| Specify intranet Microsoft update service location | http://wsus.example.com:8530 для обновления и статистики |
Клиенты берут обновления у вас, а не из интернета. Порты WSUS по умолчанию: 8530 (HTTP) и 8531 (HTTPS) |
| Enable client-side targeting | Имя группы, например «Пилот» | Клиент сам попадает в нужную группу, вручную их переносить не нужно |
| Configure Automatic Updates | Автоматически скачивать и устанавливать, по расписанию | Установка идёт без участия пользователя в согласованное окно |
| Configure auto-restart / запрет перезагрузки при вошедшем пользователе | По политике подразделения | Не терять работу пользователя в рабочее время |
Одобрение в консоли WSUS делайте по кольцам: сначала «Тест», через сутки «Пилот», затем «Основные». Автоодобрение разрешайте только для группы «Тест». Раз в месяц чистите сервер, иначе он зарастает устаревшими обновлениями:
Invoke-WsusServerCleanup -CleanupObsoleteUpdates -CleanupUnneededContentFiles -DeclineSupersededUpdates -DeclineExpiredUpdates
Ожидаемо: команда выведет число отклонённых и удалённых обновлений и освобождённое место. Ещё одна проверка, которая важна для отчёта: какие клиенты давно не выходили на связь.
Get-WsusComputer -All | Where-Object { $_.LastReportedStatusTime -lt (Get-Date).AddDays(-14) } |
Select-Object FullDomainName, LastReportedStatusTime
Ожидаемо: список узлов, молчащих больше двух недель. Это либо выключенные машины, либо узлы со сломанным агентом обновления; их надо разобрать отдельно, иначе в отчёте они выглядят как «неизвестно». На самом клиенте проверить установленные обновления можно командой Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5.
RHEL, Rocky, Alma: dnf-automatic
sudo dnf install dnf-automatic
sudoedit /etc/dnf/automatic.conf
Основные параметры файла:
[commands]
upgrade_type = security
download_updates = yes
apply_updates = yes
[emitters]
emit_via = stdio,email
[email]
email_from = root@host.example.com
email_to = it-ops@example.com
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timer
Ожидаемо: таймер включён, в списке видно время ближайшего запуска. Параметр upgrade_type = security ограничивает установку обновлениями безопасности, чтобы не ставить новые версии пакетов без необходимости. Перезагрузка после обновлений автоматически не делается: узнать, нужна ли она, можно так.
sudo dnf needs-restarting -r
Код выхода 1 означает, что нужна перезагрузка, и это стоит включить в отчёт, потому что обновлённое ядро или библиотека не работают, пока узел не перезапущен.
Debian и Ubuntu
Для этих систем используйте unattended-upgrades, как описано в отдельной статье: он ставит исправления безопасности по таймеру и умеет писать в журнал. Для Astra Linux и РЕД ОС порядок установки обновлений задаёт производитель, поэтому перед включением автоматики сверьтесь с его документацией и с методикой ФСТЭК для вашего класса защиты.
Весь парк: Ansible, кольца и проверки
Автоматика на каждом узле не знает о других узлах. Если плохое обновление ставится на всех одновременно, вы узнаете об этом по звонкам. Ansible даёт управляемую очередь: сначала тест, затем пилот, затем остальные. В инвентарной описи заведите группы patch_test, patch_pilot, patch_prod. Пример сценария (для Debian и Ubuntu; для RHEL-семейства вместо двух задач ниже используйте модуль dnf с параметром security: true):
---
- name: Обновления безопасности по кольцам
hosts: "{{ ring | default('patch_test') }}"
become: true
serial: "{{ batch | default(1) }}"
max_fail_percentage: 0
tasks:
- name: Обновить индекс пакетов
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Установить обновления безопасности
ansible.builtin.command: unattended-upgrade -v
register: upg
changed_when: "'Packages that will be upgraded' in upg.stdout"
- name: Нужна ли перезагрузка
ansible.builtin.stat:
path: /var/run/reboot-required
register: reboot_flag
- name: Перезагрузить, если разрешено окном
ansible.builtin.reboot:
reboot_timeout: 600
when: reboot_flag.stat.exists and (allow_reboot | default(false) | bool)
- name: Проверить, что узел вернулся и службы работают
ansible.builtin.command: systemctl is-system-running
register: state
failed_when: state.stdout not in ['running', 'degraded']
changed_when: false
Запускайте так: сначала «в сухую», потом по кольцам.
ansible-playbook patch.yml -e ring=patch_test --check --diff
ansible-playbook patch.yml -e ring=patch_test
# через 1-3 дня, если на тесте всё в порядке
ansible-playbook patch.yml -e ring=patch_pilot -e batch=2
# затем основное кольцо, окно с перезагрузкой
ansible-playbook patch.yml -e ring=patch_prod -e batch=5 -e allow_reboot=true
Ожидаемо: на каждом узле итог «ok» или «changed», остановка очереди при первой ошибке (параметр max_fail_percentage: 0). Риск: перезагрузка серверов баз данных без остановки приложения. Для таких узлов делайте отдельный сценарий с остановкой служб до и проверкой после.
Сценарий запускают по расписанию из планировщика или из CI: тогда у вас остаётся журнал запусков, который можно показать как подтверждение автоматизации.
Отчёт: что ещё не обновлено
Автоматизация без отчёта создаёт иллюзию порядка. Один раз в неделю собирайте состояние: сколько обновлений безопасности ждёт установки на каждом узле и нужна ли перезагрузка.
# Debian и Ubuntu: сколько пакетов ждёт установки
ansible all -b -m shell -a "apt-get -s upgrade | grep -c '^Inst'" -o
# есть ли узлы, ждущие перезагрузки
ansible all -m stat -a "path=/var/run/reboot-required" -o | grep -c '"exists": true'
Для Windows это отчёты WSUS: Reports → Update Status Summary и список клиентов без связи, который мы получили выше. Для руководителя достаточно одной цифры: доля узлов, у которых нет неустановленных обновлений безопасности старше срока из регламента.
Какие артефакты хранить
| Что хранить | Что показывает |
|---|---|
| Перечень решений по платформам с ключевыми настройками (политика WSUS, automatic.conf, сценарий Ansible) | Для критичных систем есть автоматизированное решение, а не память администратора |
| Примеры установки обновлений на критичных системах: журнал запуска Ansible, отчёт WSUS за месяц | Автоматика работает на практике |
| Отчёт о текущем состоянии обновлений | Установка контролируется, видно, что осталось |
| Список узлов, исключённых из автоматики, с причиной | Исключения не потеряны |
Диагностика
| Симптом | Причина и что делать |
|---|---|
| Клиенты Windows не появляются в консоли WSUS | Не применилась политика или заняты порты. Выполните gpresult /r и проверьте доступность порта 8530 |
| dnf-automatic молчит, письма нет | Не настроена почтовая служба на узле. Используйте emit_via = stdio и смотрите журнал: journalctl -u dnf-automatic |
| Ansible останавливается на первом узле кольца | Ошибка на нём. Разберите вывод, это и есть смысл кольца: плохое обновление дальше не пошло |
| Обновление поставлено, но сканер всё ещё видит уязвимость | Не перезапущена служба или узел не перезагружен. Проверьте needrestart и needs-restarting |
| Каталог WSUS занял весь диск | Не делалась очистка. Запустите Invoke-WsusServerCleanup, затем настройте регулярную очистку |
Где это в модели зрелости
Материал относится к направлению «Управление уязвимостями» (хаб: уязвимости, карта: карта зрелости). Он закрывает требование второго уровня: для критичных систем обновлениями управляют автоматизированные решения, которые устанавливают, наблюдают и контролируют. Чтобы автоматика не уронила продуктив, ей нужно предшествовать тестирование, см. управление изменениями.
Как проверить
- Для каждой платформы вашей инфраструктуры названо средство, и оно настроено, а не только установлено.
- На случайном критичном узле видно последнее автоматическое обновление и дату.
- Отчёт о состоянии обновлений получен за последнюю неделю и содержит цифры по узлам.
- Для узла в статусе «ждёт перезагрузки» есть задача на перезагрузку с датой.
Источники
- Microsoft Learn, развёртывание WSUS: learn.microsoft.com.
- Документация dnf-automatic: dnf.readthedocs.io.
- Документация Ansible, модули
apt,dnf,reboot: docs.ansible.com. - NIST SP 800-40 Rev. 4, управление корпоративными исправлениями: csrc.nist.gov.


















