Ограниченные права установки пакетов (для Debian/Ubuntu)

Здесь обсуждаются все вопросы, не попадающие под другие категории
saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

(копия моих постов на форуме linux.su)

Часто Debian (Ubuntu и др.) ставиться на машину, на которой работают несколько пользователей, часто не знающих пароль root'a. Для выполнения своей повседневной работы этих юзеров можно включать в группы. Например, audio - для работы с ALSA, dip - для дозвона, plugdev - для монтирования внешних ЗУ. Часто, с помощью sudo, можно дать юзеру некоторые специфические права.

Но беда в том, что новые программы (пакет) рядовой юзер установить не может. Конечно, многие пакеты слишком системны для того, чтобы их ставить рядовыми юзерами. Многие пакеты в корне меняют принципы загрузки/работы системы, например, kdm (зависимость зависимости kdebase) после инсталляции установит графичекий login. Установка многих пакетов может повредить системе только из-за того, что пользователь может дать плохие ответы на вопросы Debconf'а. Например, инсталляция пакета sash при конфигурации Debconf'ом предлагает создать sashroot (ещё одного пользователя с uid=0 т.е. администратора) и задать ему пароль!

Часто обычному пользователю и даже разработчику такие вещи не нужны. Но такой пользователь хотел бы иметь возможность установить доки или книги (например, c++-annotations), вьюверы для их прочтения (например, kpdf, kdvi), различные библиотеки (скомпилированные *.so и headerы), любимые addonы к браузеру, учебные программы, локализации.

Я сделал попытку решить эту проблему, написав на sh пока очень кривой скрипт. Надеюсь, что сама идея будет кому-нибудь интересна.

saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

Сам скрипт можно посмотреть на http://rapidshare.com/files/157744696/l ... pt-install. Скрипт предоставляет собой очень ограничивающий вариант "aptitude install", используя последний как backend. Поэтому его нужно прописать в sudo:

Код: Выделить всё

Cmnd_Alias  APTINSTALL = /usr/local/bin/limited-apt-install *
%aptinstallers LOCAL = APTINSTALL
aptinstallers - это и есть группа тех пользователей, которые могут ставить "несистемные" пакеты.

Синтаксис команды простой: limited-apt-install <package1> <package2> ... <packageN>
Раз "aptitude install" используется как backend, то становятся возможной не только инсталляция пакетов, но также:
<package>+M - инсталлировать и сразу же пометить как автоматически установленный.
<package>- - деисталлировать.
<package>_ - purge.
<package>= - зоморозить версию (чтобы не обновлялся сейчас и в будущем).
<package>: - зоморозить версию (чтобы сейчас не обновлялся).
<package>&M - пометить как автоматически установленный.
<package>&m - пометить как установленный вручную.

Пример: sudo limited-apt-install iptables- sudo_
Очевидно, что все эти дополнительные возможности нужно запретить. Для этого я сделал регулярное выражение:

Код: Выделить всё

NAMEREGEXP="^[a-z0-9][a-z0-9+\.\-]*[a-z0-9+]$"
, на соответствие которому скрипт проверяет имена пакетов, перечисленные как аргументы команды limited-apt-install. Оно запрещает символы -,_,=,:,&M,&m на конце.

Теперь подходим к самому главному. Нужно проверить, не является ли пакет, желаемый для установки пользователем, слишком системным. Я реализовал это используя debtags. Я просто запрещаю пакеты, имеющие tagи из фасетов "admin", "hardware" и "security":

Код: Выделить всё

# Checks if package is system (and dangerous for install by ordinary user).
#
# Current variation relys on debtags
IsPackageDangerous()
{
    PACKAGENAME=$1

    DANGEROUSFACETS="admin hardware security"

    for LINE in `debtags tag ls $PACKAGENAME`; do
        FACET=`echo $LINE | awk -F:: '{print $1}'`
        for DANGEROUSFACET in $DANGEROUSFACETS; do
            if [ $FACET = $DANGEROUSFACET ]; then
                echo "E: Package \"""$PACKAGENAME""\" is dangerous! ""(""$FACET"")"
                return 1
            fi
        done
    done

    return 0
}
Я прекрасно понимаю недостатки своего решения:
  • Таги не могут помочь правильно отличить системный (опасный) пакет от несистемного. Таги предназначены для поиска!
  • Maintainerы могут выложить пакет в дистрибутив, не успев дать таги
  • Фасет или таг может быть ещё не придуман
  • Сама концепция "запретить всё кроме" является порочной по своей сути
Я думаю, что нужно просто составить список несистемных пакетов и проверять, есть ли в нём имя данного пакета. Тем более, что пакетов в Debianе немного (около 27000).

Также необходимо удостовериться, что желаемый пакет будем установлен из нужного (используемого администратором) дистрибутива (suite). Это предотвратит от установки пользователем чего-нибудь из experimental :). Для этого, в первую очередь, нужно явно указать suite для команды "aptitude install":

Код: Выделить всё

