hasher: технология безопасной сборки пакетов

Дмитрий Левин

Традиционная схема сборки дистрибутивов

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

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

Требования к сборочной технологии

Технология сборки элементов дистрибутива (пакетов) должна:

  • не снижать уровень безопасности хост-системы;

  • обеспечивать собственную безопасность от атак со стороны пакетов;

  • обеспечивать безопасность сборки пакетов от атак со стороны других пакетов;

  • гарантировать надёжность (воспроизводимость) результатов сборки;

  • обеспечивать приемлемый уровень производительности.

Архитектура hasher'а

В основе архитектуры hasher'а лежит трёхпользовательская модель: вызывающий непривилегированный пользователь (C) и два непривилегированных вспомогательных псевдопользователя; первый (R) играет роль root в порождаемой сборочной среде, второй (U) "--- обычного пользователя, собирающего программы.

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

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

  1. Пользователь C порождает среду (aptbox) для работы с apt.

  2. Полностью удаляется сборочная среда, возможно оставшаяся от предыдущей сборки. Удаление происходит последовательно в chroot пользователем U, в chroot пользователем R и, наконец, пользователем С.

  3. Пользователь C создаёт каркас новой сборочной среды, состоящий из вспомогательных каталогов и вспомогательных статически слинкованных программ (ash, find и cpio). С помощью вспомогательной привилегированной программы создаётся фиксированный набор устройств, достаточный для нормального функционирования сборочной среды и при этом не несущий угрозы host-системе.

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

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

  6. Порождается сборочная среда для данного пакета. Пользователь U извлекает сборочные зависимости пакета, пользователь C с помощью apt определяет набор пакетов для установки, и пользователь R устанавливает их.

  7. Пользователь U осуществляет сборку пакета.

Такая схема призвана исключить атаки вида U->R, U->C, R->C, а также все виды атак на root.

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

beehive: распределённая сборка с помощью hasher'а

Благодаря свойству воспроизводимости результатов сборки hasher можно использовать для параллельной сборки большого числа пакетов на нескольких серверах. Таким образом удаётся достичь разумного времени сборки при средних вычислительных ресурсах. Открывается возможность организовать регулярное тестирование на пересобираемость большого репозитория пакетов, что и было сделано на примере Sisyphus с помощью средства параллельной сборки beehive.