Polkit: различия между версиями

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


Polkit (прежнее название: PolicyKit) — библиотека для UNIX-подобных операционных систем. API библиотеки используется для предоставления непривилегированным процессам возможности выполнения действий, требующих прав администратора. Использование Polkit противопоставляется использованию таких систем, как sudo, но не наделяет процесс пользователя правами администратора, а позволяет точно контролировать, что разрешено, а что запрещено.
== Настройка ==
 
Архитектура Polkit оперирует двумя видами понятий — действия (actions) и правила (rules).
 
=== Действия polkit ===
 
Действия (actions) определены в XML-файлах .policy, расположенных в каталоге /usr/share/polkit-1/actions. Для каждого действия указан набор разрешений по умолчанию.
 
Действия, доступные через polkit, зависят от установленных пакетов. Некоторые из них используются в нескольких средах рабочего стола (org.freedesktop.*), некоторые специфичны для конкретной среды рабочего стола (org.gnome.*), а некоторые специфичны для одной программы (org.xfce.thunar). Вывести список всех действий, определённых в {{path|/usr/share/polkit-1/actions}} можно, выполнив команду {{cmd|pkaction}}.
 
Все политики находятся в {{path|/usr/share/polkit-1/actions/}} в формате ''*.policy''  Каждая политика представляет собой xml-файл, в котором описываются запросы к ''polkit''.  


===Политики polkit===
Каждое действие определяется в теге <action> в файле .policy. Например, файл {{path|org.freedesktop.UDisks2.policy}} содержит несколько действий. Пример действия:


Все политики находятся в ''/usr/share/polkit-1/actions/'' в формате ''*.policy'' Каждая политика представляет собой xml-файл, в котором описываются запросы к ''polkit''. Каждый запрос имеет три условия, прописанных в секции ''defaults'':
<syntaxhighlight lang="xml">
<action id="org.freedesktop.udisks2.filesystem-mount-system">
    <description>Mount a filesystem on a system device</description>
    <description xml:lang="ru">Монтировать файловую систему на системном устройстве</description>
    <message>Authentication is required to mount the filesystem</message>
    <message xml:lang="ru">Для монтирования файловой системы требуется подтверждение подлинности пользователя</message>
    <message>Authentication is required to mount the filesystem</message>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
  </action>
</syntaxhighlight>


1. Запрос от любого пользователя. Тег ''<allow_any>''
Элементы, которые используются внутри действия:
* атрибут ''id'' — команда, посылаемая в DBus;
* тег ''description'' — описание действия;
* тег ''message'' — сообщение, отображаемое пользователю при запросе учетных данных, когда требуется аутентификация;
* тег ''defaults'' — описывает параметры, установленные по умолчанию. Тег ''defaults'' содержит три параметра:
** тег ''allow_any'' — запрос от любого пользователя.  
** тег ''allow_inactive'' — запрос от неактивного пользователя (неактивный сеанс — это, как правило, удалённые сеансы SSH, VNC и т.д.);
** тег ''allow_active'' — запрос от активного пользователя (активные сеанс — это вход, выполненный непосредственно на машине через TTY или X).


2. Запрос от неактивного пользователя. Тег ''<allow_inactive>''
Каждый из элементов ''allow_any'', ''allow_inactive'' и ''allow_active'' может содержать следующие значения:
*  '''yes''' — предоставить разрешения;
*  '''no''' — заблокировать разрешения;
*  '''auth_self''' — пользователь должен ввести свой пароль для аутентификации (обратите внимание, что этого разрешения недостаточно для большинства применений в многопользовательских системах, обычно рекомендуется разрешение '''auth_admin''');
*  '''auth_self_keep''' — пользователь должен ввести свой пароль для аутентификации, авторизация сохраняется на несколько минут (обратите внимание, что этого разрешения недостаточно для большинства применений в многопользовательских системах, обычно рекомендуется разрешение '''auth_admin_keep''');
*  '''auth_admin''' — пользователь должен ввести пароль администратора при каждом запросе;
*  '''auth_admin_keep''' — пользователь должен ввести пароль администратора, авторизация сохраняется на несколько минут.


