Настраиваем автоматическое обновление при помощи Unattended Upgrades в Debian / Ubuntu

  • Автор:

unattended-upgrades-000.pngРегулярное и своевременное обновление операционной системы является сегодня одной из наиболее важных задач обслуживания, особенно для тех систем, которые непосредственно доступны из сети интернет. Многие Linux-администраторы предпочитают выполнять это действие по старинке - вручную, но это не всегда удобно, особенно если серверов много. Сегодня мы рассмотрим каким образом можно автоматизировать этот процесс, при этом, не теряя нужного уровня контроля над системой.

Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Система автоматических обновлений давно знакома пользователям Windows и далеко не всегда с самой лучшей стороны. Пользователи Linux, а особенно администраторы обычно предпочитают обновлять свои системы вручную, но этот подход нельзя признать современным. Количество угроз и уязвимостей только растет, при этом скорость и масштаб их эксплуатации порой становится действительно пугающим. Поэтому любое ПО, содержащее уязвимости, является серьезной угрозой, сейчас мы уже не говорим "если", а говорим "когда", потому что атака на такую систему - это вопрос времени.

Обновлять системы вручную можно если у вас немного серверов и есть достаточное количество свободного времени, в остальных случаях лучше доверить это дело автоматике, а самому заняться более интересными и полезными делами. Основные аргументы противников автоматического обновления разбиваются о существующую практику - Debain и Ubuntu LTS стабильны и надежны и такой процесс как обновление давно не вызывает каких-либо затруднений. Тем более что большинство обновляют системы вручную командами вроде:

apt update -y && apt full-upgrade -y && apt autoremove -y

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

Для автоматизации процесса установки обновлений в системах основанных на Debian разработан механизм Unattended Upgrades, который позволяет не только избавиться от ручной работы, но и достаточно тонко настроить всю эту процедуру, ведь Linux всегда оставляет последнее слово за администратором системы и не склонен своевольничать.

Установка и настройка Unattended Upgrades

Все, что будет изложено ниже одинаково подходит для любой системы на базе Debian, но есть некоторые отличия, например, в Ubuntu пакет unattended-upgrades может быть уже установлен и все что вам останется - это настроить его под собственные потребности. Поэтому действия по его установке можно пропустить, хотя если вы их все-таки выполните - хуже не будет. Все приведённые ниже действия следует выполнять от имени суперпользователя или через sudo.

Для установки выполните:

apt install unattended-upgrades

Затем, для создания первоначальной конфигурации, введите следующую команду:

dpkg-reconfigure -plow unattended-upgrades

После чего будут созданы и заполнены все необходимые конфигурационные файлы.

unattended-upgrades-001.png

Затем перейдем в /etc/apt/apt.conf.d и откроем файл 50unattended-upgrades, который содержит основные настройки автоматического обновления. Самый первый и важный вопрос - какие именно обновления мы будем скачивать и устанавливать. Для этого нам нужно указать соответствующие репозитории, более подробно о них вы можете прочитать в нашей статье: Linux - начинающим. Часть 5. Управление пакетами в Debian и Ubuntu.

В Debian, если отбросить комментарии, мы увидим следующий список:

Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};

Что это и откуда взято? Это описания репозиториев, в минимальном варианте нам нужно указать origin - источник и кодовое имя дистрибутива - codename, в его качестве используется переменная ${distro_codename}, которая вернет имя дистрибутива, так для Debian 11 это будет bullseye. Для origin тоже можно использовать переменную ${distro_id}, так, например, сделано в Ubuntu.

В зависимости от структуры организации репозиториев может потребоваться также указать метку - label, это используется в Deban, в Ubuntu достаточно источника и кодового имени. На первый взгляд сложно и есть где запутаться, но только на первый взгляд. Все системные репозитории уже перечислены в конфигурационном файле, только часть из них закомментирована. Поэтому добавлять самим ничего не нужно, достаточно только отредактировать блок.

unattended-upgrades-002.pngИ все-таки, откуда взяты все эти параметры? Для их получения выполните команду:

apt-cache policy

unattended-upgrades-003.pngЗдесь все достаточно просто: o - origin, n - codename, l - label. Теперь нам не составит труда подключить даже сторонний репозиторий, скажем Nginx, для этого в блок Unattended-Upgrade::Origins-Pattern потребуется добавить строку:

"origin=nginx,codename=${distro_codename}";

Следующая опция позволяет задать "черный список" - исключения для пакетов, которые не должны обновляться в автоматическом режиме. Обратите внимание, данная настройка касается только Unattended Upgrades, при ручном запуске обновления данные пакеты будут обновлены. Все параметры опции неплохо описаны в конфигурационном файле и проиллюстрированы примерами. Но все равно немного коснемся синтаксиса. Например, мы создали следующие записи:

Unattended-Upgrade::Package-Blacklist {
"linux-";
"libc6$";
};

