Автоматические обновления безопасности: настройка unattended-upgrades

Опубликовано 14 мин. чтения

Как настроить unattended-upgrades так, чтобы механизм действительно работал: разрешённые источники, исключённые пакеты, поведение при перезагрузке, отчёт на почту и доказательство в журнале, что ночью что-то произошло.

Между выходом обновления безопасности и его установкой на большинстве серверов остаётся зазор. Возникает он редко из-за небрежности, чаще из-за того, что кто-то собирается заняться этим «на следующей неделе». Сканеры перебирают ставшую известной уязвимость в течение нескольких часов. Пакет unattended-upgrades этот зазор закрывает.

Краткая версия описана как шаг 7 в чек-листе для нового root-сервера. Здесь речь идёт обо всём, что следует дальше: обновления безопасности против всех обновлений подряд, поведение при перезагрузке на игровом сервере, уведомления на почту, исключённые пакеты, пробный прогон и подтверждение в журнале.

Проверено на Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS и Ubuntu 22.04 LTS. Там, где эти четыре системы расходятся, об этом сказано отдельно. Команды рассчитаны на работу от имени root. Если вы работаете под обычным пользователем, добавляйте перед каждой из них sudo.

Что здесь на самом деле происходит

Поиск неисправностей затягивается именно потому, что непонятно, какая из трёх участвующих частей делает не то, что от неё ждут:

  1. Два таймера systemd: apt-daily.timer отвечает за списки пакетов и скачивание, apt-daily-upgrade.timer за установку.
  2. Скрипт /usr/lib/apt/apt.systemd.daily, который разбирает параметры из раздела APT::Periodic::.
  3. Программа 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-Patterntrixie-security, метка Debian-Securityне создаётся
Debian 12 (bookworm)нет, нужно доустановитьOrigins-Patternbookworm-security, метка Debian-Securityне создаётся
Ubuntu 24.04 LTSда, в серверных образах включёнAllowed-Originsnoble-security/var/run/reboot-required
Ubuntu 22.04 LTSда, в серверных образах включёнAllowed-Originsjammy-security/var/run/reboot-required

Чего автоматика не делает

  • Не переводит систему на новую основную версию и не трогает сторонние источники, пока для них не внесён шаблон.
  • Ничего за пределами системы управления пакетами. Распакованные вручную программы, расширения системы управления сайтом, плагины игрового сервера и контейнеры продолжают работать в своём прежнем состоянии.
  • Не заменяет резервное копирование и мониторинг. Обновление может остановить службу, и если никто не смотрит, она простоит до утра.
  • Не защищает от сетевых атак. Актуальные пакеты закрывают известные уязвимости, а против объёмных атак помогает только фильтрация в сети перед сервером, у KernelHost в дата-центре maincubes во Франкфурте-на-Майне.

Итоговая проверка

  1. apt-config dump APT::Periodic выводит Update-Package-Lists "1" и Unattended-Upgrade "1".
  2. apt-config dump | grep "^Unattended-Upgrade::" показывает ваши собственные значения.
  3. systemctl list-timers 'apt-daily*' --all показывает оба таймера с правдоподобным столбцом NEXT.
  4. unattended-upgrade --dry-run --debug проходит без ошибок и называет ожидаемые источники.
  5. tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.log после первого запуска содержит запись с датой.
  6. ls -l /var/run/reboot-required в Ubuntu, needrestart -b в Debian.

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

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

