Автоматические обновления безопасности: настройка unattended-upgrades
Как настроить unattended-upgrades так, чтобы механизм действительно работал: разрешённые источники, исключённые пакеты, поведение при перезагрузке, отчёт на почту и доказательство в журнале, что ночью что-то произошло.
Между выходом обновления безопасности и его установкой на большинстве серверов остаётся зазор. Возникает он редко из-за небрежности, чаще из-за того, что кто-то собирается заняться этим «на следующей неделе». Сканеры перебирают ставшую известной уязвимость в течение нескольких часов. Пакет unattended-upgrades этот зазор закрывает.
Краткая версия описана как шаг 7 в чек-листе для нового root-сервера. Здесь речь идёт обо всём, что следует дальше: обновления безопасности против всех обновлений подряд, поведение при перезагрузке на игровом сервере, уведомления на почту, исключённые пакеты, пробный прогон и подтверждение в журнале.
Проверено на Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS и Ubuntu 22.04 LTS. Там, где эти четыре системы расходятся, об этом сказано отдельно. Команды рассчитаны на работу от имени root. Если вы работаете под обычным пользователем, добавляйте перед каждой из них sudo.
Что здесь на самом деле происходит
Поиск неисправностей затягивается именно потому, что непонятно, какая из трёх участвующих частей делает не то, что от неё ждут:
- Два таймера systemd:
apt-daily.timerотвечает за списки пакетов и скачивание,apt-daily-upgrade.timerза установку. - Скрипт
/usr/lib/apt/apt.systemd.daily, который разбирает параметры из разделаAPT::Periodic::. - Программа
unattended-upgrade, которая разбирает параметры из разделаUnattended-Upgrade::и делает саму работу.
Обратите внимание на единственное число: пакет называется unattended-upgrades, программа unattended-upgrade.
systemctl list-timers 'apt-daily*' --all
systemctl cat apt-daily-upgrade.timer
Столбцы LAST и PASSED показывают, был ли вообще хоть один запуск. В самом unit прописано OnCalendar=*-*-* 6:00 вместе с RandomizedDelaySec=60m: запуск приходится на промежуток между шестью и семью утра, а у apt-daily.timer разброс составляет двенадцать часов. Тот, кто заглянет в 06:05, ошибочно решит, что механизм сломан.
Перед первым изменением: путь назад
Автоматические обновления вмешиваются в систему тогда, когда вас нет за консолью. Пойти не так может трижды: перезагрузка выводит сервер из работы, операция с пакетами обрывается и оставляет dpkg в незавершённом состоянии, либо служба после обновления больше не запускается.
Доступ, который работает во всех трёх случаях, это не SSH. У KVM root-серверов и выделенных серверов KernelHost нет ни IPMI, ни iDRAC, аварийный доступ идёт через VNC-консоль в личном кабинете. Она держится на уровне виртуализации, а на выделенном сервере на самом подключении, поэтому сбой в гостевой системе до неё не доходит. Зайдите через неё один раз заранее и проверьте пароль root. Аварийный путь, который пробуют впервые уже в аварии, аварийным путём не является.
Затем сохраните исходное состояние:
mkdir -p /root/pre-unattended
cp -a /etc/apt/apt.conf.d/50unattended-upgrades /root/pre-unattended/
dpkg --get-selections > /root/pre-unattended/packages.txt
apt-mark showhold > /root/pre-unattended/holds.txt
Аварийный выключатель есть в двух вариантах. Жёсткий, через таймеры:
systemctl disable --now apt-daily-upgrade.timer apt-daily.timer
Мягкий вариант состоит в том, чтобы задать в /etc/apt/apt.conf.d/20auto-upgrades значение APT::Periodic::Unattended-Upgrade "0";. Тогда списки пакетов остаются актуальными, а устанавливаться не будет ничего.
Проверка результата:
systemctl is-enabled apt-daily-upgrade.timer
apt-config dump APT::Periodic
Для отката: /var/log/apt/history.log называет старый и новый номер версии. Но apt install пакет=версия сработает только до тех пор, пока старая версия ещё лежит на зеркале, а архивы чаще всего держат лишь текущее состояние. Рассчитывайте на исправление вперёд и на резервную копию.
Установка и включение
apt update
apt install -y unattended-upgrades
Разница между дистрибутивами: в Ubuntu 22.04 и 24.04 пакет уже стоит в серверных образах и работает, поэтому там сначала проверьте текущее состояние. В Debian на минимальных образах его нет, и установка спрашивает, ставить ли стабильные обновления автоматически. Если она идёт не в интерактивном режиме, например при сборке образа, действует значение по умолчанию, и решающий файл так и не появляется.
Дело в том, что сам по себе пакет ничего не включает. Это делает только вот этот файл:
cat /etc/apt/apt.conf.d/20auto-upgrades
Если файла нет, команда сообщит cat: /etc/apt/apt.conf.d/20auto-upgrades: No such file or directory. Тогда либо вызовите пропущенный вопрос заново командой dpkg-reconfigure -plow unattended-upgrades, либо напишите файл сами:
cat > /etc/apt/apt.conf.d/20auto-upgrades <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
EOF
Значения здесь не переключатели «да или нет», а интервалы в днях: "1" ежедневно, "7" не чаще раза в неделю, "0" выключено. AutocleanInterval убирает файлы пакетов, которых на зеркале уже нет, и на небольших системных накопителях это заметно (диск заполнен в Linux).
Проверка результата: apt-config dump APT::Periodic выводит заданные строки. Если не выводится вообще ничего, значит ни один файл прочитан не был и ночной запуск ничего не делает.
Собственные настройки в правильном месте
Поставляемый с пакетом файл /etc/apt/apt.conf.d/50unattended-upgrades принадлежит пакету. Если вы его измените, при следующем обновлении пакета возникнет конфликт по файлу конфигурации, и unattended-upgrades начнёт этот пакет пропускать. Получится, что инструмент автоматических обновлений сам себя из них и исключил.
Собственные значения кладут в отдельный файл с более высоким номером. APT читает каталог по алфавиту, и для простых значений побеждает прочитанное последним:
cat > /etc/apt/apt.conf.d/52unattended-upgrades-local <<'EOF'
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Unattended-Upgrade::MinimalSteps "true";
EOF
MinimalSteps включён по умолчанию и разбивает запуск на мелкие шаги, которые при выключении системы можно чисто прервать. Remove-Unused-Kernel-Packages убирает старые ядра, которые иначе заполняют раздел /boot. Оба параметра очистки в Ubuntu заданы по умолчанию, в Debian нет.
Имя файла здесь не мелочь. APT читает тут только файлы без расширения или с расширением .conf, и только имена из букв, цифр, дефиса, подчёркивания и точки. Резервная копия 52unattended-upgrades-local.bak будет молча пропущена, что удобно; файл 52-my-settings.txt точно так же, а вот это уже досадно.
Проверка результата, сразу после каждого изменения:
apt-config dump > /dev/null && echo "Синтаксис в порядке"
apt-config dump | grep "^Unattended-Upgrade::"
Пропущенная точка с запятой парализует любой вызов apt, в том числе и ночной.
Только обновления безопасности или все обновления
Какие пакеты вообще попадают в рассмотрение, решает список разрешённых источников. Дистрибутивы расходятся уже в названии ключа: Debian использует Unattended-Upgrade::Origins-Pattern, Ubuntu Unattended-Upgrade::Allowed-Origins.
sed -n '/Allowed-Origins\|Origins-Pattern/,/};/p' /etc/apt/apt.conf.d/50unattended-upgrades
По умолчанию активны шаблоны для источника безопасности и для основного архива вашего собственного выпуска. Закомментированы дополнительные наборы (pockets) -updates, -proposed и -backports. В Ubuntu там дополнительно стоят две записи для расширенной поддержки; без подписки они ничего не дают. Подстановки ${distro_id} и ${distro_codename} программа раскрывает во время работы, например в Debian и trixie.
Откуда берутся составные части шаблона, показывает apt-cache policy. Для каждого источника там есть строка, начинающаяся с release, с полями o= (происхождение), a= (архив), n= (кодовое имя), l= (метка) и c= (компонент). Источник безопасности Debian несёт метку Debian-Security, и именно на неё нацелен поставляемый шаблон.
Если вы хотите, чтобы автоматически приходили и текущие исправления дистрибутива, дополните шаблон в собственном файле. Списки в конфигурации apt дополняются, а не заменяются:
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename}-updates";
};
В Ubuntu этому соответствует "${distro_id}:${distro_codename}-updates"; внутри блока Allowed-Origins. Полностью заменить список можно единственным способом: сначала очистить его через #clear Unattended-Upgrade::Origins-Pattern;.
Для сторонних источников порядок точно такой же. Правда, они часто приносят новые функциональные версии вместо чистых исправлений безопасности, а установка такого ночью и без присмотра, это уже другой класс риска. Поэтому для боевых систем правило простое: оставаться на источниках безопасности.
Пробный прогон
apt update
unattended-upgrade --dry-run --debug
apt update перед этим не украшение: пробный прогон сам списки пакетов не обновляет, и без этого вызова вы оцениваете вчерашнее состояние. Устанавливаться при этом не будет ничего. В выводе имеют значение четыре места:
Allowed origins are:со списком, который действует на самом деле. Именно это, а не взгляд в файл, доказывает, что ваше изменение дошло до программы.Initial blacklist:с вашими исключениями. Если там пусто, хотя вы их вносили, значит ваш файл не читается.- Строки, начинающиеся с
Checking:, по одной на пакет, с источником и решением о допуске. - В конце либо
Packages that will be upgraded:со списком, либоNo packages found that can be upgraded unattended and no pending auto-removals.
Последнее сообщение появляется и тогда, когда apt list --upgradable вполне себе перечисляет пакеты. Это не ошибка, а работа фильтра: каждый пакет, который есть там и отсутствует в пробном прогоне, либо приходит из неразрешённого источника, либо стоит в вашем списке исключений, либо придержан через apt-mark hold, либо вызывает вопрос о файле конфигурации.
Как исключить пакеты из автоматики
Кое-что обновлять ночью не стоит: базу данных, перезапуск которой оборвёт работу приложения, или ядро системы, которая не должна перезагружаться без предупреждения. Первый из двух путей действует только на автоматику:
Unattended-Upgrade::Package-Blacklist {
"mariadb-server$";
"nginx$";
"linux-image-";
};
Записи здесь — регулярные выражения, привязанные к началу имени пакета. Поэтому "nginx" без знака доллара попадает ещё и в nginx-common и в nginx-full, а $ ограничивает запись ровно этим именем. И наоборот, "linux-image-" без $ написано верно, если вы имеете в виду все пакеты ядра.
Второй путь действует на любой вызов apt, то есть и на ваш ручной apt upgrade:
apt-mark hold mariadb-server
apt-mark showhold
Отменяется это командой apt-mark unhold. Если пакет не должен обновляться только без присмотра, берите список исключений; если он не должен обновляться вообще, берите hold.
Проверка результата: apt-config dump | grep -i "Package-Blacklist" и apt-mark showhold. Неудобная сторона: исключённый пакет вам придётся обновлять самостоятельно. Назначьте для этого дату, иначе через полгода исключение превратится в забытую уязвимость.
Автоматическая перезагрузка
Новое ядро после обновления уже лежит на накопителе, но работать начинает только после перезагрузки, а заменённые библиотеки вступают в дело только тогда, когда служба перезапустится. Управляют этим три параметра:
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
Automatic-Reboot по умолчанию выключен. Automatic-Reboot-WithUsers по умолчанию включён, и это многих удивляет: открытая SSH-сессия перезагрузке не помешает, а кто хочет обратного, ставит значение "false". Automatic-Reboot-Time обязателен, как только перезагрузка включена. Без этого указания действует now, то есть сервер перезагрузится сразу после запуска, а значит между шестью и семью часами утра.
Запускает её не пакет ядра, а файл-признак:
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
Самое серьёзное по последствиям различие в этой статье: Ubuntu этот файл создаёт (он приходит из пакета update-notifier-common), а второй файл называет ответственные пакеты. Debian по умолчанию его не создаёт. Там Automatic-Reboot "true" может постоянно оставаться без действия, и при этом ни о какой ошибке не сообщается. Кто на это положится, месяцами работает со старым ядром и с приятным ощущением, что всё под контролем. В Debian вместо этого помогает вот что:
apt install -y needrestart
needrestart -b
Вывод называет в строке NEEDRESTART-KCUR работающее ядро, а в NEEDRESTART-KEXP ожидаемое; если они различаются, перезагрузка назрела. Строки NEEDRESTART-SVC перечисляют службы, которые всё ещё работают с заменёнными библиотеками.
Почему на игровом сервере настройка выглядит иначе
На веб-сервере перезагрузка в 02:00 занимает секунды, и её никто не замечает. На игровом сервере подключены игроки, мир лежит в оперативной памяти, а сохранение записывается полностью только при штатном завершении. Если процесс снимут жёстко, вы потеряете весь прогресс с момента последнего автосохранения, а в худшем случае файл мира окажется повреждён.
К этому добавляется деталь systemd: при выключении каждая служба получает сигнал остановки, а затем ограниченный срок, по истечении которого её завершают жёстко. Игровому серверу, который при завершении сначала сохраняется, часто нужно больше времени, чем даёт значение по умолчанию, а ещё ему нужна команда остановки, которая отправляет stop в консоль сервера, а не просто сигнал стартовому скрипту. Поэтому для игровых серверов разумной будет вот такая комбинация:
Automatic-Reboot "false". Обновления безопасности продолжают ставиться, а перезагрузка остаётся вашим решением.- Окно обслуживания с малым числом игроков, объявленное заранее, а не свалившееся неожиданно.
- Unit systemd с сохраняющей командой остановки и достаточным
TimeoutStopSec, смотрите статью создание systemd-сервиса. - Если всё же автоматически, то
Automatic-Reboot-Timeна время суток с малым числом игроков.
Проверить это можно и без перезагрузки: остановите службу через systemctl stop, посмотрите сохранение, запустите снова. Если всё проходит чисто, то и перезагрузку в 02:00 сервер переживёт.
Как сдвинуть время запуска
systemctl edit apt-daily-upgrade.timer
[Timer]
OnCalendar=
OnCalendar=*-*-* 03:30
RandomizedDelaySec=30m
Пустая строка OnCalendar= обязательна, она стирает поставляемое значение. Без неё ваше время добавится к прежнему, и запуск будет происходить дважды в сутки.
systemctl daemon-reload
systemctl restart apt-daily-upgrade.timer
systemctl list-timers 'apt-daily*' --all
Проверка результата: в столбце NEXT стоит новое время.
Уведомления по электронной почте
Механизм, о котором никто ничего не слышит, не контролируют, а забывают. Две строки это меняют:
Unattended-Upgrade::Mail "admin@example.com";
Unattended-Upgrade::MailReport "on-change";
У MailReport три значения: always после каждого запуска, on-change только когда что-то установлено или пошло не так, only-on-error только при ошибке. Более старый параметр MailOnlyOnError замените, если он вам попадётся.
Условие тут одно: должен быть путь отправки. unattended-upgrades отправляет через /usr/bin/mail или через /usr/sbin/sendmail. Если нет ни того, ни другого, отправки не будет, и вы об этом не узнаете. На свежем сервере это обычное дело:
apt install -y bsd-mailx
echo "Тестовое сообщение" | mail -s "Тест с сервера" admin@example.com
Вместе с этим ставится и служба доставки почты. Проверьте потом через ss -lntp | grep ':25', что она слушает только на 127.0.0.1. Кроме того, письма прямо с IP-адреса сервера часто попадают в папку со спамом, поэтому, если отчёт должен доходить, ведите отправку через релей-сервер с аккуратно настроенным доменом отправителя.
Практический совет: на первые две недели поставьте always. Ежедневное письмо о том, что делать было нечего, это самое простое доказательство того, что механизм работает. Потом вернитесь к on-change, иначе вы скоро начнёте удалять эти письма не читая.
Как убедиться, что действительно что-то произошло
ls -l /var/log/unattended-upgrades/
tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.log
Там лежат до трёх файлов. unattended-upgrades.log фиксирует, что решила программа. unattended-upgrades-dpkg.log содержит сырой вывод установки, и туда вы смотрите, если пакет не смог настроиться. unattended-upgrades-shutdown.log появляется после запуска, который завершился при выключении системы.
Запуск без событий заканчивается строкой No packages found that can be upgraded unattended and no pending auto-removals. Запуск, который что-то сделал, содержит Packages that will be upgraded: и ниже All upgrades installed. Если файл пуст или каталога нет, значит ни одного запуска ещё не было.
Независимо от этого система управления пакетами записывает каждое действие со старым и новым номером версии:
grep -E "^(Start-Date|Commandline|Upgrade|End-Date):" /var/log/apt/history.log | tail -n 20
zgrep -h "^Upgrade:" /var/log/apt/history.log*.gz | tail -n 10
Второй вызов обращается к ротированным файлам, а кто смотрит только в текущий, ничего не находит и делает из этого неверный вывод. Третий источник — systemd:
journalctl -u apt-daily-upgrade.service --since "-7 days" --no-pager
Ловушка, в которую попадается почти каждый: systemctl status unattended-upgrades.service постоянно показывает active (running). Это не идущее обновление. Задача этого unit в том, чтобы завершить начатый запуск при выключении системы, а всё остальное время он ждёт. Устанавливается всё в apt-daily-upgrade.service.
Частые ошибки и их решения
cat: /etc/apt/apt.conf.d/20auto-upgrades: No such file or directory
Пакет установлен, но ничего не включено; в Debian это нормальное состояние после неинтерактивной установки. Решение: dpkg-reconfigure -plow unattended-upgrades.
No packages found that can be upgraded unattended and no pending auto-removals, хотя apt list --upgradable показывает пакеты
Это не ошибка, а фильтр. Проверьте по порядку: разрешённые источники в пробном прогоне, список исключений, apt-mark showhold, вопросы о файлах конфигурации.
E: Syntax error /etc/apt/apt.conf.d/52unattended-upgrades-local:2: Extra junk at end of file
Пропущенная точка с запятой в конце строки или незакрытая фигурная скобка. Пока ошибка на месте, срывается любой вызов apt, а не только автоматика.
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (unattended-upgr) вместе с E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
Автоматический запуск занят, и обрезанное до пятнадцати символов имя процесса это выдаёт. Подождите несколько минут. Если снять процесс принудительно, вы получите следующую ошибку из этого списка. Подробно: apt не удалось получить блокировку.
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.
Выполните ровно эту команду. Заданный по умолчанию Unattended-Upgrade::AutoFixInterruptedDpkg позволяет следующему запуску починить это самому, но только если он до этого дойдёт.
Package nginx-common has conffile prompt and needs to be upgraded manually в журнале
Вы изменили файл конфигурации, который принадлежит пакету, а новая версия несёт с собой изменённый вариант. Программа после этого пропускает пакет постоянно. Обновите его вручную. Открытые случаи показывает вот эта команда:
find /etc -type f \( -name "*.dpkg-dist" -o -name "*.dpkg-new" -o -name "*.ucf-dist" \)
Cache has broken packages, exiting в журнале
От более раннего действия осталось незавершённое состояние. apt --fix-broken install, затем dpkg --configure -a. До тех пор автоматика каждую ночь ничего не делает.
Ваши настройки не действуют, и никакого сообщения об ошибке нет.
Это признак пропущенного имени файла. Проверьте через apt-config dump | grep -i unattended, были ли значения прочитаны.
Automatic-Reboot "true" в Debian ничего не даёт.
Там нет файла-признака /var/run/reboot-required.
Сравнение четырёх систем
| Система | Пакет по умолчанию | Ключ для источников | Источник безопасности | Файл-признак для перезагрузки |
|---|---|---|---|---|
| Debian 13 (trixie) | нет, нужно доустановить | Origins-Pattern | trixie-security, метка Debian-Security | не создаётся |
| Debian 12 (bookworm) | нет, нужно доустановить | Origins-Pattern | bookworm-security, метка Debian-Security | не создаётся |
| Ubuntu 24.04 LTS | да, в серверных образах включён | Allowed-Origins | noble-security | /var/run/reboot-required |
| Ubuntu 22.04 LTS | да, в серверных образах включён | Allowed-Origins | jammy-security | /var/run/reboot-required |
Чего автоматика не делает
- Не переводит систему на новую основную версию и не трогает сторонние источники, пока для них не внесён шаблон.
- Ничего за пределами системы управления пакетами. Распакованные вручную программы, расширения системы управления сайтом, плагины игрового сервера и контейнеры продолжают работать в своём прежнем состоянии.
- Не заменяет резервное копирование и мониторинг. Обновление может остановить службу, и если никто не смотрит, она простоит до утра.
- Не защищает от сетевых атак. Актуальные пакеты закрывают известные уязвимости, а против объёмных атак помогает только фильтрация в сети перед сервером, у KernelHost в дата-центре maincubes во Франкфурте-на-Майне.
Итоговая проверка
apt-config dump APT::PeriodicвыводитUpdate-Package-Lists "1"иUnattended-Upgrade "1".apt-config dump | grep "^Unattended-Upgrade::"показывает ваши собственные значения.systemctl list-timers 'apt-daily*' --allпоказывает оба таймера с правдоподобным столбцомNEXT.unattended-upgrade --dry-run --debugпроходит без ошибок и называет ожидаемые источники.tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.logпосле первого запуска содержит запись с датой.ls -l /var/run/reboot-requiredв Ubuntu,needrestart -bв Debian.
Пятый пункт действительно важен, и он требует суток терпения: всё, что было до него, это подготовка, а доказательством служит только запись, появившаяся сегодня ночью.
Частые вопросы
Действительно ли unattended-upgrades ставит только обновления безопасности?
Я установил пакет, а ничего всё равно не происходит. В чём дело?
В какое время запускается обновление?
Я поставил Automatic-Reboot в true, но сервер на Debian всё равно никогда не перезагружается. Почему?
Стоит ли включать автоматическую перезагрузку на игровом сервере?
Как исключить отдельный пакет из автоматических обновлений?
В журнале написано «No packages found that can be upgraded unattended», хотя apt показывает обновления. Это ошибка?
Почему systemctl status unattended-upgrades постоянно показывает «active (running)»?
2026 KernelHost GmbH. Все права защищены. Эта инструкция охраняется авторским правом. Публикация на других сайтах, в том числе частично или в изменённом виде, без нашего письменного согласия не разрешается. Цитирование с указанием источника и активной ссылкой мы приветствуем.

