Сам скрипт можно посмотреть на http://rapidshare.com/files/157744696/limited-apt-install. Скрипт предоставляет собой
очень ограничивающий вариант "aptitude install", используя последний как backend. Поэтому его нужно прописать в sudo:
Код:
Cmnd_Alias APTINSTALL = /usr/local/bin/limited-apt-install *
%aptinstallers LOCAL = APTINSTALL
aptinstallers - это и есть группа тех пользователей, которые могут ставить "несистемные" пакеты.
Синтаксис команды простой:
limited-apt-install ...
Раз "aptitude install" используется как backend, то становятся возможной не только инсталляция пакетов, но также:
+M - инсталлировать и сразу же пометить как автоматически установленный.
- - деисталлировать.
_ - purge.
= - зоморозить версию (чтобы не обновлялся сейчас и в будущем).
: - зоморозить версию (чтобы сейчас не обновлялся).
&M - пометить как автоматически установленный.
&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
}