Начнем с того, что каждая запись является регулярным выражением, а следовательно, маской, с которой будут сравниваться имена существующих пакетов. Так первая запись исключит из обновляемых все пакеты, которые начинаются на linux-, а вторая только пакет libc6, потому что в конце мы поставили знак явного окончания строки - $, если бы этого не сделали, то libc6 рассматривалась бы как маска и под нее попали бы все пакеты имеющие эту строку в начале, такие как libc6-dev, libc6-amd64 и т.д. и т.п.

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

Грамотное сочетание указанных выше опций позволяет достаточно гибко настроить процесс автоматического обновления согласно индивидуальным предпочтениям и обновлять не только стандартные пакеты, но и пакеты из сторонних репозиториев, в т.ч. собственных. А исключения помогут сохранить контроль над потенциально опасными ситуациями, которые администратор предпочитает контролировать вручную, скажем обновления ядра.

Идем дальше, часть рассматриваемых ниже опций может быть закомментирована, поэтому если вы хотите их использовать, то их следует раскомментировать и установить нужное значение. Опции перечислены в порядке их следования в файле.

Если при попытке обновления возникают ошибки, то система может попытаться их исправить, для этого установите в true следующий параметр:

Unattended-Upgrade::AutoFixInterruptedDpkg "true";

Фактически ее установка будет приводить к запуску команды:

dpkg --force-confold --configure -a

Т.е. ничего необычного она не делает, а указанная выше команда часто используется при появлении проблем с неправильно установленными пакетами или нарушенными зависимостями и обычно она хорошо справляется со своими задачами. Но на наш взгляд такая ситуация является потенциально опасной и лучше оставить ее для ручного разрешения администратором.

Следующая опция позволяет разделить обновления на минимально возможные порции, чтобы из всегда можно было прервать при помощи SIGTERM. Это замедляет процесс, но делает его более безопасным и позволяет спокойно выключить компьютер в процессе обновления, например, по сигналу источника бесперебойного питания.

Unattended-Upgrade::MinimalSteps "true";

Автоматическое обновление производится по умолчанию в фоновом режиме, можно изменить такое поведение и устанавливать обновления при выключении компьютера, данная опция может быть полезна при обслуживании рабочих станций, для серверов это, наоборот, может сослужить дурную службу, так как вместо быстрой перезагрузки вы можете получить продолжительный процесс обновления.

Unattended-Upgrade::InstallOnShutdown "true";

Любая автоматизированная система должна уметь уведомлять о результатах своей работы, традиционным каналом для уведомлений является электронная почта. Укажем адрес для получения сообщений:

Unattended-Upgrade::Mail "admin@examlpe.com";

Теоретически Linux умеет сам отправлять почту и для этого не нужно сложных настроек, но фактически большинство современных почтовых систем будут отклонять такую почту как нежелательные сообщения, настройка же полноценного почтового сервера ради нескольких уведомлений явно не имеет никакого смысла, поэтому для отправки почты проще использовать внешние почтовые сервисы. Для этого укажем от имени кого системе следует отправлять почту, используйте свой адрес в публичной почтовой системе, через которую вы хотите работать. Следующую опцию в файл следует добавить:

Unattended-Upgrade::Sender "my_account@gmail.com";

Теперь укажем, какие именно уведомления мы хотим получать, доступны три варианта: always - всегда, only-on-error - только при ошибках или on-change - при изменениях (т.е. если были обновления). На наш взгляд наиболее удобный вариант - сообщать только об ошибках, так как в противном случае внимание через некоторое время притупляется и действительно важное сообщение можно пропустить.

Unattended-Upgrade::MailReport "only-on-error";

Будем ли мы автоматически удалять старые ядра и связанные с ними пакеты? Конечно, да, особенно если у вас отдельный /boot небольшого размера.

Unattended-Upgrade::Remove-Unused-kernel-Packages "true";

Следующие две опции указывают что делать с неиспользуемыми пакетами, которые были установлены автоматически. Первая из них подразумевает удаление только новых неиспользуемых пакетов, которые возникли после обновления:

Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

Вторая подразумевает удаление всех неиспользуемых пакетов, в том числе возникших после действий пользователя:

Unattended-Upgrade::Remove-Unused-Dependencies "true";

По своему действию она аналогична команде:

apt autoremove

Вы должны выбрать какую-либо одну из них.

Если обновления предполагают перезагрузку (например, пришло новое ядро), то можно разрешить автоматически перезагружать систему, для этого используйте опцию:

Unattended-Upgrade::Automatic-Reboot "true";

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

Unattended-Upgrade::Automatic-Reboot-WithUsers "true";

Ну и наконец имеется возможность указать время перезагрузки:

Unattended-Upgrade::Automatic-Reboot-Time "02:00";

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

dpkg-reconfigure tzdata

