4.21 Работа с политиками Polkit

Polkit

Polkit (прежнее название: PolicyKit) — библиотека для UNIX-подобных операционных систем. API библиотеки используется для предоставления непривилегированным процессам возможности выполнения действий, требующих прав администратора. Использование Polkit противопоставляется использованию таких систем, как sudo, но не наделяет процесс пользователя правами администратора, а позволяет точно контролировать, что разрешено, а что запрещено.

Политики polkit

Все политики находятся в /usr/share/polkit-1/actions/ в формате *.policy Каждая политика представляет собой xml-файл, в котором описываются запросы к polkit. Каждый запрос имеет три условия, прописанных в секции defaults:

  1. Запрос от любого пользователя. Тег <allow_any>
  2. Запрос от неактивного пользователя. Тег <allow_inactive>
  3. Запрос от активного пользователя <allow_active>

Внутри каждого тега прописывается возвращаемое значение. Используются следующие варианты значений:

  • yes— предоставить разрешения
  • no— заблокировать разрешения
  • auth_self— пользователь должен ввести свой пароль для аутентификации
  • auth_self_keep_session— пользователь должен ввести свой пароль для аутентификации один раз за сессию, разрешение предоставляется для всей сессии
  • auth_self_keep_always— пользователь должен ввести свой пароль для аутентификации один раз, разрешение предоставляется для текущей и будущих сессий
  • auth_admin— пользователь должен ввести пароль admin при каждом запросе
  • auth_admin_keep_session— пользователь должен ввести пароль admin, разрешение предоставляется для всей сессии
  • auth_admin_keep_always— пользователь должен ввести пароль admin, разрешение предоставляется для текущей и будущих сессий

admin — в РЕД ОС определён в правиле /etc/polkit-1/rules.d/50-default.rules:

polkit.addAdminRule(function(action, subject) {
return ["unix-user:root"];
});

Правила polkit

Менять напрямую политики нельзя, так как при обновлении системы они затрутся. Необходимо создавать собственные правила в /etc/polkit-1/rules.d/ в формате *.rules. Правила выполняются в порядке названия по алфавиту, поэтому вначале пишутся цифры, чтобы указать приоритет правила. Алгоритм создания правила (все действия выполняются от root):

  1. Для начала определяем какую политику мы хотим изменить, для этого находим в /usr/share/polkit-1/actions/требуемую.
  2. Редактируем новый файл с политикой:
nano /etc/polkit-1/rules.d/99-vashe_pravilo.rules
  1. Вставляем такой текст:
 polkit.addRule(function(action, subject) {
    if (action.id == "policy" && vashe_uslovie) {
            return polkit.Result.YES;
    };
});

где

  • вместо 99 подставляем нужное число (файлы с политиками просматриваются в лексикографическом порядке, 99 будет последним правилом)
  • вместо policyпишем название политики, поведение которой нужно изменить
  • вместо vashe_uslovie: если нужно изменить поведение политики для одного пользователя пишем subject.user == ‘%username%’, если для группы, то subject.isInGroup(‘%groupname%’)
  • Result.YESозначает, что политика будет при выполнении условия правила предоставлять разрешение.

Журналирование действий polkit

Используя правила polkit можно также делать записи в системный журнал. Метод log() записывает сообщение в системный журнал. Пример:

polkit.addRule(function(action, subject) {
    if (action.id == "действие") {
        polkit.log("action=" + action);
        polkit.log("subject=" + subject);
    }
});

В параметре action передается объект с информацией о совершенном процессе и связанные с этим действием параметры (например, если запрошенное действие монтирование съемного диска, то в параметре action будут переданы серийный номер диска, его id, файловая система и т.д).

В параметре subject передается объект с информацией о пользователе, запустившем процесс. Этот объект имеет следующие атрибуты:

  • id – идентификатор процесса;
  • user – имя пользователя;
  • groups – список групп, в которые входит пользователь;
  • seat – местонахождение субъекта (пустое значение, если местонахождение не локальное);
  • session – сессия субъекта;
  • local – true, только если местонахождение имеет локальный характер;
  • active – true, только если сеанс активен.

Примеры

Пользователи часто жалуются на необходимость вводить пароль при монтировании разделов в файловом менеджере и создании нового подключения в NetworkManager, а также невозможность извлечь usb-flash или лоток оптического привода. За эти разрешения отвечают:

org.freedesktop.udisks2.filesystem-mount-system — разрешение на монтирование файловых систем системных устройств

org.freedesktop.udisks2.filesystem-mount-other-seat — разрешение на монтирование файловых систем с устройств подключенных в другое место

org.freedesktop.udisks2.eject-media-other-seat — разрешение на извлечение лотка оптического привода

org.freedesktop.udisks2.power-off-drive-other-seat — разрешение на извлечение usb-flash

org.freedesktop.NetworkManager.settings.modify.system — разрешение на создание и модификацию системных сетевых соединений

Монтирование раздела и создание нового подключения без запроса пароля

Сделаем так, чтобы если пользователь находится в системной группе xgrp, то для него запросы пароля не должны будут выполняться для этих действий. Для этого (все действия выполняются от root):

  1. Наполнить/etc/polkit-1/rules.d/99-udisk2_mount.rules таким содержанием:
polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.udisks2.filesystem-mount-system" || action.id == "org.freedesktop.udisks2.filesystem-mount-other-seat" || action.id == "org.freedesktop.udisks2.eject-media-other-seat" || action.id == "org.freedesktop.udisks2.power-off-drive-other-seat") && subject.isInGroup("xgrp")) {
            return polkit.Result.YES;
    };  
});
  1. Наполнить /etc/polkit-1/rules.d/99-networkmanager.rules таким содержанием:
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.NetworkManager.settings.modify.system" && subject.isInGroup("xgrp")) {
            return polkit.Result.YES;
    };
});
  1. Создать системную группу xgrp (если её ещё нет):
groupadd -r xgrp
  1. Добавить пользователя в группу xgrp:
gpasswd -a имя_пользователя xgrp

5. Перезапустить политики Polkit:

systemctl restart polkit

Монтирование раздела и создание нового подключения с запросом пароля

Пример создания правила, разрешающего пользователю выполнять монтирование и извлечение устройств — с запросом пароля (при указании polkit.Result.AUTH_SELF — будет запрошен пароль текущего пользователя, polkit.Result.AUTH_ADMIN — администратора). При подключении съемного устройства записывать в системный журнал какое устройство было подключено и каким пользователем:

  1. Наполнить 99-udisk2_mount.rules таким содержанием:
polkit.addRule(function(action, subject) {        
    polkit.log("action "+ action);        
    polkit.log("subject "+ subject);        
    if (action.id == "org.freedesktop.udisks2.filesystem-mount-system") {            
       return polkit.Result.AUTH_SELF;};        
    if (action.id == "org.freedesktop.udisks2.filesystem-mount") {            
       return polkit.Result.AUTH_SELF;};        
   if (action.id == "org.freedesktop.udisks2.filesystem-mount-other-seats") {
       return polkit.Result.AUTH_SELF;};
 });

2.Перезапустить политики Polkit:

systemctl restart polkit

При монтировании USB-диска в системном журнале появятся записи:

Jul 24 12:57:12 host-15 polkitd[9879]: /etc/polkit-1/rules.d/99-udisk2_mount.rules:4: action [Action id='org.freedesktop.udisks2.filesystem-mount-system' id.version='FAT32' id.usage='filesystem' drive.serial='11101094E6BA1A00A4A5200A' id.label='ALT p8 xfce/x86_64' partition.flags='0x00000000' polkit.gettext_domain='udisks2' drive='UFD 2.0 Silicon-Power4G (/dev/sdb1)' partition.number='1' id.uuid='F076-C625' drive.vendor='UFD 2.0' device='/dev/sdb1' id.type='vfat' partition.type='0x0b' polkit.message='Authentication is required to mount $(drive)' drive.revision='PMAP' drive.model='Silicon-Power4G']Nov 22 12:57:13 host-15 polkitd[9879]: /etc/polkit-1/rules.d/99-udisk2_mount.rules:5: subject [Subject pid=4673 user='test' groups= uucp,proc,cdrom,floppy,cdwriter,audio,radio,users,scanner,xgrp, vmusers,audit_group,audit1,test, seat='seat0' session='5' local=true active=true]

Таким образом, в системном журнале зарегистрировано, что usb-диск с серийным номером 11101094E6BA1A00A4A5200A был подключен пользователем test.

Просмотреть факты подключения конкретного носителя, можно выполнив команду:

journalctl |grep  "drive.serial='11101094E6BA1A00A4A5200A'"

Разрешение монтирования определённых usb-flash накопителей

Создаём файл 30-mount.rules в директории /etc/polkit-1/rules.d

polkit.addRule(function(action, subject) { 
 if (action.id == "org.freedesktop.udisks.filesystem-mount"){
    if (action.id.version == "FAT32" || drive.serial="11101094E6BA1A00A4A5200A') 
       { return polkit.Result.NO; };
    else
       { return polkit.Result.YES; };
 }; 
});

Во втором правиле можно указать:

  • AUTH.ADMIN – разрешено с вводом пароля администратора;
  • NO – не разрешено вообще.

В данном примере разрешается монтирование usb-flash накопителей с файловой системой «FAT32» или серийным номером «11101094E6BA1A00A4A5200A»

Основной список доступных параметров вы можете получить при подключении usb-flash накопителя и просмотре содержимого журнала:

journalctl |grep "org.freedesktop.udisks2.filesystem-mount-system"

Или в статусе сервиса политик Polkit:

systemctl status polkit

Изменение Network Manager только администратору

Создаём 60-sysvinit-nm.rules в директории /etc/polkit-1/rules.d

polkit.addRule(function(action, subject) {
  if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 )) {
    return polkit.Result. AUTH_ADMIN;}
});

Добавление и изменение настроек принтера всем пользователям без ввода пароля

Создаём 40-allow-passwordless-printer-admin.rules в директории /etc/polkit-1/rules.d:

polkit.addRule(function(action, subject) {
   if (action.id == "org.opensuse.cupspkhelper.mechanism.all-edit" && subject.isInGroup("users")){
      return polkit.Result.YES;}
});

Если вы нашли ошибку, выделите текст и нажмите Ctrl+Enter.

Print Friendly, PDF & Email