С чего начать Первые шаги трек · 15 ступеней
Linux Labs

unattended-upgrades: обновления безопасности без участия человека

10 мин Ubuntu 24.04 · unattended-upgrades 2.9 · needrestart 3.6

Служба Ubuntu: раз в сутки по таймеру apt ставит обновления из разрешённых источников, по умолчанию — только security.

Шпаргалка

7 команд Версия для печати
  • systemctl list-timers 'apt-daily*' когда следующий запуск
  • cat /etc/apt/apt.conf.d/20auto-upgrades включены ли
  • apt-config dump | grep -E '^APT::Periodic|^Unattended-Upgrade::'
  • sudo unattended-upgrade --dry-run -v что поставил бы сейчас
  • sudo ls /var/log/unattended-upgrades/ журналы запусков
  • sudo needrestart -b кому нужен перезапуск
  • ls /var/run/reboot-required нужна ли перезагрузка

Обзор

unattended-upgrades ставит обновления без человека. Запускают его таймеры apt:

Шаг Таймер → служба Что делает
1 apt-daily.timer → apt-daily.service раз в сутки обновляет списки пакетов, как apt update
2 apt-daily-upgrade.timer → apt-daily-upgrade.service в 6:00 плюс до 60 минут случайно запускает unattended-upgrade
3 хук DPkg::Post-Invoke в 99needrestart после установки перезапускает службы со старыми файлами
text
student@ubuntu:~$ systemctl cat apt-daily-upgrade.timer \
> | grep -E 'OnCalendar|Randomized|Persistent'
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true

Persistent=true — если машина была выключена в 6:00, запуск пройдёт после загрузки. Служба unattended-upgrades.service («Unattended Upgrades Shutdown») обновления не ставит: она ждёт выключения машины, чтобы не оборвать начатую установку.

Шаги 1 и 2 включает файл 20auto-upgrades, число — интервал в днях:

text
student@ubuntu:~$ cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

На учебной машине (unattended-upgrades 2.9.1) 20auto-upgrades включает оба шага, но таймеры и служба выключены (disabled), а сети нет. В старых списках пакетов полторы сотни обновлений, больше сотни из них — из noble-security, и пробный запуск падает на скачивании:

text
student@ubuntu:~$ sudo unattended-upgrade --dry-run -v
Could not figure out development release: Distribution data outdated.
  Please check for an update for distro-info-data. See
  /usr/share/doc/distro-info-data/README.Debian for details.
Starting unattended upgrades script
Allowed origins are: o=Ubuntu,a=noble, o=Ubuntu,a=noble-security,
  o=UbuntuESMApps,a=noble-apps-security,
  o=UbuntuESM,a=noble-infra-security
Initial blacklist:
Initial whitelist (not strict):
The URI http://security.ubuntu.com/ubuntu/pool/main/u/util-linux/
  bsdutils_2.39.3-9ubuntu6.6_amd64.deb failed to download, aborting

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

Что ставится

Источники — список Allowed-Origins в 50unattended-upgrades. Пакет ставится, если его источник (o= — кто выпустил, a= — ветка архива) совпал с одной из строк:

text
Unattended-Upgrade::Allowed-Origins {
	"${distro_id}:${distro_codename}";
	"${distro_id}:${distro_codename}-security";
	"${distro_id}ESMApps:${distro_codename}-apps-security";
	"${distro_id}ESM:${distro_codename}-infra-security";
};

${distro_id}:${distro_codename} — сам выпуск noble, он после выхода не меняется. Строка -updates в файле закомментирована, поэтому по умолчанию приходят только обновления безопасности. Ветки ESM работают при подключённой подписке Ubuntu Pro.

Перезапуск после обновления

Обновление меняет файлы на диске. Работающая программа продолжает выполнять старые: её файл удалён, но открыт, как удалённый открытый файл. Пока служба не перезапущена, исправление на неё не действует. Бинарь demo-sleep заменили новым, служба demo-old работает дальше:

text
student@ubuntu:~$ sudo lsof +L1
COMMAND    PID USER  FD   TYPE DEVICE SIZE/OFF NLINK NODE NAME
demo-slee 4214 root txt    REG  253,4    35336     0 4464
  /usr/local/bin/demo-sleep (deleted)