Остальные опции файла мы рассматривать не будем, они не являются критически важными и касаются ограничения скорости скачивания обновлений и логирования, в подавляющем большинстве случаев их можно оставить по умолчанию, тем не менее они отлично прокомментированы и разобраться с ними самостоятельно не должно составить труда.

Сохраним изменения конфигурации и откроем второй конфигурационный файл /etc/apt/apt.conf.d/20auto-upgrades, который отвечает за периодичность обновлений. По умолчанию в нем присутствуют две опции:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

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

Также вам может быть интересна опция, позволяющая только скачивать обновления, без их установки:

APT::Periodic::Download-Upgradeable-Packages "1";

С ее помощью вы можете организовать только скачивание обновлений, оставив их установку за администратором.

Для очистки кеша скачанных пакетов используйте следующую настройку:

APT::Periodic::AutocleanInterval "7";

В данном случае период очистки установлен как 7 дней.

Как видим, Unattended Upgrades позволяет достаточно гибко настроить процесс обновления, контролируя все его этапы от и до с нужной степенью автоматизации, в зависимости от собственных предпочтений.

Настройка отправки уведомлений через публичные почтовые службы

Как мы уже говорили выше отправка почты средствами самого сервера в настоящее время не оправдана, без серьезных настроек, в том числе и внешних сервисов (DNS-записи), такая почта будет очень многими получателями восприниматься как нежелательная, поэтому мы будем использовать публичные почтовые службы, также можно использовать собственный почтовый сервер.

Для этого установим SMTP-клиент, который прозрачно заменяет sendmail и позволяет отправлять системную почту через внешний почтовый сервер:

apt install ssmtp mailutils

Затем откроем файл /etc/ssmtp/ssmtp.conf и приступим к редактированию параметров, благо их немного.

Сначала укажем получателя для системной почты (все пользователи с идентификаторами < 1000):

root = admin@examlpe.com

Если вы не хотите выполнять перенаправление, то оставьте эту опцию пустой.

Разрешим изменять отправителя в поле From, для этого раскомментируйте и приведите к следующему виду опцию:

FromLineOverride=YES

Если этого не сделать, то система будет отправлять письма от имени root@hostname, которые будут отклоняться почтовым сервером.

В некоторых случаях вам потребуется правильно указать в опции hostname имя хоста, желательно FQDN, но в большинстве случаев все работает с автоматически подставленным туда значением.

Это были общие параметры, а теперь настроим работу с конкретными почтовыми службами.

Начнем с почтового сервиса Google:

mailhub=smtp.gmail.com:587

AuthUser=my_account@gmail.com
AuthPass=mY_pa$$word_1
UseTLS=YES
UseSTARTTLS=YES
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt

Настройки достаточно простые и не требуют подробных пояснений. В опции mailhub указываем адрес и порт почтового сервера, ниже идут учетные данные и параметры шифрования.

Для того, чтобы вы могли выполнять отправку почты вам также потребуется разрешить доступ ненадежным приложениям в настройках Аккаунта Google.

unattended-upgrades-004.pngЕсли ограничиться отправкой сообщений от Unattended Upgrades, то на этом настройку можно закончить, но мы советуем еще создать алиасы для системных пользователей, чтобы с почтой могли работать и другие службы. Для этого откроем /etc/ssmtp/revaliases и внесем туда следующую строку:

root:my_account@gmail.com:smtp.gmail.com:587

Это означает что пользователю root соответствует аккаунт my_account@gmail.com на сервере smtp.gmail.com:587 и отправку почты следует производить через него.

Для почты Яндекса настройки будут немного другие:

mailhub=smtp.yandex.ru:465

AuthUser=my_account@yandex.ru
AuthPass=mY_pa$$word_1
UseTLS=YES
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt

Если же вы используете Яндекс ПДД (она же Яндекс Коннект или Яндекс 360 для бизнеса) то настраивать соединение следует так:

mailhub=smtp.yandex.ru:587

AuthUser=my_account@example.com
AuthPass=mY_pa$$word_1
UseTLS=YES
UseSTARTTLS=YES
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt

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

Для проверки почты выполните:

echo "Test" | mail  -s "Test" admin@example.com

Если все сделано правильно, то вы получите на указанный ящик письмо с темой Test и таким же текстом. Обратите внимание, что для проверки мы использовали системную команду mail, что позволяет быть уверенным, что с почтой смогут успешно работать любые службы.

В случае ошибки полезно будет выполнить отладку с получением логов обмена с почтовым сервером, для этого немного изменим команду отправки почты:

 echo "Test" | ssmtp -v -s "Test" admin@example.com

Теперь весь обмен с сервером как на ладони, что позволяет быстро найти и исправить возможные ошибки настройки.

Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Поддержи автора и новые статьи будут выходить чаще:

Поддержи проект!

Или подпишись на наш Телеграм-канал: Подпишись на наш Telegram-канал



Loading Comments