Пакетный менеджер — главный инструмент администратора Linux. Через него ставится ПО, приходят исправления безопасности, и именно из-за него случаются неприятные сюрпризы: обновился драйвер, подтянулась новая мажорная версия базы данных, исчез нужный пакет из репозитория. В этой статье разберём apt (Debian, Ubuntu) и dnf (Rocky, AlmaLinux, RHEL), научимся находить, откуда пришёл пакет, фиксировать версии, подключать сторонние репозитории и поднимать свой собственный на srv-backup01 (192.168.10.30) для хостов домена itpages.lab.local.

Команды выполняются от root. Примеры проверены на Debian 12 и Rocky Linux 9.

Основные операции в apt и dnf

Повседневный набор команд

Команды в двух семействах похожи по смыслу, но отличаются в деталях. Ниже сводка того, что нужно чаще всего:

# Debian / Ubuntu
apt update
apt list --upgradable
apt install nginx
apt remove nginx          # оставляет конфиги
apt purge nginx           # удаляет и конфиги
apt autoremove --purge
apt search prometheus
apt show nginx

# Rocky / AlmaLinux
dnf check-update
dnf install nginx
dnf remove nginx
dnf autoremove
dnf search prometheus
dnf info nginx

Обрати внимание на различие: apt update только обновляет списки пакетов, а ничего не устанавливает. Реальное обновление — это apt upgrade или apt full-upgrade (последняя может удалять пакеты ради разрешения зависимостей). В dnf индекс обновляется автоматически, а dnf upgrade делает всё сразу.

Кто владеет файлом и откуда пакет

Этот набор вопросов возникает при любой диагностике:

# Debian
dpkg -S /usr/sbin/nginx
dpkg -L nginx | head
apt policy nginx
apt-cache rdepends --installed nginx

# Rocky
rpm -qf /usr/sbin/nginx
rpm -ql nginx | head
dnf repoquery --installed --whatrequires nginx
dnf provides '*/bin/dig'

Команда apt policy особенно полезна: она показывает установленную и доступную версии, а также из каких репозиториев они пришли и с каким приоритетом. Когда обновление не ставится или приходит «не оттуда», начинай с неё.

История и откат

В dnf есть история транзакций с возможностью отмены, в apt откат придётся делать вручную по журналам:

# dnf
dnf history
dnf history info 12
dnf history undo 12

# apt
grep -E 'Start-Date|Commandline|Upgrade' /var/log/apt/history.log | tail -20
apt install nginx=1.22.1-9      # вернуть конкретную версию
apt list -a nginx

Команда apt list -a покажет все версии, доступные в подключённых репозиториях. Если нужной нет, остаётся кэш /var/cache/apt/archives или snapshot-сервис Debian для старых версий.

Фиксация версий

Зачем и как

Иногда пакет нельзя обновлять: приложение работает только с определённой версией PostgreSQL, ядро совместимо с проприетарным модулем, а в новой версии ПО изменился формат конфигурации. Тогда версию фиксируют.

# apt
apt-mark hold nginx postgresql-15
apt-mark showhold
apt-mark unhold nginx

# dnf
dnf install python3-dnf-plugin-versionlock
dnf versionlock add nginx
dnf versionlock list
dnf versionlock delete nginx

На Rocky 9 плагин versionlock называется python3-dnf-plugin-versionlock. Заметь разницу в семантике: apt-mark hold блокирует любое изменение пакета, а versionlock запоминает конкретную версию. Если нужно просто исключить пакет из массовых обновлений, в dnf есть и более простой способ — параметр exclude=kernel* postgresql* в /etc/dnf/dnf.conf.

Приоритеты репозиториев: apt pinning

Тонкая настройка в Debian делается через pinning. Допустим, на srv-linux01 нужен свежий nginx из backports, а всё остальное должно остаться стабильным:

echo 'deb http://deb.debian.org/debian bookworm-backports main' > /etc/apt/sources.list.d/backports.list
cat > /etc/apt/preferences.d/nginx-backports <<'EOF'
Package: nginx nginx-*
Pin: release a=bookworm-backports
Pin-Priority: 600
EOF
apt update
apt policy nginx
apt install -t bookworm-backports nginx

По умолчанию backports имеют приоритет 100 и сами не ставятся; пин на 600 делает версии из backports предпочтительными только для nginx. Всегда смотри на результат через apt policy: если там не то, что ожидалось, значит, пин написан неверно.

