Зачем
Большинство publicly-known CVE эксплуатируются через 30 дней после публикации. Если update'ы накатываются раз в квартал, окно уязвимости огромно. Но «накатить-всё-руками» в 100-узловом флоте не работает, нужен автомат.
Компромисс: автоматически устанавливать только security-update'ы, остальные пакеты, после QA. Это покрывает 95% реальных рисков и не ломает приложения «случайным» апгрейдом MySQL major версии.
Debian / Ubuntu, unattended-upgrades
Пакет в base-репах. Установка:
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 (избежать пиков).
systemctl list-timers apt-daily-upgrade.timer
unattended-upgrade --dry-run -d # debug что будет установлено
Логи:
/var/log/unattended-upgrades/unattended-upgrades.log
/var/log/unattended-upgrades/unattended-upgrades-dpkg.log
RHEL / Fedora / CentOS / Rocky, dnf-automatic
Стандартный модуль dnf:
dnf install dnf-automatic
Конфиг, /etc/dnf/automatic.conf:
[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:
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 в работающее ядро, без перезагрузки. Технология:
- Патч компилируется в kernel module
- Ядро загружает модуль через
livepatch-API - 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)
sudo snap install canonical-livepatch
sudo canonical-livepatch enable <token> # token с ubuntu.com/security
sudo canonical-livepatch status
Free tier, до 5 машин. Заводится в Ubuntu Pro.
kpatch (RHEL/Rocky/AlmaLinux)
dnf install kpatch
systemctl enable --now kpatch
# патчи приходят как kpatch-patch-<kernel-version>.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:
- Drain ноды (k8s
kubectl drain, или вывести из LB) - Apply pending kernel update / reboot
- Wait healthy
- Uncordon → следующая нода
- 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 (старая, удалена с диска, но загружена)
Решение:
# 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'ом).
Проверка статуса в проде
# Сколько 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.confupgrade_type = default. Поменять наsecurity. - Сервис не перезапускается после lib-update,
needrestartне настроен или blacklist. Проверить/etc/needrestart/conf.d/*. reboot-requiredфайл создан, но никто не ребутит, если нет kured / cron-perezagruzki, ноды копят апдейты. Visibility: Prometheusnode_reboot_required.- Livepatch применён, но
uname -rпоказывает старое ядро это нормально.canonical-livepatch statusилиcat /proc/sys/kernel/osrelease. - На старой LTS обновлений нет, но CVE есть, EOL дистро. Migrate на supported или платная extended-support (Ubuntu ESM, RHEL EUS).