student@ubuntu:~$ sudo readlink /proc/4214/exe
/usr/local/bin/demo-sleep (deleted)

Так же остаётся в памяти старая общая библиотека — с пометкой (deleted) в /proc/<PID>/maps (см. proc-filesystem). После systemctl restart demo-old процесс запускается с нового файла, и пометка пропадает.

Ядро перезапуском служб не обновить. Пакет, которому нужна перезагрузка, создаёт файл /var/run/reboot-required; сама машина перезагрузится, только если включён Automatic-Reboot.

needrestart

needrestart находит процессы со старыми файлами и называет их службы. Режим задаёт -r: l — только список, a — перезапустить, i — спросить. -b печатает строки для скриптов:

text
student@ubuntu:~$ sudo needrestart -b
NEEDRESTART-VER: 3.6
NEEDRESTART-KCUR: 6.8.0-124-generic
NEEDRESTART-KEXP: 6.8.0-124-generic
NEEDRESTART-KSTA: 1
NEEDRESTART-SVC: demo-old.service
student@ubuntu:~$ sudo needrestart -r l
Running kernel seems to be up-to-date.

Services to be restarted:
 systemctl restart demo-old.service

KCUR — работающее ядро, KEXP — новейшее установленное, KSTA: 1 — они совпадают, перезагрузка не нужна. SVC — служба для перезапуска.

В Ubuntu needrestart вызывается хуком apt после каждой установки и по умолчанию перезапускает службы сам — так сказано в /etc/needrestart/needrestart.conf:

text
# UBUNTU: the default restart mode when running as part of the APT
# hook is 'a', unless a specific UI is configured (see below).

Часть служб он не трогает даже в режиме a: их список — ключ $nrconf{override_rc}. Такие службы попадают в отдельный список:

text
student@ubuntu:~$ sudo needrestart -r a
Running kernel seems to be up-to-date.
Restarting services...
Service restarts being deferred:
 systemctl restart demo-lib.service

Здесь demo-lib отложена строкой в /etc/needrestart/conf.d/demo.conf:

text
$nrconf{override_rc}{qr(^demo-lib)} = 0;

Отложенную службу перезапускают руками, когда это безопасно.

Журналы

Каталог /var/log/unattended-upgrades/ читают root и группа adm:

Файл Что в нём
unattended-upgrades.log какие пакеты поставлены и почему другие пропущены
unattended-upgrades-dpkg.log вывод dpkg при установке
unattended-upgrades-shutdown.log работа службы при выключении

На учебной машине каталог пуст: обновление ни разу не запускалось, а служба unattended-upgrades.service выключена. Запуски таймера видно в journalctl -u apt-daily-upgrade.

Конфигурация

8

Настройки — в формате apt в /etc/apt/apt.conf.d/. Файлы читаются по алфавиту: 20auto-upgrades — включатель, 50unattended-upgrades — что и как ставить. Свои значения удобно держать в отдельном файле с номером больше 50: обновление пакета может предложить заменить 50unattended-upgrades, а свой файл оно не тронет.

text
// /etc/apt/apt.conf.d/52unattended-upgrades-local
Unattended-Upgrade::Package-Blacklist { "postgresql-"; };
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";

Строка-значение из позднего файла заменяет прежнее, а элементы списка { … } добавляются к прежним. Итог видно в apt-config dump:

bash
apt-config dump | grep -E '^APT::Periodic|^Unattended-Upgrade::'

Главные ключи — в таблице директив ниже. В 50unattended-upgrades машины закомментированы Automatic-Reboot "false", Remove-Unused-Dependencies "false" и Mail "" — это и есть значения по умолчанию.