SUITE="testing"
INSTALLEROPTIONS="--target-release ""$SUITE" # used to explicitly indicate suite
aptitude $INSTALLEROPTIONS install $ALLPARAMS
. Но, к примеру, если желаемого пакета нет testingе, то "aptitude install" установит его из unstable. Поэтому нужно обязательно проверять, есть ли какая-нибудь версия этого пакета в нужном дистрибутиве. Это можно сделать так:

Код: Выделить всё

# Checks if our suite contains given package otherwise aptitude will install this package from other suite.
# This will prevent system to be inadequate versions installed on.
CheckSuiteHasPackage()
{
    PACKAGENAME=$1

    NOGIVENSUITESTR="No ""$SUITE"" version"
    #TODO: use $NOGIVENSUITESTR variable
    if
        apt-show-versions -a -p $PACKAGENAME | grep 'No testing version' > /dev/null 2>&1
    then
        echo "E: There are no version in suite ""$SUITE"" for package: \"""$PACKAGENAME""\"."
        return 1
    else
        return 0
    fi
}

saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

Но вот в чём главная трудность: "aptitude install" устанавливает пакеты с их зависимостями (также рекомендуемыми и предлагаемыми пакетами (в зависимости от настроек пользователя)). Поэтому необходимо проверять на "несистемность" и наличие в нужном дистрибутиве не только сами пакеты (параметры командной строки), но и всё дерево их зависимостей, которые aptitude захочет установить! Например, пакет phpbb3 - несистемный (с точки зрения моей функции IsPackageDangerous()), но он зависит от пакета dbconfig-common, который имеет таги admin::configuring и admin::package-management.

Первая идея, которая пришла мне в голову заключается в том, что нужно рекурсивно (используя output комманды "apt-cache depends") проверять на несистемность все неустановленные зависимости. Тогда, конечно, необходимо проверять всё дерево зависимостей и на конфликты: конфликтует ли пакет с каким-нибудь уже установленным. Разумеется, такие конфликты допускать нельзя, иначе пользователь сможет деинсталлировать некоторые пакеты.

Но здесь есть подводные камни, и этот метод правильно работать не будет! Во первых, среди пакетов пользователя (или из зависимостей) могут быть виртуальные, которые "aptitude install"' может заменить на реальные, но ... их зависимости нельзя узнать. Во вторых, мы не знаем будет ли "aptitude install" автоматически ставить рекомендуемые и предлагаемые пакеты (это зависит от насктроек). В третьих, некоторые пакеты aptitudом могут быть брошены или downgraded.

Из-за этого я отбросил первую идею и решить полностью положиться на output команды "aptitude install". Её нужно заранее запускать с опциями --simulate (чтобы она не начала инсталлировать, пока скрипт ещё ничего не проверил) и --assume-yes (чтобы не задавала вопросов).

Сторока за строкой я читаю вывод комманды aptitude $INSTALLEROPTIONS --simulate --assume-yes install $ALLPARAMS и ищю, где начинается и где кончается список пакетов для инсталляции, проверяя сообщения команды "aptitudе install". Для этого мне даже пришлось составить список сообщений:

Код: Выделить всё

    INSTALLEDPRELIMINARYSTR="The following NEW packages will be installed:"
    REMOVEDPRELIMINARYSTR="The following packages will be REMOVED:"
    BROKENPRELIMINARYSTR="The following packages are BROKEN:"
    UPGRADEDPRELIMINARYSTR="The following packages will be upgraded:"
    DOWNGRADEDPRELIMINARYSTR="The following packages will be DOWNGRADED:"
Найденные строки с пакетами для установки нужно парсить и удалять из них флаги (типа {a}), после чего проверять их на "несистемность" и наличие в нужном дистрибутиве. Удобно то, что "aptitude install" сам составит полное дерево зависимостей так, как ему угодно, и выведет его в стандартный поток вывода. Тут же можно и проверить, собирается ли "aptitude install" что-либо деисталлировать, бросать или даунгрэйдить (из-за конфликтов). Читайте код функции CheckSafetyOfAllInstalledPackages() в моём скрипте (ссылка выше).