3. Запрос от активного пользователя ''<allow_active>''
=== Правила polkit ===
Правила авторизации (authorization rules) определены в JavaScript-файлах .rules. Polkit читает правилами из двух каталогов {{path|/usr/share/polkit-1/rules.d}} и {{path|/etc/polkit-1/rules.d}}, сортируя файлы в лексическом порядке на основе базового имени (если имена совпадают, файлы в {{path|/etc}} обрабатываются раньше файлов в {{path|/usr}}). Например, для следующих четырех файлов порядок следующий:
* {{path|/etc/polkit-1/rules.d/10-auth.rules}}
* {{path|/usr/share/polkit-1/rules.d/10-auth.rules}}
* {{path|/etc/polkit-1/rules.d/15-auth.rules}}
* {{path|/usr/share/polkit-1/rules.d/20-auth.rules}}


Внутри каждого тега прописывается возвращаемое значение. Используются следующие варианты значений:
Менять стандартные правила polkit нельзя, так как при обновлении системы они могут быть перезаписаны. Необходимо создавать собственные правила в {{path|/etc/polkit-1/rules.d/}} в формате ''*.rules''. Правила выполняются в порядке названия по алфавиту, поэтому вначале пишутся цифры, чтобы указать приоритет правила.
 
'''yes''' - предоставить разрешения