Директива Что делает Пример
APT::Periodic::Update-Package-Lists 20auto-upgrades Раз во сколько дней обновлять списки пакетов; 0 — не обновлять. APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade 20auto-upgrades Раз во сколько дней запускать unattended-upgrade; 0 — автообновлений нет. APT::Periodic::Unattended-Upgrade "1";
Unattended-Upgrade::Allowed-Origins 50unattended-upgrades Список источников «выпуск:ветка», из которых можно ставить пакеты; по умолчанию — только -security. Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security"; };
Unattended-Upgrade::Package-Blacklist 50unattended-upgrades Пакеты, которые не обновлять; имена — регулярные выражения. Unattended-Upgrade::Package-Blacklist { "postgresql-"; };
Unattended-Upgrade::Automatic-Reboot 50unattended-upgrades Перезагрузить машину, если обновлению она нужна (есть /var/run/reboot-required). Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time 50unattended-upgrades Время перезагрузки вместо «сразу после обновления». Unattended-Upgrade::Automatic-Reboot-Time "03:30";
Unattended-Upgrade::Remove-Unused-Dependencies 50unattended-upgrades Удалять зависимости, которые стали не нужны, как apt autoremove. Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Mail 50unattended-upgrades Адрес для отчёта о запуске; нужна работающая отправка почты на машине. Unattended-Upgrade::Mail "admin@example.org";

Ничего не найдено. Попробуй запрос короче.

Рецепты

3

Включено ли и когда сработает

bash
cat /etc/apt/apt.conf.d/20auto-upgrades
systemctl is-enabled apt-daily.timer apt-daily-upgrade.timer
systemctl list-timers 'apt-daily*'

Оба значения "1" и оба таймера enabled — обновления идут раз в сутки.

Отложить пакет

text
Unattended-Upgrade::Package-Blacklist { "nginx"; "postgresql-"; };

Имена — регулярные выражения: postgresql- ловит все пакеты с этим началом. Проверка — sudo unattended-upgrade --dry-run -v: в строке Initial blacklist: появятся эти имена.

Найти службы со старыми файлами

bash
sudo needrestart -r l          # список, ничего не перезапускает
sudo lsof +L1                  # все удалённые открытые файлы
sudo grep -l deleted /proc/[0-9]*/maps 2>/dev/null

Неполадки

4

Обновления не ставятся

  • В 20auto-upgrades стоит "0" или файла нет.
  • Таймер выключен: systemctl is-enabled apt-daily-upgrade.timer.
  • Нет сети: в журнале failed to download, aborting.
  • Пакет из источника вне Allowed-Origins или в Package-Blacklist.

Причину пропуска пакета пишет unattended-upgrades.log и --dry-run -v.

apt ждёт блокировку: (unattended-upgr)

apt пишет Could not get lock /var/lib/dpkg/lock-frontend. It is held by process … (unattended-upgr). Идёт плановая установка. Дождись её — systemctl status apt-daily-upgrade. Процесс dpkg, убитый посреди установки, оставляет пакеты недоустановленными.

Обновление поставлено, а уязвимость жива

Служба работает со старой копией файла: (deleted) в /proc/<PID>/maps, строка в lsof +L1, служба в needrestart -r l. Перезапусти её. Обновлено ядро — нужна перезагрузка: есть /var/run/reboot-required, uname -r старше установленного ядра.

Служба перезапустилась ночью сама

Её перезапустил needrestart после планового обновления. Время совпадает с запуском apt-daily-upgrade, пакеты — в unattended-upgrades-dpkg.log. Исключить службу можно в /etc/needrestart/conf.d/*.conf, ключ $nrconf{override_rc}.

Опасно

2

Automatic-Reboot "true" без своего времени

Без Automatic-Reboot-Time машина перезагрузится сразу после обновления, которому нужна перезагрузка, — посреди рабочего дня. Ставь время окна обслуживания.

Добавить -updates и чужие источники

Обновления безопасности меняют мало и редко ломают. Ветка -updates и сторонние репозитории приносят новые версии, и они встанут ночью без проверки. Такие источники обновляй руками.

См. также

  • apt — установка и обновление пакетов руками.
  • systemd-timers — как устроены таймеры apt-daily*.
  • lsof — lsof +L1 и удалённые открытые файлы.
  • proc-filesystem — /proc/<PID>/maps и exe.
  • systemctl — перезапуск служб.
  • kernel — новое ядро и перезагрузка.
Загрузка…