# Автообновления безопасности (unattended-upgrades, dnf-automatic, livepatch) _Безопасность · LinuxLab Knowledge Base_ **TL;DR:** Debian/Ubuntu - unattended-upgrades, RHEL - dnf-automatic. Auto только security-updates, остальное вручную. Live patching ядра (livepatch/kpatch) даёт security-fixes без reboot. Без autoreboot - но с уведомлением о необходимости. ## Зачем Большинство **publicly-known CVE** эксплуатируются через 30 дней после публикации. Если update'ы накатываются раз в квартал, окно уязвимости огромно. Но «накатить-всё-руками» в 100-узловом флоте не работает, нужен автомат. Компромисс: **автоматически устанавливать только security-update'ы**, остальные пакеты, после QA. Это покрывает 95% реальных рисков и не ломает приложения «случайным» апгрейдом MySQL major версии. ## Debian / Ubuntu, unattended-upgrades Пакет в base-репах. Установка: ```bash apt install unattended-upgrades apt-listchanges dpkg-reconfigure -plow unattended-upgrades # → создаёт /etc/apt/apt.conf.d/20auto-upgrades ``` Главный конфиг, `/etc/apt/apt.conf.d/50unattended-upgrades`: ``` Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security"; // только security // "${distro_id}:${distro_codename}-updates"; // всё остальное - off // "${distro_id}ESMApps:${distro_codename}-apps-security"; // "${distro_id}ESM:${distro_codename}-infra-security"; }; Unattended-Upgrade::Package-Blacklist { "linux-*"; // ядро не апгрейдить "postgresql-*"; // БД отдельно }; Unattended-Upgrade::Mail "ops@example.com"; Unattended-Upgrade::MailReport "on-change"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Automatic-Reboot "false"; // НЕ ребутить Unattended-Upgrade::Automatic-Reboot-Time "03:00"; // если "true" ``` И `/etc/apt/apt.conf.d/20auto-upgrades`: ``` APT::Periodic::Update-Package-Lists "1"; // apt update APT::Periodic::Unattended-Upgrade "1"; // запускать APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; ``` Запускается **systemd timer** `apt-daily-upgrade.timer`, раз в день, со случайным delay (избежать пиков). ```bash systemctl list-timers apt-daily-upgrade.timer unattended-upgrade --dry-run -d # debug что будет установлено ``` Логи: ```bash /var/log/unattended-upgrades/unattended-upgrades.log /var/log/unattended-upgrades/unattended-upgrades-dpkg.log ``` ## RHEL / Fedora / CentOS / Rocky, dnf-automatic Стандартный модуль dnf: ```bash dnf install dnf-automatic ``` Конфиг, `/etc/dnf/automatic.conf`: ```ini [commands] upgrade_type = security # default | security | minimal random_sleep = 300 # 0-N секунд delay (анти-thundering) network_online_timeout = 60 download_updates = yes apply_updates = yes # действительно ставить (не только download) [emitters] emit_via = stdio,email # куда уведомлять system_name = web-01.prod [email] email_from = root@web-01.prod email_to = ops@example.com email_host = localhost [base] debuglevel = 1 ``` Затем включить timer: ```bash systemctl enable --now dnf-automatic.timer # или вариант "только download, без apply" systemctl enable --now dnf-automatic-download.timer systemctl enable --now dnf-automatic-notifyonly.timer ``` Три timer-unit'а, выбираешь нужное поведение. ## SUSE, zypper-automatic / yast2-online-update ``` zypper install yast2-online-update-configuration yast online_update_configuration ``` Или cron: ``` 0 3 * * * /usr/bin/zypper -n patch --category security ``` ## Kernel live-patching, апдейт ядра без reboot Самые болезненные CVE, kernel-уровня (privilege escalation). Они требуют новое ядро → reboot → даунтайм. **Live patching** позволяет внедрить hotfix в работающее ядро, без перезагрузки. Технология: 1. Патч компилируется в **kernel module** 2. Ядро загружает модуль через `livepatch`-API 3. Ftrace перенаправляет вызовы старой функции на новую Provider'ы: | Provider | Дистро | Тип | |----------|--------|-----| | **Canonical Livepatch** | Ubuntu (free до 5 машин с UA) | proprietary | | **kpatch** | RHEL/CentOS/Fedora | open-source + RH-патчи | | **kGraft** | SUSE Enterprise (legacy) | merged в Linux | | **TuxCare KernelCare** | universal | commercial | ### Canonical Livepatch (Ubuntu) ```bash sudo snap install canonical-livepatch sudo canonical-livepatch enable # token с ubuntu.com/security sudo canonical-livepatch status ``` Free tier, до 5 машин. Заводится в Ubuntu Pro. ### kpatch (RHEL/Rocky/AlmaLinux) ```bash dnf install kpatch systemctl enable --now kpatch # патчи приходят как kpatch-patch-.rpm dnf install kpatch-patch-5.14.0-362.13.1 ``` Или подписка Red Hat Enterprise Linux for Live Patching. ## Когда live-patching не подходит - **Большое изменение** (новый syscall, новая subsystem), патч not livepatch-able. Только reboot. - **Userspace updates** (libc, openssl), livepatch не помогает, надо restart процессов. `needrestart` (Debian) или `dnf needs-restarting`. - **Initramfs / bootloader**, никогда не live. Поэтому **планировать reboot** всё равно надо, просто реже раз в квартал или после большого CVE-окна. ## Reboot-стратегия В кластере с redundancy: 1. **Drain** ноды (k8s `kubectl drain`, или вывести из LB) 2. Apply pending kernel update / reboot 3. Wait healthy 4. Uncordon → следующая нода 5. Rolling через всё. Tools: - **kured** (Kubernetes Reboot Daemon), DaemonSet, видит `/var/run/reboot-required`, делает rolling reboot - **system-reboot** Ansible playbook - **AWS Systems Manager Patch Manager**, для облачных VM Кажется простым, но в проде с 100+ нод координация критична без kured получается «случайно ребутнули control-plane разом». ## Userspace restart, `needrestart` / `needs-restarting` После update'а **процессы продолжают использовать старые .so**: ``` $ openssl version OpenSSL 3.0.13 # новая $ ls -la /proc/$(pgrep nginx)/maps | grep libssl → libssl.so.3.0.11 (старая, удалена с диска, но загружена) ``` Решение: ```bash # Debian/Ubuntu apt install needrestart needrestart -r i # interactive: что рестартить? needrestart -r a # auto-restart # RHEL dnf install yum-utils needs-restarting -r # требует ли reboot? needs-restarting -s # какие сервисы? ``` unattended-upgrades + needrestart можно настроить чтобы рестартили сервисы автоматически (с whitelist'ом). ## Проверка статуса в проде ```bash # Сколько security-обновлений pending? apt list --upgradable 2>/dev/null | grep -i security | wc -l # На RHEL dnf updateinfo list security # Когда последний раз был auto-upgrade? grep "Run install" /var/log/unattended-upgrades/unattended-upgrades.log | tail ``` Метрика для monitoring (Prometheus node-exporter): `apt_upgrades_pending`, `apt_upgrades_pending_security`. Alert если security >0 более 24h. ## Когда что-то пошло не так - **`unattended-upgrades` не запускается**, проверить `/etc/apt/apt.conf.d/20auto-upgrades`, должна быть строка `APT::Periodic::Unattended-Upgrade "1";`. Иначе `dpkg-reconfigure`. - **`Cache has broken packages`** во время auto-upgrade, конфликт зависимостей, держится в pending. Решение: `apt --fix-broken install` руками. - **dnf-automatic ставит всё, не только security**, в `automatic.conf` `upgrade_type = default`. Поменять на `security`. - **Сервис не перезапускается после lib-update**, `needrestart` не настроен или blacklist. Проверить `/etc/needrestart/conf.d/*`. - **`reboot-required` файл создан, но никто не ребутит**, если нет kured / cron-perezagruzki, ноды копят апдейты. Visibility: Prometheus `node_reboot_required`. - **Livepatch применён, но `uname -r` показывает старое ядро** это нормально. `canonical-livepatch status` или `cat /proc/sys/kernel/osrelease`. - **На старой LTS обновлений нет, но CVE есть**, EOL дистро. Migrate на supported или платная extended-support (Ubuntu ESM, RHEL EUS). ## Команды ```bash unattended-upgrade --dry-run -d ``` Debug-режим - покажет что будет установлено сейчас, без реальных изменений ```bash systemctl list-timers apt-daily-upgrade.timer ``` Когда последний раз запускался и когда следующий запуск автообновления ```bash apt list --upgradable 2>/dev/null | grep -i security ``` Только security-обновления pending - быстрая проверка perimeter ```bash dnf updateinfo list security ``` RHEL/Rocky - все pending security-update'ы с CVE-номерами ```bash needrestart -r a ``` Auto-restart всех процессов с устаревшими .so после lib-update'а ```bash sudo canonical-livepatch status ``` Текущее состояние kernel-livepatch на Ubuntu - какие patch'и применены ```bash ls /var/run/reboot-required && cat /var/run/reboot-required.pkgs ``` Нужен ли reboot и из-за каких пакетов - стандартный маркер Debian ## См. также - [systemctl - управление сервисами systemd](/kb/cmd-systemctl.md) - [cron и crontab - расписание задач](/kb/cmd-cron-crontab.md) - [CIS Benchmark и system hardening (lynis, OpenSCAP)](/kb/cis-benchmark-hardening.md) - [journalctl - журнал systemd](/kb/cmd-journalctl.md) - [fail2ban - автобан по логам](/kb/fail2ban.md)