* '''no''' - заблокировать разрешения
Структура файлов .rules:
<syntaxhighlight lang="ini">
polkit.addRule(function(action, subject) {
if (action.id == "policy" && vashe_uslovie {
return polkit.Result.YES;
};
});
</syntaxhighlight>
где
* addRule() — используется для добавления функции, которая может вызываться всякий раз, когда выполняется проверка авторизации действия и субъекта;
* ''policy'' — название политики, поведение которой нужно изменить;
* ''vashe_uslovie'' — условие, если нужно изменить поведение политики для одного пользователя пишем subject.user == '%username%', если для группы, то subject.isInGroup('%groupname%');
* ''polkit.Result.YES'' означает, что политика будет при выполнении условия правила предоставлять разрешение.


* '''auth_self''' - пользователь должен ввести свой пароль для аутентификации
Каждая функция должна возвращать одно из значений, соответствующие значениям, которые можно использовать в качестве значений по умолчанию:
* NO;
* YES;
* AUTH_SELF;
* AUTH_SELF_KEEP;
* AUTH_ADMIN;
* AUTH_ADMIN_KEEP;
* NOT_HANDLED;
Если правило возвращает polkit.Result.NOT_HANDLED, null, undefined или вообще не возвращает значение, пробуется следующая пользовательская функция.


*  '''auth_self_keep_session''' - пользователь должен ввести свой пароль для аутентификации один раз за сессию, разрешение предоставляется для всей сессии
=== Журналирование действий polkit ===


'''auth_self_keep_always''' - пользователь должен ввести свой пароль для аутентификации один раз, разрешение предоставляется для текущей и будущих сессий
Используя правила polkit можно также делать записи в системный журнал. Метод log() записывает сообщение в системный журнал.
Пример:
<syntaxhighlight lang="ini">
polkit.addRule(function(action, subject) {
    if (action.id == "действие") {
        polkit.log("action=" + action);
        polkit.log("subject=" + subject);
}
});
</syntaxhighlight>
В параметре ''action'' передается объект с информацией о совершенном процессе и связанные с этим действием параметры (например, если запрошенное действие монтирование съемного диска, то в параметре action будут переданы серийный номер диска, его id, файловая система и т.д).


'''auth_admin''' - пользователь должен ввести пароль root при каждом запросе разрешения
В параметре ''subject'' передается объект с информацией о пользователе, запустившем процесс.
Этот объект имеет следующие атрибуты:
* id — идентификатор процесса;
* user — имя пользователя;
* groups — список групп, в которые входит пользователь;
* seat — местонахождение субъекта (пустое значение, если местонахождение не локальное);
* session — сессия субъекта;
* local — true, только если местонахождение имеет локальный характер;
* active — true, только если сеанс активен.


*  '''auth_admin_keep_session''' - пользователь должен ввести пароль root, разрешение предоставляется для всей сессии
=== Определение администраторов ===
Администратор — в Альт определён в правиле {{path|/etc/polkit-1/rules.d/50-default.rules}}:


*  '''auth_admin_keep_always''' - пользователь должен ввести пароль root, разрешение предоставляется для текущей и будущих сессий
<syntaxhighlight lang="ini">
polkit.addAdminRule(function(action, subject) {
        return ["unix-group:wheel"];
});
</syntaxhighlight>


=== Правила polkit ===
По умолчанию, запрашивается пароль пользователя, находящегося в группе wheel. Для того, чтобы запрашивался пароль root, необходимо добавить правило с числом меньше 50 в начале имени (т.к. конфигурация по умолчанию находится в файле {{path|50-default.rules}}) с таким содержанием:
 
<syntaxhighlight lang="ini">
polkit.polkit (function(action, subject) {
        return ["unix-user:root"];
});
</syntaxhighlight>
 
Правило должно возвращать массив строк, где каждая строка имеет вид ''unix-group:<группа>'', ''unix-netgroup:<сетевая группа>'' или ''unix-user:<пользователь>''. Если правило возвращает null, undefined или вообще не возвращает значение, пробуется следующее правило.
 
== Примеры ==
Пользователи часто жалуются на необходимость вводить пароль при монтировании разделов в файловом менеджере и создании нового подключения в NetworkManager, а также невозможность извлечь usb-диск или лоток оптического привода. За эти разрешения отвечают:


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


1. Для начала определяем какую политику мы хотим изменить, для этого находим в ''/usr/share/polkit-1/actions/'' требуемую.
''org.freedesktop.udisks2.filesystem-mount-other-seat'' — разрешение на монтирование файловых систем пользователям, подключенным не к основному рабочему месту


2. Создаём новое правило:
''org.freedesktop.udisks2.eject-media-other-seat'' — разрешение на извлечение лотка оптического привода пользователям, подключенным не к основному рабочему месту


<source lang="bash">
''org.freedesktop.udisks2.power-off-drive-other-seat'' — разрешение на извлечение usb-диска пользователям, подключенным не к основному рабочему месту
touch /etc/polkit-1/rules.d/99-vashe_pravilo.rules
</source>


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


<source lang="bash">
mcedit /etc/polkit-1/rules.d/55-mount.rules
</source>


4. Вставляем такой текст:
{{note|Устройства хранения информации, делятся на системные, которые не считаются извлекаемыми, и несистемные, к которым относятся USB подключаемые накопители, Flash медиа и оптические приводы. Для каждой из групп устройств, системных и несистемных (т.н. извлекаемых — removable), для одной операции часто нужно два polkit actions, по одному на группу устройств.


<source lang="javascript">
Чтобы узнать является ли устройство системным, на которые распространяется действие ''org.freedesktop.udisks2.filesystem-mount-system'', выполните сначала команду, которая выведет все подключенные накопители:
polkit.addRule(function(action, subject) {
if (action.id == "policy" && vashe_uslovie {
return polkit.Result.YES;
};
});
</source>
где


* вместо ''policy'' пишем название политики, поведение которой нужно изменить
<syntaxhighlight lang="bash">
* вместо ''vashe_uslovie'': если нужно изменить поведение политики для одного пользователя пишем subject.user == '%username%', если для группы, то subject.isInGroup('%groupname%')
$ udisksctl status
* ''polkit.Result.YES'' означает, что политика будет при выполнении условия правила предоставлять разрешение.
MODEL                    REVISION  SERIAL              DEVICE
--------------------------------------------------------------------------
Micron MTFDKCD512TFK      0002V5LN  22293A5BBD07        nvme0n1
</syntaxhighlight>


=== Примеры ===
Затем команду с именем вашего устройства. Например ''/dev/nvme0n1''. Статус ''true'' для ''HintSystem'', в выводе команды говорит, что это системное устройство:
Пользователи часто жалуются на необходимость вводить пароль при монтировании разделов в файловом менеджере и создании нового подключения в NetworkManager. За эти разрешения отвечают соответственно org.freedesktop.udisks2.filesystem-mount-system и org.freedesktop.NetworkManager.settings.modify.system Сделаем так, чтобы если пользователь находится в системной группе xgrp, то для него запросы пароля не должны будут выполняться для этих действий. Для этого (все действия выполняются от root):


1. Создать два правила 99-udisk2_mount.rules и 99-networkmanager.rules
<syntaxhighlight lang="bash">
$ udisksctl info -b /dev/nvme0n1|grep ' Device:\|HintSystem'
    Device:                    /dev/nvme0n1
    HintSystem:                true
</syntaxhighlight>


<source lang="bash">
Для несистемных устройств, на которые распространяется действие ''org.freedesktop.udisks2.filesystem-mount-other-seat'', для ''HintSystem'' статус будет ''false''}}
touch /etc/polkit-1/rules/99-udisk2_mount.rules 99-networkmanager.rules
</source>


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


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


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


<source lang="bash">
#Наполнить {{path|99-udisk2_mount.rules}} таким содержанием:
groupadd -r xgrp
#:<syntaxhighlight lang="ini">polkit.addRule(function(action, subject) {
</source>
        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;
        };
});
</syntaxhighlight>
#Перелогиниться.