Я прекрасно понимаю, что моя реализации жутко кривая :(. Конечно, нельзя полагать на output, который предназначен только для удобства пользователя и его формат может быть изменён. Код функции выглядит даже как-то маразматически.

saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

Но, я думаю, что моя идея будет кому-нибудь интересна.

Думаю, что её можно правильно реализовать, используя, какие-нибудь API APTа (может быть, python-apt).

Недостаток идеи в том, что пользователь сможет инсталлировать пакет, но не сможет его позже деинсталлировать. Но я думаю, что и эту проблему можно решить. Можно создать список пакетов, которые (не включая зависимости) поставил с помощью limited-apt-install данный пользователь, и разрешить ему деинсталлировать только эти пакеты. Правда я не знаю как узнать из скрипта имя пользователя, который запустил данный скрипт через sudo. :?:

Можно реализовать и что-то вроде подсчёта ссылок. Для этого нужно разрешить пользователю A устанавливать пакет, если он уже установлен пользователем B (вместо инсталляции тогда нужно будет просто добавить пакет в список пользователя B). При "деинсталляции" имя пакета нужно просто удалять из списка данного пользователя. А когда имя пакета удалено из списков всех пользователей, нужно деинсталлировать пакет физически.

saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

Немного порассуждаю о безопасности подобной штуки...

При инсталляции (иногда и при обновлении) некоторых пакетов Debconf задаёт вопросы пользователю. Что сделать, чтобы пользователь не наконфигурировал абы-что и чтобы данная конфигурация не ущемила безопасность системы? Может быть нужно поднять наименьший приоритет вопросов Debconfа до critical для данной инсталляции (это можно сделать используя переменную окружения $DEBIAN_PRIORITY)? Может быть давать ответы на вопросы в noninteractive-режиме, используя готовые базы ответов?

А вот сейчас мне пришла ещё одна интересная идея. Что если вообще оставлять пакет несконфигурированным (лучше, наверное, задать какие-нибудь умолчания), а оставить конфигурирование администратору. Можно, например, отправлять ему почтовое сообщение с именами пакетов, которые нужно сконфигурировать Debconfом.

Ещё одна проблема: что будет, если по какой-нибудь причине пакет останется "наполовину установленным" (в состоянии half-installed, unpacked или half-configured)?

Как я уже говорил, нужно научиться правильно отличать "несистемные" (безопасные для установки рядовым пользователем) пакеты от "системных". Для этого можно просто составить список "несистемных" пакетов.

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

d4s
Маньяк
Сообщения: 184
Зарегистрирован: 11 авг 2003, 12:12
Откуда: Минск
Контактная информация:

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение d4s »

1. хм... а создать репозиторий только из разрешенных программ и их зависимостей уже не модно ? дать доступ к sudo apt*, но не давать возможности сменить репозиторий.

2. в том же конфиге apt поставить на холд опасные и/или системообразующие вещи
WBR, d4s
linux registered user #264610 [Empty]

saintleva
Заглянувший
Сообщения: 7
Зарегистрирован: 25 окт 2008, 19:41

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение saintleva »

d4s писал(а):1. хм... а создать репозиторий только из разрешенных программ и их зависимостей уже не модно ? дать доступ к sudo apt*, но не давать возможности сменить репозиторий.
Действительно интересная идея 8). Насколько я понимаю, вы предлагаете создать свой suite типа "lenny-for-user", записав в соотвествующий директорий dists/lenny/main/binary-i386 файл Packages.gz со списком только разрешённых пакетов (и еще Package.gz в секции non-free и contrib). При этом как backend нужно использовать aptitude --target-release lenny-for-user install <пакет> (обязательно явное указание репозитория lenny-for-user). Но после несколькочасового обдумывания я вижу несколько недостатков такого подхода:
  1. В списке пакетов секции репозитория указывает относительный путь к конкретной версии пакета. Такие списки нужно будет обновлять вместе с обновлением реального дистрибутива.
  2. Даже явное указание опции --target-release lenny-for-user не поможет, если пакета в этом репозитории нет (такую же вещь я проверяет и мой скрипте). Может быть, есть опция в apt.conf которая отменяет такое поведения, но я её не знаю. Подскажите мне, если таковая есть.
  3. Можно физически отключать другие репозитории. Для этого, наверное, нужно перемещать файлы sources.list и sources.list.d/*.list, обязательно выполняя после этого "aptitude update". Мне это кажется неудобным.
  4. Здесь не решён вопрос о дополнительных возможностях "aptitude install", которые дадут возможность деинсталлировать пакеты.
  5. Здесь не решён вопрос о настройке Debconfом
d4s писал(а): 2. в том же конфиге apt поставить на холд опасные и/или системообразующие вещи
Здесь мне представляется опасным сам подход: разрешить юзеру делать всё, кроме чего-то. При этом, конечно, root рано или поздно захочет снять hold на эти пакеты (чтобы, например, обновить их), но тогда нужно будет снять все holdы. А администратору могут быть нужны эти настоящие/постоянные holdы для каких-нибудь целей.

P.S. Извините меня, если я неправильно понимаю вашу идею и её возможные реализации.

d4s
Маньяк
Сообщения: 184
Зарегистрирован: 11 авг 2003, 12:12
Откуда: Минск
Контактная информация:

Re: Ограниченные права установки пакетов (для Debian/Ubuntu)

Сообщение d4s »

Я не дебиан юзер - так что по созданию репозитория конкретно под него не подскажу.

Кроме того, хотел более развернуто ответить - вспомнил про переменную APT_CONFIG, благодаря которой юзер при использовании sudo apt-* может сам подключить все что захочет, хоть локальный репозиторий с руткитом ;-)

Так что враппер по-любому нужен и разрешение sudo только на него.
Хотя я бы просто очищал окружение, а во враппере указывал использование соответствующим образом настроенных apt.cong/sources.list

Но, как знаете - система ваша ;-)
WBR, d4s
linux registered user #264610 [Empty]

Ответить