Действительно ли unattended-upgrades ставит только обновления безопасности?
В настройках по умолчанию да. В Debian этим управляет Unattended-Upgrade::Origins-Pattern, в Ubuntu Unattended-Upgrade::Allowed-Origins. По умолчанию активны шаблоны для источника безопасности и для основного архива вашего собственного выпуска, а дополнительные наборы -updates, -proposed и -backports стоят там закомментированными. Что действует на самом деле, показывает пробный прогон unattended-upgrade --dry-run --debug в строке «Allowed origins are:», а вовсе не взгляд в файл конфигурации.
Я установил пакет, а ничего всё равно не происходит. В чём дело?
Почти всегда в том, что отсутствует файл /etc/apt/apt.conf.d/20auto-upgrades. Установка пакета сама по себе ничего не включает, это делает только он, строками APT::Periodic::Update-Package-Lists "1" и APT::Periodic::Unattended-Upgrade "1". В Debian этот файл не появляется, если установка шла не в интерактивном режиме, например при сборке образа. Наверстать упущенное можно командой dpkg-reconfigure -plow unattended-upgrades. Проверяется всё через apt-config dump APT::Periodic: если вывода нет вообще, значит ни один файл прочитан не был.
В какое время запускается обновление?
Этим управляет apt-daily-upgrade.timer. По умолчанию там стоит OnCalendar=*-*-* 6:00 вместе с RandomizedDelaySec=60m, то есть запуск приходится куда-то между шестью и семью часами утра. У apt-daily.timer, который забирает списки пакетов, разброс составляет двенадцать часов. Сдвинуть время можно через systemctl edit apt-daily-upgrade.timer, причём перед вашим собственным значением обязательно должна стоять пустая строка OnCalendar=, иначе таймер сработает дважды в сутки.
Я поставил Automatic-Reboot в true, но сервер на Debian всё равно никогда не перезагружается. Почему?
Потому что перезагрузку запускает не пакет ядра, а файл-признак /var/run/reboot-required. Ubuntu его создаёт, там он приходит из пакета update-notifier-common, а /var/run/reboot-required.pkgs называет даже ответственные пакеты. Debian по умолчанию его не создаёт, поэтому параметр там остаётся без действия, и ни о какой ошибке при этом не сообщается. В Debian необходимость перезагрузки проверяют командой needrestart -b и сравнивают NEEDRESTART-KCUR с NEEDRESTART-KEXP.
Стоит ли включать автоматическую перезагрузку на игровом сервере?
Лучше не стоит. На игровом сервере подключены игроки, мир лежит в оперативной памяти, а сохранение записывается полностью только при штатном завершении. Если процесс завершат жёстко, после того как истечёт срок остановки systemd, вы потеряете весь прогресс с момента последнего автосохранения либо получите повреждённый файл мира. Разумно поставить Automatic-Reboot "false", объявлять окно обслуживания заранее и оформить unit systemd с сохраняющей командой остановки и достаточным TimeoutStopSec.
Как исключить отдельный пакет из автоматических обновлений?
Есть два пути с разным охватом. Unattended-Upgrade::Package-Blacklist действует только на автоматику; записи там регулярные выражения, привязанные к началу имени пакета, поэтому "nginx" попадает ещё и в nginx-common и в nginx-full, а "nginx$" означает ровно это одно имя. apt-mark hold, наоборот, действует на любой вызов apt, то есть и на ваш ручной apt upgrade. И то и другое стоит себе записать: исключённый пакет вам придётся обновлять самостоятельно.
В журнале написано «No packages found that can be upgraded unattended», хотя apt показывает обновления. Это ошибка?
Нет, это работа фильтра. Пакет, который есть в apt list --upgradable и отсутствует в пробном прогоне, приходит из неразрешённого источника, стоит в списке исключений, придержан через apt-mark hold или вызвал бы вопрос о файле конфигурации. Последний случай видно в журнале по строке «has conffile prompt and needs to be upgraded manually», и он действует на пакет постоянно, пока вы не обновите его вручную.
Почему systemctl status unattended-upgrades постоянно показывает «active (running)»?
Это не идущее обновление. Задача этого unit в том, чтобы аккуратно завершить начатый запуск при выключении системы, а всё остальное время он ждёт. Устанавливается всё в apt-daily-upgrade.service, и эта служба работает лишь несколько минут в сутки. Что произошло на самом деле, вы прочитаете в /var/log/unattended-upgrades/unattended-upgrades.log и в /var/log/apt/history.log.

unattended-upgrades Обновления безопасности apt Debian Ubuntu Безопасность сервера systemd root-сервер