Для критичных систем фиксируй не только версии, но и источники. Хорошая практика — держать список установленных пакетов в хранилище конфигураций:

dpkg --get-selections > /root/pkg-list-$(hostname).txt
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /root/pkg-list-$(hostname).txt

Сторонние репозитории

Подключение с проверкой подписи

Старый способ apt-key add считается устаревшим и небезопасным: ключ получал доверие ко всем репозиториям сразу. Современный подход — привязывать ключ к конкретному репозиторию через signed-by:

install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /etc/apt/keyrings/nginx.gpg
cat > /etc/apt/sources.list.d/nginx.sources <<'EOF'
Types: deb
URIs: http://nginx.org/packages/debian
Suites: bookworm
Components: nginx
Signed-By: /etc/apt/keyrings/nginx.gpg
EOF
apt update

Для dnf то же самое делается файлом в /etc/yum.repos.d/ с обязательными gpgcheck=1 и gpgkey=:

cat > /etc/yum.repos.d/nginx.repo <<'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
dnf clean all && dnf makecache
dnf repolist

Никогда не ставь gpgcheck=0 и не подключай репозитории случайных авторов командой вида «curl | bash». Репозиторий получает права root на твою систему при каждом обновлении. Перед подключением посмотри, кто его поддерживает, и проверь отпечаток ключа по официальной странице проекта.

Свой репозиторий на srv-backup01

Репозиторий deb через reprepro

Зачем он нужен? Чтобы раздавать внутренние пакеты (например, собранное приложение IT-Pages), а также держать зеркало нужных версий, которые не изменятся неожиданно. Начнём с Debian:

apt install -y reprepro nginx gnupg
gpg --quick-generate-key 'IT-Pages Repo <repo@itpages.lab.local>' ed25519 sign 3y
mkdir -p /srv/repo/deb/conf
cat > /srv/repo/deb/conf/distributions <<'EOF'
Origin: IT-Pages
Label: IT-Pages internal
Codename: bookworm
Architectures: amd64 source
Components: main
SignWith: repo@itpages.lab.local
EOF
reprepro -b /srv/repo/deb includedeb bookworm /root/build/itpages-app_1.4.0_amd64.deb
reprepro -b /srv/repo/deb list bookworm

Публичный ключ выгрузи командой gpg --export repo@itpages.lab.local > /srv/repo/deb/itpages.gpg и раздай каталог /srv/repo через nginx на внутреннем адресе 192.168.10.30. На клиентах подключение выглядит так же, как для любого стороннего репозитория, с Signed-By.

Репозиторий rpm через createrepo_c

