Авторские статьи

Больше никаких Hash Sum Mismatch.


Разработчики недавно нас порадовали ускорением работы apt утилиты и вот ещё подарок - изменение в нашем общении с репозиториями.

Формат Debian репозитория был разработан очень давно. Самые старые его версии создавались через dpkg-scanpackages и забирали мы их через метод dselect по имени dpkg-ftp. Забирался файл Packages (возможно сжатый) и использовался в качестве индекс-файла, который отражал доступные пакеты. Каждый пакет имел контрольную сумму MD5, чтобы вы могли сверить наличие/отсутствие проблем при передаче. В те далёкие года ещё не было цифровой подписи у репозитория или какой-либо другой защиты от атаки "человек посередине" (Man in the middle (MITM)).

Важной особенностью раннего формата репозитория, помимо Packages файла, все файлы были статичны в том смысле, что будучи опубликованы, их контент не менялся без изменения имени файла. Это означает, что репозитория могли быть эффективно скопированы утилитами типа rsync без необходимости пересчитывать контрольную сумму всех файлов И помогали избежать сетевых гонок при обновлении. Сам репозиторий мог вполне быть обновлён в середине вашего обновления системы, но так как программы, обслуживающие репозиторий, сохраняли вытесненные новыми версиями пакеты на какой-то период, то у вас оставалась возможность их скачать (fetch).

Формат репозитория со временем эволюционировал под влиянием требований различных клиентских инструментов. В какой-то момент времени был добавлен индекс Sources для пакетов с исходниками программ по аналогии с Packages. Но значительным изменением в структуре репозитория стало внедрение проекта package pools.

Первоначальная схема подразумевала размещение пакетов в dists/ вместе с индексными файлами. Дерево dists/ создавало программные наборы (suite), современные примеры которых вы знаете по таким именам как stable, stable-updates, testing, unstable, xenial, xenial-updates. Это означало, что выпуск релиза Debian вынуждал копировать огромные массивы данных и делало реализацию testing очень затратной.

Package pools решили эту проблему перемещением отдельных файлов пакетов из dists/ в pool/, позволяя различным программным наборам (suite) делить между собой один и тот же пакет. Это позволило значительно снизить расходы дискового пространства и пропускную способность при зеркалировании репо. Как часть этого проекта, первоначальный скрипт dinstall, обслуживающий Debian репозиторий, был заменён на da-katie (dak), который использовал apt-ftparchive для построения индексных файлов. Были заменены dpkg-scanpackages, dpkg-scansources. Благодаря реализации кэша базы данных, было достигнуто существенное увеличение производительности.

Спустя пару месяцев после первой реализации package pools, были добавлены файлы Release. Они образовывали своего рода мета-индексы для каждого программного набора (suite), объясняя APT какие индексы доступны (main/binary-i386/Packages, non-free/source/Sources и т.д) и какие у них контрольные суммы. Реализация подписей (Release.gpg) позволило безопасно получать пакеты и проверять их на стороне клиента с помощью ключа репозитория. Данная структура репозитория оставалась неизменной многие годы.

В какой-то момент времени все те кто обслуживают хранилища пакетов начали осознавать, что потеряли важное свойство первоначального формата репозитория - отсутствие состояния гонки при обновлении (race-free). Но после введения файла Release это было утеряно. Клиент должен вначале скачать (fetch) Release и другие индексные файлы, обычно в отдельных HTTP транзакциях. Если клиенту не повезло и он попал в момент обновления репо, то транзакции будут завершены с ошибкой и он получит Hash Sum Mismatch.

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

Исправление ситуации заняло долгий путь с 2007 года, так как нужно было сохранить совместимость. Первым шагом было внедрение inline-signed версии файла Release под названием InRelease, чтобы избежать состояния гонки при скачивании Release и сигнатур.

Apt инструмент и репозитории Debian и Ubuntu поддерживают нововведение. Изменение других индексных файлов сложнее, хотя делать для них inline-signed версию необязательно, так как клиенты обычно забирают малую часть доступных индексов, доступных в данном программном наборе.

Окончательно решение проблемы было закончено благодаря работе Майкла Фогта (Michael Vogt). Его реализация в Apt по имени by-hash будет понятна людям, знакомые с работой git. Индексные файлы для программных наборов (suite) поддерживают механизм by-hash, который позволяет получить (fetch) их, используя URL-хэш. То есть клиент может использовать:

  • Fetch dists/xenial/InRelease
  • Fetch dists/xenial/main/binary-amd64/by-hash/SHA256/46316a202cdae76a73b555414741b11d08c66620b76c470a1623cedcc8a14740
  • Fetch отдельный файл пакета

Все новшества доступны только в Ubuntu 16.04, так как ранние версии не имеют нужного в apt. Теперь Hash Sum Mismatch должны остаться в прошлом.

Есть люди, которые не получат выгоды от новшеств. Debmirror не поддерживает by-hash. Apt-cacher-ng поддерживает в Ubuntu 16.04. Полное зеркалирование репозитория должно происходить так: файлы by-hash должны быть скопированы ДО InRelease. Настоятельно рекомендуется двухступенчатое зеркалирование. Ubumirror требует доработки. Дебиановский ftpsync работает почти правильно, но нуждается в маленьком твике, который послан разработчикам. Другие программы зеркалирования и проксирования должны доработать свои действия при обслуживании нового формата репозитория.

Если что-то происходит по вашему мнению странное, то выполните apt -o Debug::Acquire::http=true update для отладки происходящего.

APT станет быстрее.
С apt-get ни шагу назад.

Дата последней правки: 2023-12-27 16:42:26

RSS vasilisc.com   


Разделы

Главная
Новости
Ворох бумаг
Видео Linux
Игры в Linux
Безопасность
Статьи об Astra Linux
Статьи о FreeBSD
Статьи об Ubuntu
Статьи о Snappy
Статьи об Ubuntu Phone
Статьи о Kubuntu
Статьи о Xubuntu
Статьи о Lubuntu
Статьи об Open Source
Карта сайта