apt и репозитории
apt — front-end управления пакетами Debian. apt update обновляет локальный индекс; apt upgrade устанавливает новые версии; apt install скачивает и подключает пакет. Репозитории подписаны GPG — установка из неподписанного репозитория это решение о безопасности, а не опция.
Ты вводишь sudo apt install nginx — и через десять секунд nginx запущен. За этой одной командой: система скачала криптографически подписанный индекс пакетов с зеркала, разрешила граф зависимостей, загрузила три .deb-архива, распаковала их в правильном порядке, запустила post-install скрипты и зарегистрировала каждый файл в локальной базе. Когда что-то идёт не так — «package has unmet dependencies», «repository is not signed», «held broken packages» — тебе нужно понимать, какой слой отказал. Ответ почти всегда: либо индекс, либо подпись.
После этого урока ты сможешь объяснить разницу между apt и apt-get, управлять sources.list и новым форматом deb822, правильно запускать apt update перед apt upgrade, добавлять сторонний репозиторий с GPG-ключом и объяснять, почему установка из неподписанного репозитория является угрозой безопасности.
apt против apt-get: тот же движок, другой интерфейс. apt-get существует с 1998 года; apt добавили в 2014-м — для более красивого вывода и разумных умолчаний. Оба под капотом вызывают dpkg. Для скриптов используй apt-get — формат вывода стабилен между релизами. Для интерактивной работы используй apt.
# Интерактивное использование — apt
sudo apt update
sudo apt install nginx
sudo apt remove nginx
sudo apt autoremove # удалить пакеты, которые больше не нужны
# Скрипты — apt-get (стабильный, без цвета и индикаторов прогресса)
DEBIAN_FRONTEND=noninteractive apt-get install -y nginxКлючевой флаг для автоматизации — DEBIAN_FRONTEND=noninteractive — он подавляет интерактивные запросы (часовой пояс, раскладка клавиатуры), которые завесят CI-пайплайн. -y автоматически подтверждает установку. Без обоих флагов в Dockerfile сборка зависнет в ожидании ответа человека, которого нет.
apt update и apt upgrade — две разные операции, никогда не путай их. apt update скачивает индекс пакетов (список того, что доступно и в каких версиях) из каждого настроенного репозитория. Он ничего не устанавливает и не обновляет. apt upgrade читает локальный индекс и устанавливает новые версии уже установленных пакетов.
# Шаг 1: обновить локальный индекс
sudo apt update
# Шаг 2: установить обновления (использует свежий индекс)
sudo apt upgrade
# Частая ошибка: запустить upgrade без предшествующего update
# Это устанавливает «новые» версии по УСТАРЕВШЕМУ индексу —
# ты можешь пропустить критические патчи безопасности, вышедшие
# после последнего apt update.Запуск apt upgrade без предшествующего apt update — одна из самых распространённых ошибок безопасности на долго работающих серверах. Система выглядит «обновлённой», но на самом деле работает со списками пакетов месячной давности.
Источники репозиториев находятся в /etc/apt/sources.list и /etc/apt/sources.list.d/. Классический однострочный формат:
deb [signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stableПоля: deb (бинарные пакеты; deb-src для исходников), необязательные [опции], URL, suite (например jammy), компонент (например main universe).
Новый формат deb822 находится в /etc/apt/sources.list.d/*.sources:
# /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: jammy
Components: stable
Signed-By: /usr/share/keyrings/docker.gpg
Enabled: yesФормат deb822 читабельнее и проще отключается (Enabled: no) без удаления файла. Новые дистрибутивы (Debian 12+, Ubuntu 22.04+) предпочитают этот формат.
Репозитории должны быть подписаны. Неподписанные репозитории — это атака на цепочку поставок в ожидании своего часа. apt использует GPG для проверки того, что индекс пакетов и отдельные пакеты подписаны владельцем репозитория. Если ключ отсутствует или подпись не проходит, apt update отказывается доверять индексу:
# Ошибка при отсутствии ключа репозитория:
# W: GPG error: http://... Release: The following signatures
# couldn't be verified because the public key is not available:
# NO_PUBKEY 7EA0A9C3F273FCD8
# Добавить GPG-ключ правильным современным способом (не apt-key add — устарел)
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
# Затем сослаться на него в записи источника через signed-by=
# deb [signed-by=/usr/share/keyrings/docker.gpg] https://...apt-key add устарел, потому что добавлял ключи в глобальное доверенное хранилище, применявшееся ко ВСЕМ репозиториям. Скомпрометированный ключ одного репозитория мог подписывать пакеты для любого другого. Современный подход signed-by= ограничивает ключ одной записью репозитория.
Команды apt-cache позволяют запрашивать локальный индекс без установки. Разделение «поиск в индексе» и «установка» предотвращает классическую ошибку: устанавливать что-то только чтобы проверить, существует ли оно.
# Поиск пакетов по ключевому слову
apt-cache search nginx
# Показать версию, зависимости и описание
apt-cache show nginx
# Сравнить установленное с доступным
apt-cache policy nginx
# Вывод содержит:
# Installed: 1.18.0-6ubuntu14.4
# Candidate: 1.18.0-6ubuntu14.5 ← новая версия в индексе
# Version table: ...
# Найти пакет, которому принадлежит команда
dpkg -S /usr/bin/nginxapt-cache policy — самый быстрый способ проверить, нужен ли apt update: если candidate новее installed, индекс обновился, но ты ещё не выполнил upgrade.
Добавить репозиторий Docker CE на Ubuntu 22.04 и правильно установить Docker.
Свежий сервер Ubuntu 22.04. Задача: установить Docker CE из официального репозитория Docker, а не устаревший пакет docker.io из основного репозитория Ubuntu.
# 1. Установить зависимости для HTTPS-транспорта
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# 2. Скачать и сохранить GPG-ключ Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# 3. Добавить репозиторий в формате deb822
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 4. Обновить индекс, чтобы подхватить новый репозиторий
sudo apt update
# 5. Установить Docker CE (теперь из официального репозитория)
sudo apt install -y docker-ce docker-ce-cli containerd.ioКлючевые решения: шаг 2 ограничивает ключ репозиторием Docker через signed-by=. Шаг 3 использует VERSION_CODENAME вместо хардкода jammy — работает на будущих выпусках Ubuntu. Шаг 4 обязателен перед шагом 5: новый репозиторий не в индексе, пока apt update его не подтянет.
▸Частая ошибка
Распространённая ошибка — сразу после подготовки сервера из кастомного облачного образа запускать sudo apt upgrade. Облачные образы часто поставляются с закреплёнными версиями пакетов или удерживают определённые пакеты (например, ядро), чтобы избежать сюрпризов. Запуск apt upgrade без проверки apt-mark showhold может обновить удерживаемый пакет — это может сломать совместимость модулей ядра или спровоцировать незапланированную перезагрузку через needrestart. На production-серверах перед обновлением проверяй удержания и предпочитай apt-get upgrade --no-new-pkgs вместо apt-get dist-upgrade, если ты специально не хочешь подтягивать новые пакеты.
▸Почему это работает
Почему в Ubuntu есть компоненты main, universe, restricted и multiverse? Main = поддерживается Canonical, патчи безопасности гарантированы. Universe = поддерживается сообществом, безопасность по мере возможности. Restricted = проприетарные драйверы с официальной поддержкой. Multiverse = ПО с патентными или лицензионными ограничениями. Подключая universe, ты принимаешь, что Canonical не гарантирует обновления безопасности для этих пакетов. На сервере с публичными сервисами аудитируй установленные пакеты из universe: либо прими ответственность, либо найди альтернативы из main.
Ты запустил `sudo apt upgrade` на production-сервере и заметил, что установилась старая версия OpenSSL, в которой отсутствует критический патч CVE, вышедший на прошлой неделе. Какова наиболее вероятная причина?
apt — пользовательский front-end; apt-get — скрипт-стабильный вариант, оба вызывают dpkg под капотом. apt update обновляет локальный индекс пакетов из настроенных репозиториев; apt upgrade устанавливает новые версии, используя этот индекс — всегда выполняй их по порядку. Источники репозиториев находятся в /etc/apt/sources.list и .../sources.list.d/; формат deb822 предпочтителен на Ubuntu 22.04+. Каждый репозиторий должен быть подписан GPG; используй signed-by= для привязки ключа к одному репозиторию, никогда не используй apt-key add. Запуск apt upgrade на устаревшем индексе — главный способ думать, что ты защищён, не будучи им.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.