5 Добавить пользователя в группу xgrp:
При монтировании USB-диска в системном журнале появятся записи:


<source lang="bash">
<syntaxhighlight lang="ini">
gpasswd -a имя_пользователя xgrp
Nov 22 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']
</source>
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]
</syntaxhighlight>


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


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


1. [https://ru.wikipedia.org/wiki/Polkit Polkit. Статья в Википедии]
<syntaxhighlight lang="bash">
# journalctl |grep  "drive.serial='11101094E6BA1A00A4A5200A'"
</syntaxhighlight>


2. [http://lampslave.ru/2-words-about-polkit/ Пара слов о polkit]
== Ссылки ==
# [https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html Документация Polkit]
# [https://ru.wikipedia.org/wiki/Polkit Polkit. Статья в Википедии]
# [http://udisks.freedesktop.org/docs/latest/udisks-polkit-actions.html Отличие системных устройств от извлекаемых (англ.яз.)]


[[Категория:admin]]
[[Категория:Admin]]
{{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}}

Текущая версия от 12:00, 1 июня 2023

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

Настройка

Архитектура Polkit оперирует двумя видами понятий — действия (actions) и правила (rules).

Действия polkit

Действия (actions) определены в XML-файлах .policy, расположенных в каталоге /usr/share/polkit-1/actions. Для каждого действия указан набор разрешений по умолчанию.

Действия, доступные через polkit, зависят от установленных пакетов. Некоторые из них используются в нескольких средах рабочего стола (org.freedesktop.*), некоторые специфичны для конкретной среды рабочего стола (org.gnome.*), а некоторые специфичны для одной программы (org.xfce.thunar). Вывести список всех действий, определённых в /usr/share/polkit-1/actions можно, выполнив команду pkaction.

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

Каждое действие определяется в теге <action> в файле .policy. Например, файл org.freedesktop.UDisks2.policy содержит несколько действий. Пример действия:

<action id="org.freedesktop.udisks2.filesystem-mount-system">
    <description>Mount a filesystem on a system device</description>
    <description xml:lang="ru">Монтировать файловую систему на системном устройстве</description>
    <message>Authentication is required to mount the filesystem</message>
    <message xml:lang="ru">Для монтирования файловой системы требуется подтверждение подлинности пользователя</message>
    <message>Authentication is required to mount the filesystem</message>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
 </action>

Элементы, которые используются внутри действия:

  • атрибут id — команда, посылаемая в DBus;
  • тег description — описание действия;
  • тег message — сообщение, отображаемое пользователю при запросе учетных данных, когда требуется аутентификация;
  • тег defaults — описывает параметры, установленные по умолчанию. Тег defaults содержит три параметра:
    • тег allow_any — запрос от любого пользователя.
    • тег allow_inactive — запрос от неактивного пользователя (неактивный сеанс — это, как правило, удалённые сеансы SSH, VNC и т.д.);
    • тег allow_active — запрос от активного пользователя (активные сеанс — это вход, выполненный непосредственно на машине через TTY или X).

Каждый из элементов allow_any, allow_inactive и allow_active может содержать следующие значения:

  • yes — предоставить разрешения;
  • no — заблокировать разрешения;
  • auth_self — пользователь должен ввести свой пароль для аутентификации (обратите внимание, что этого разрешения недостаточно для большинства применений в многопользовательских системах, обычно рекомендуется разрешение auth_admin);
  • auth_self_keep — пользователь должен ввести свой пароль для аутентификации, авторизация сохраняется на несколько минут (обратите внимание, что этого разрешения недостаточно для большинства применений в многопользовательских системах, обычно рекомендуется разрешение auth_admin_keep);
  • auth_admin — пользователь должен ввести пароль администратора при каждом запросе;
  • auth_admin_keep — пользователь должен ввести пароль администратора, авторизация сохраняется на несколько минут.

Правила polkit

Правила авторизации (authorization rules) определены в JavaScript-файлах .rules. Polkit читает правилами из двух каталогов /usr/share/polkit-1/rules.d и /etc/polkit-1/rules.d, сортируя файлы в лексическом порядке на основе базового имени (если имена совпадают, файлы в /etc обрабатываются раньше файлов в /usr). Например, для следующих четырех файлов порядок следующий:

  • /etc/polkit-1/rules.d/10-auth.rules
  • /usr/share/polkit-1/rules.d/10-auth.rules
  • /etc/polkit-1/rules.d/15-auth.rules
  • /usr/share/polkit-1/rules.d/20-auth.rules

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

Структура файлов .rules:

 polkit.addRule(function(action, subject) {
	if (action.id == "policy" && vashe_uslovie {
		return polkit.Result.YES;
	};
});

где

  • addRule() — используется для добавления функции, которая может вызываться всякий раз, когда выполняется проверка авторизации действия и субъекта;
  • policy — название политики, поведение которой нужно изменить;
  • vashe_uslovie — условие, если нужно изменить поведение политики для одного пользователя пишем subject.user == '%username%', если для группы, то subject.isInGroup('%groupname%');
  • polkit.Result.YES означает, что политика будет при выполнении условия правила предоставлять разрешение.

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

  • NO;
  • YES;
  • AUTH_SELF;
  • AUTH_SELF_KEEP;
  • AUTH_ADMIN;
  • AUTH_ADMIN_KEEP;
  • NOT_HANDLED;

Если правило возвращает polkit.Result.NOT_HANDLED, null, undefined или вообще не возвращает значение, пробуется следующая пользовательская функция.

Журналирование действий 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, только если сеанс активен.

Определение администраторов

Администратор — в Альт определён в правиле /etc/polkit-1/rules.d/50-default.rules:

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

По умолчанию, запрашивается пароль пользователя, находящегося в группе wheel. Для того, чтобы запрашивался пароль root, необходимо добавить правило с числом меньше 50 в начале имени (т.к. конфигурация по умолчанию находится в файле 50-default.rules) с таким содержанием:

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

Правило должно возвращать массив строк, где каждая строка имеет вид unix-group:<группа>, unix-netgroup:<сетевая группа> или unix-user:<пользователь>. Если правило возвращает null, undefined или вообще не возвращает значение, пробуется следующее правило.

Примеры

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

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-диска пользователям, подключенным не к основному рабочему месту

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


Примечание: Устройства хранения информации, делятся на системные, которые не считаются извлекаемыми, и несистемные, к которым относятся USB подключаемые накопители, Flash медиа и оптические приводы. Для каждой из групп устройств, системных и несистемных (т.н. извлекаемых — removable), для одной операции часто нужно два polkit actions, по одному на группу устройств.

Чтобы узнать является ли устройство системным, на которые распространяется действие org.freedesktop.udisks2.filesystem-mount-system, выполните сначала команду, которая выведет все подключенные накопители:

$ udisksctl status
MODEL                     REVISION  SERIAL               DEVICE
--------------------------------------------------------------------------
Micron MTFDKCD512TFK      0002V5LN  22293A5BBD07         nvme0n1

Затем команду с именем вашего устройства. Например /dev/nvme0n1. Статус true для HintSystem, в выводе команды говорит, что это системное устройство:

$ udisksctl info -b /dev/nvme0n1|grep ' Device:\|HintSystem'
    Device:                     /dev/nvme0n1
    HintSystem:                 true
Для несистемных устройств, на которые распространяется действие org.freedesktop.udisks2.filesystem-mount-other-seat, для HintSystem статус будет false


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

Сделаем так, чтобы если пользователь находится в системной группе 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" && subject.isInGroup("xgrp")) {
    		return polkit.Result.YES;
    	};
    	if (action.id == "org.freedesktop.udisks2.filesystem-mount-other-seat" && subject.isInGroup("xgrp")) {
    		return polkit.Result.YES;
    	};
            if (action.id == "org.freedesktop.udisks2.eject-media-other-seat" && subject.isInGroup("xgrp")) {
            	return polkit.Result.YES;
            };
            if (action.id == "org.freedesktop.udisks2.power-off-drive-other-seat" && subject.isInGroup("xgrp")) {
            	return polkit.Result.YES;
            };
    });
    
  2. Наполнить /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;
    	};
    });
    
  3. Создать системную группу xgrp (если её ещё нет):
    # groupadd -r xgrp
    
  4. Добавить пользователя в группу xgrp:
    # gpasswd -a имя_пользователя xgrp
    
  5. Перелогиниться

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

Пример создания правила, разрешающего пользователю выполнять монтирование и извлечение устройств — с запросом пароля (при указании 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. Перелогиниться.

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

Nov 22 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'"

Ссылки

  1. Документация Polkit
  2. Polkit. Статья в Википедии
  3. Отличие системных устройств от извлекаемых (англ.яз.)