dnf install -y createrepo_c nginx rpm-sign
mkdir -p /srv/repo/rpm/el9
cp /root/build/itpages-app-1.4.0-1.el9.x86_64.rpm /srv/repo/rpm/el9/
rpmsign --addsign /srv/repo/rpm/el9/*.rpm
createrepo_c /srv/repo/rpm/el9
cat > /etc/yum.repos.d/itpages.repo <<'EOF'
[itpages]
name=IT-Pages internal
baseurl=http://srv-backup01.itpages.lab.local/repo/rpm/el9
gpgcheck=1
repo_gpgcheck=0
gpgkey=http://srv-backup01.itpages.lab.local/repo/rpm/itpages.gpg
EOF
dnf makecache && dnf info itpages-app

Чтобы создать зеркало внешнего репозитория, пригодятся apt-mirror и reposync из dnf-utils. Зеркало потребует места (сотни гигабайт для полного дистрибутива), но даёт стабильность и независимость от внешнего интернета. Обновление зеркала раз в неделю удобно вешать на systemd-таймер, а в тестовой группе хостов сначала проверять новые пакеты.

На клиентах с внутренним адресом по HTTP полагайся на подписи пакетов, а не на сетевое доверие. Если планируешь отдавать репозиторий за пределы сегмента 192.168.10.0/24, включай HTTPS.

Чистота и безопасность системы пакетов

Проверка целостности и осиротевшие пакеты

# Debian
debsums -c 2>/dev/null | head
apt autoremove --purge -s | grep ^Remv
dpkg -l | grep '^rc'          # удалённые, но с конфигами
apt-get check

# Rocky
rpm -Va | grep -v '^.......T.' | head
dnf list extras
dnf needs-restarting -r
dnf clean packages

Команда debsums -c показывает файлы, изменённые относительно пакета, а rpm -Va делает то же для RPM. Неожиданные изменения в /usr/bin или /usr/sbin — повод разбираться, не взлом ли это. Команда dnf list extras выводит пакеты, которых нет ни в одном репозитории, то есть установленные вручную или из ушедших источников.

Если процессы продолжают использовать старые библиотеки после обновления, поможет проверка:

apt install -y needrestart && needrestart -r l
dnf needs-restarting -s

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

Практика сопровождения

Единый порядок обновлений на всех хостах

Чтобы флот из нескольких серверов не разъезжался по версиям, заведи простой регламент. Сначала новые пакеты ставятся на тестовый хост, затем на srv-linux01 как второстепенный, и только потом на srv-web01. Перед обновлением смотри список изменений: apt list --upgradable и apt changelog имя на Debian, а на Rocky — dnf updateinfo list security и dnf updateinfo info. Они показывают, какие обновления относятся к безопасности и какие уязвимости закрывают. Это помогает решить, что ставить немедленно, а что подождать окна обслуживания.

Кэш, место на диске и скорость

Менеджеры пакетов оставляют кэш, который со временем занимает гигабайты. Чисти его командами apt clean и dnf clean all. Если хостов много и все ходят за пакетами в интернет, поставь кэширующий прокси: apt-cacher-ng на srv-backup01 экономит канал, а для dnf достаточно общего зеркала. В /etc/apt/apt.conf.d/01proxy одна строка Acquire::http::Proxy "http://192.168.10.30:3142"; перенаправляет весь трафик через кэш. В dnf аналогичный параметр proxy= прописывается в dnf.conf. Побочный плюс: при недоступности внешних источников установка всё равно проходит из кэша.

Модули dnf и потоки

В Rocky 9 помимо обычных пакетов есть модульные потоки (module streams), например разные ветки PostgreSQL или nginx. Посмотреть и выбрать поток можно так:

dnf module list postgresql
dnf module enable postgresql:15
dnf module install postgresql:15/server
dnf module reset postgresql

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

Особенности безопасности цепочки поставки

Проверка пакетов перед установкой

Прежде чем ставить пакет из нового источника, посмотри его содержимое и скрипты. В deb-пакетах скрипты установки (preinst, postinst) выполняются от root, поэтому они способны на что угодно. Просмотр без установки делается так: apt download имя && dpkg-deb -I имя.deb && dpkg-deb -e имя.deb /tmp/ctl && cat /tmp/ctl/postinst. Для rpm аналогично работает rpm -qp --scripts файл.rpm. Привычка заглядывать в скрипты окупается при работе с неизвестными источниками.

Хранение собственных сборок

Если ты собираешь пакеты сам, соблюдай несколько правил: подписывай их отдельным ключом, не используй личный ключ администратора, храни закрытый ключ вне серверов репозитория и регулярно проверяй срок его действия. При смене ключа заранее раздай новый открытый ключ на все клиенты и только потом начинай подписывать им. Версионируй пакеты осмысленно: номер ревизии (1.4.0-2) должен расти при каждой пересборке, иначе клиенты не увидят обновление, а кэши смешают старые и новые файлы.

Наконец, держи под рукой список «что откуда пришло»: apt-cache policy для отдельных пакетов или dnf list installed --from-repo=itpages для всех пакетов из внутреннего репозитория. Такой инвентарь пригодится при аудите и при решении, какие хосты затронуты, если в одном из источников обнаружили проблему.

Частые ошибки и как их избежать

  • Подключение репозиториев без проверки подписи. Отключённый gpgcheck или устаревший apt-key дают стороннему источнику доверие ко всей системе. Привязывай ключи через signed-by, в dnf держи gpgcheck=1 и проверяй отпечаток ключа.
  • Бесконечный hold и забытые блокировки. Зафиксированный пакет перестаёт получать исправления безопасности, и через год ты запускаешь уязвимую версию. Записывай причину и дату фиксации, периодически смотри apt-mark showhold и dnf versionlock list.
  • Смешивание версий дистрибутива. Добавление репозитория от другой версии (например, Ubuntu или Debian testing в Bookworm) превращает систему в кашу зависимостей. Проверяй apt policy и dnf repolist до установки, а пакеты из другого релиза ставь только через pinning или контейнеры.

Что дальше

Администрирование Linux — это набор связанных навыков, вот соседние темы серии: