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

Цели аудита пакетов и каналы их накопления

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

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

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

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

Инвентаризация список вручную установленного и кандидатов

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

apt-mark showmanual

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

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

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

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

Осторожное удаление партиями с тестированием

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

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

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

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

Конфигурации удалённых пакетов это отдельное решение: сохранить или вычистить. Аккуратная практика сначала удаление с сохранением конфигураций, финальная чистка конфигураций по итогам партиий, когда уверенность выросла. Удалённая конфигурация стоит на месте как след привычки, и в спешке восстанавливать её из памяти приятнее, чем с нуля.

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

Чистка кэша журналов и локальных остатков

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

apt-get clean

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

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

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

Поверхность атаки и пакеты без обновлений

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

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

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

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

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

Сравнение машин парка и эталонные наборы

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

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

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

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

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

Рабочая процедура полугодового аудита

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

  1. Выгрузить вручную поставленное и полный состав для протокола;
  2. Пройти список с вопросом о назначении и разложить на кучки решения;
  3. Проверить сомнительные пункты поиском по сценариям и планировщикам;
  4. Удалить партиями с тестом служб и записью команды отката;
  5. Вычистить кэш, старые журналы операций и локальные остатки;
  6. Сверить состав с эталоном роли и зафиксировать протокол аудита.

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

Итоговое суждение по полугодовой привычке доброе. Аудит состава это разгрузка памяти на бумагу: состав, который можно объяснить, не нужно помнить. Сервер с осознанным набором пакетов обновляется быстрее, объясняется новому человеку за минуты и деградирует медленнее, потому что в нём меньше вещей, способных деградировать. Полдня раз в полгода это скромная цена за сервер, о котором можно ответить на любой вопрос "что это и зачем" без паузы и без легенд.
Мелкая привычка с большим эффектом: протокол аудита хранить рядом с описанием сервера, одной папкой. Через год два протокола ложатся рядом и показывают тренд состава: что чистится легко, что возвращается, а что пора признать частью системы и внести в эталон без стыда.