Запрет монтирования съемных устройств через polkit
В своей организации столкнулся со следующей задачей: необходимо запретить монтировать пользователям USB-носители, кроме некоторых избранных (с приложенным списком).
Перекопал множество способов, начиная от запрета загрузки модулей и заканчивая ограничением прав на точку монтирования. Из всех методов мне больше всего понравилась реализация через polkit.
Немного теоретической основы. Polkit - это фреймворк, обеспечивающий предоставление механизмов авторизации на выполнение различных задач конечному пользователю. Эти самые различные задачи (в терминологии polkit - actions) могут варьироваться: установка системных шрифтов, перезагрузка компьютера, смена пользователя, управление питанием, подключение сетевых интерфейсов и прочее. Естественно, некоторые задачи при этом требуют повышенных привилегий, которые и обеспечивает polkit. Каждая задача имеет политику по умолчанию (default policy), которая может применяться в трех состояниях пользователя - когда пользователь находится в активной сессии (active), когда пользователь отключен от активной сессии по неактивности (inactive) и при любом из состояний (any). Действия polkit при этом могут быть следующими: разрешать (yes), запрещать (no), разрешать после подтверждения собственным паролем (auth_self), разрешать после подтверждения собственным паролем с сохранением сессии (auth_self_keep), разрешать после подтверждения паролем суперпользователя (auth_admin), разрешать после подтверждения паролем суперпользователя с сохранением сессии (auth_admin_keep). Эту политику можно переопределять локальными средствами. Как - мы рассмотрим в практическом примере.
Вернемся к нашей задаче. Монтированием в любом современном DE занимается пакет udisks, который имеет несколько действий, касающихся монтирования файловых систем. Соответствующая политика находится в XML-файле /usr/share/polkit-1/actions/org.freedesktop.udisks.policy
. Для конкретно нашей задачи нам нужно действие org.freedesktop.udisks.filesystem-mount
, которая имеет следующий вид:
<action id="org.freedesktop.udisks.filesystem-mount"> <description>Mount a device</description> <description xml:lang="da">Montér en enhed</description> <message>Authentication is required to mount the device</message> <message xml:lang="da">Autorisering er påkrævet for at montere et fil system</message> <defaults> <allow_any>no</allow_any> <allow_inactive>no</allow_inactive> <allow_active>yes</allow_active> </defaults> </action>
Казалось бы, вот оно, решение - меняем действие allow_active на другое, и дело в шляпе! Но нет, во-первых, это файл системного пакета, который перезапишется при следующем обновлении, а во-вторых, не решен вопрос предоставления доступа избранным. Тут на помощь приходит такая замечательная особенность polkit, как переопределение политик по умолчанию. Подробно о ней можно прочитать в man pklocalauthority
. Данная возможность позволяет создавать .pkla-файлы (на деле - .ini-файлы), которые могут определять действия для конкретных групп и пользователей (Identity). Сами же файлы могут размещаться на различных уровнях, которые могут друг друга переопределять. Создателями polkit предусмотрена следующая структура:
/var/lib/polkit-1/ |-- localauthority |-- 10-vendor.d |-- 20-org.d |-- 30-site.d |-- 50-local.d |-- 90-mandatory.d /etc/polkit-1/ |-- localauthority |-- 10-vendor.d |-- 20-org.d |-- 30-site.d |-- 50-local.d |-- 90-mandatory.d
Порядок следования идет сверху вниз, то есть последними применяются действия из /etc/polkit-1/localauthority/90-mandatory.d
. Мы можем включить файлы в любой из уровней, но я предпочел 20-org.d
- уровень организации.
Остается только написать переопределение. Оно простое и имеет формат ini-файла:
[Disable mounting removable disks to all] Identity=unix-group:* Action=org.freedesktop.udisks.filesystem-mount ResultAny=no ResultInactive=no ResultActive=no [Enable mounting removable disks to some users] Identity=unix-user:alice,bob Action=org.freedesktop.udisks.filesystem-mount ResultAny=no ResultInactive=no ResultActive=auth_self
Вот и все. Помещаем эти строки в файл /etc/polkit-1/localauthority/20-org.d/10-flash-mounting-policy.pkla
и наслаждаемся результатом. Ничего не нужно перезагружать - политики применяются сразу же при активации заданного действия. В данном примере, никто, кроме пользователей alice и bob (которым предварительно понадобится ввести свой пароль), не сможет смонтировать съемные носители. Естественно, это можно обойти, имея права root или права запускать sudo, но тогда таких пользователей вообще ничего не остановит.
А теперь об ограничениях текущей реализации. К сожалению, мне не удалось реализовать переопределения политики по умолчанию для действия, то есть файл (отсутствие Identity)
[Disable mounting removable disks to all] Action=org.freedesktop.udisks.filesystem-mount ResultAny=no ResultInactive=no ResultActive=no
работать не будет. Плюс к этом глоббинг (*
при определении групп или пользователей) отрабатывается не так, как ожидается: указав звездочку, вы уже не сможете назначить исключения, звездочка съест их всех. Вот такой пример не будет работать:
[Disable mounting removable disks to all] Identity=unix-group:* Action=org.freedesktop.udisks.filesystem-mount ResultAny=no ResultInactive=no ResultActive=no [Enable mounting removable disks to some users] Identity=unix-group:disks Action=org.freedesktop.udisks.filesystem-mount ResultAny=no ResultInactive=no ResultActive=auth_self
В заключение скажу, polkit - очень мощная и гибкая система раздачи прав, которая очень удобна для конечного пользователя рабочей станции, но ее поддержка включена не всюду, поэтому пока круг ее задач ограничен.
- Блог пользователя - winterheart
- Для комментирования войдите или зарегистрируйтесь
Может лучше у Вики?
Есть мнение, что достаточно первой строчки, а сам формат (все три параметра) кочует... неведомо откуда и не вполне корректен.
ИМХО правильнее использовать
ResultAny
илиResultActive/Inactive
.ЗЫ: А я-то надеялся, что здесь расскажут, как запретить монтировать все носители кроме списка конкретных (артефактов)... :)
:wq
--
Live free or die
ResultAny - это не комбинация
ResultAny - это не комбинация ResultActive и ResultInactive. ResultAny - это результат при любом условии, когда как ResultActive и ResultInactive - при активной/неактивной сессии локального пользователя.
Для блокировки всех устройств и предоставления только некоторых нужно копать еще глубже, ближе к аппаратному уровню - либо в правила udev, либо в D-Bus, что для меня было и неоправданно сложно.
Не грусти, товарищ! Всё хорошо, beautiful good!
/
Ну да.
Всё так и есть.
Вопрос: зачем запретив действие при любов условии запрещать его ещё раз для активной и неактивной сессий пользователя?
И потом, по результатам моих, достаточно скромных, опытов, как минимум начиная с определённой версии значение
ResultActive/Inactive
перекрываетResultAny
(помнится и тема на форуме была).:wq
--
Live free or die
(*)
Исчерпывающе и впечатляюще.
Kруто. Еще бы по сети ... да
Kруто. Еще бы по сети ... да push модель.... да по шифрованному каналу с крипрографическим квитированием ...
ну вот, опять из хотелок получилась винда ;(
Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)
.
С учётом области _реальной_ необходимости перечисленных хотелок (сразу вспомнается виндузячий критерий "защищённой" рабочей станции: последние обновления от майкрософта в слепо-автоматическом режиме, антивирус касперского с последними базами --- и самое главное сохранение в строжайшей тайне условий аудита, которым оно должно удовлетворять) и параметра реализуемости можно сделать вывод, что тов. slepnoga мечтает о том, чтобы GNU/Linux догнал виндавс в части удалённых уязвимостей.
:wq
--
Live free or die