Вопрос или проблема
Я написал службу dbus и настроил её на прослушивание системной шины, под именем “org.jfhbrook.plusdeck” и с путём “/”. Это, похоже, работает нормально. У меня есть соответствующий клиент dbus, который я хотел бы использовать для взаимодействия с этой службой системной шины, либо если я root-пользователь (вызванный с помощью sudo), либо если я нахожусь в определённой группе (в данном случае, группа “plusdeck”).
В настоящее время у меня есть этот файл политики, основанный на документации dbus-daemon и составленный из примеров, которые я смог найти:
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Root пользователь может владеть службой plusdeck -->
<policy user="root">
<allow own="org.jfhbrook.plusdeck"/>
<allow send_destination="org.jfhbrook.plusdeck"/>
</policy>
<!-- Разрешить доступ для группы "plusdeck" -->
<policy group="plusdeck">
<allow send_destination="org.jfhbrook.plusdeck"/>
</policy>
</busconfig>
Это работает, когда я использую sudo
. Однако, когда я пользуюсь тем же клиентом со своим пользователем, который является членом группы plusdeck
, я получаю ошибку:
ERROR:plusdeck.dbus.client:org.freedesktop.DBus.Error.AccessDenied: Access to org.jfhbrook.plusdeck.Eject() not permitted.
Обратите внимание, что это ошибка отличается от той, которую я получил бы, если бы не имел доступа к шине – это была бы ошибка ERROR:plusdeck.dbus.client:org.freedesktop.DBus.Error.AccessDenied: Sender is not authorized to send message
. Похоже, что мне разрешено отправлять сообщения, но не вызывать этот метод.
Я пробовал все комбинации, которые только мог придумать, включая установку send_member="*"
в теге разрешения, а также <allow send_type="method_call"/>
. Я на пределе своих возможностей. Любая помощь или руководство были бы полезны.
К слову, я использую Fedora 41. Упоминаю это, так как знаю, что проблема может быть за пределами этой конфигурации, например, связана с SELinux. Однако, я считаю, что отсутствие записей в /var/log/audit/audit.log
исключает это.
Обновление, 8 февраля 2025
Я провел дополнительное расследование и предполагаю, что проблема не в политике dbus как таковой, а в systemd и polkit.
Во-первых, если я интроспектирую свой интерфейс, я могу видеть, что методы аннотированы с “org.freedesktop.systemd1.Privileged”:
<method name="Eject">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
Я не нашел четкой документации по этому поводу – документация systemd здесь особенно… запутанная. Но похоже, что намерение заключается в том, чтобы systemd делегировал политику polkit. Доказательство тому – похожий разочарованный пользователь на GitHub и некоторые документы для C API, которые, как кажется, были предназначены для помощи.
С этой целью у меня есть политика polkit, которая выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<vendor>plusdeck</vendor>
<vendor_url>https://github.com/jfhbrook/plusdeck</vendor_url>
<action id="org.jfhbrook.plusdeck.Eject">
<message>Polkit no allow eject tho</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
</policyconfig>
Я также попытался написать правило на JavaScript:
polkit.addRule(function(action, subject) {
if ((action.id == "org.jfhbrook.plusdeck.Eject" ||
action.id == "org.jfhbrook.plusdeck.FastForwardA" ||
action.id == "org.jfhbrook.plusdeck.Pause" ||
action.id == "org.jfhbrook.plusdeck.PlayA" ||
action.id == "org.jfhbrook.plusdeck.PlayB" ||
action.id == "org.jfhbrook.plusdeck.Stop" ||
action.id == "org.jfhbrook.plusdeck.WaitFor") &&
subject.isInGroup("plusdeck")) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
Однако ни один из этих файлов, похоже, не имеет никакого эффекта, даже с учётом перезагрузок и перезапусков. Я также не вижу никаких логов, связанных с polkit – хотя я не совсем уверен, где искать.
Ответ или решение
Настройка политики доступа к системной службе DBus может быть сложной задачей, особенно если нужно обеспечить доступ для определенного пользователя или группы. В вашем случае, вы пытаетесь настроить политику доступа для группы пользователей "plusdeck", чтобы они могли взаимодействовать с системной службой, зарегистрированной на DBus под именем "org.jfhbrook.plusdeck". Давайте разберем ключевые моменты и возможные решения этой задачи.
Теория
DBus является межпроцессным механизмом для обмена сообщениями, который позволяет приложениям взаимодействовать друг с другом. Он имеет строгую систему контроля доступа, которая управляется через политические конфигурационные файлы. Эти файлы определяют, какие пользователи и группы могут взаимодействовать с конкретными службами DBus. Основной задачей является правильная настройка этих файлов, чтобы обеспечить необходимый уровень безопасности и доступности.
Вы уже создали базовую конфигурацию, позволяющую пользователю root и группе "plusdeck" отправлять сообщения, направленные на "org.jfhbrook.plusdeck". Однако возникла проблема при попытке управлять методом Eject, что, по всей видимости, связано с политикой systemd и polkit.
Пример
Ваша текущая конфигурация для DBus и polkit выглядит следующим образом:
-
Конфигурация DBus:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <!-- Root user can own the plusdeck service --> <policy user="root"> <allow own="org.jfhbrook.plusdeck"/> <allow send_destination="org.jfhbrook.plusdeck"/> </policy> <!-- Allow access for the "plusdeck" group --> <policy group="plusdeck"> <allow send_destination="org.jfhbrook.plusdeck"/> </policy> </busconfig>
-
Политика Polkit:
Политика polkit устанавливается для управления привилегированными действиями, такими как вызовы специфических методов:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> <policyconfig> <vendor>plusdeck</vendor> <vendor_url>https://github.com/jfhbrook/plusdeck</vendor_url> <action id="org.jfhbrook.plusdeck.Eject"> <message>Polkit no allow eject tho</message> <defaults> <allow_any>yes</allow_any> <allow_inactive>yes</allow_inactive> <allow_active>yes</allow_active> </defaults> </action> </policyconfig>
JavaScript правило для polkit:
polkit.addRule(function(action, subject) { if ((action.id == "org.jfhbrook.plusdeck.Eject" || action.id == "org.jfhbrook.plusdeck.FastForwardA" || action.id == "org.jfhbrook.plusdeck.Pause" || action.id == "org.jfhbrook.plusdeck.PlayA" || action.id == "org.jfhbrook.plusdeck.PlayB" || action.id == "org.jfhbrook.plusdeck.Stop" || action.id == "org.jfhbrook.plusdeck.WaitFor") && subject.isInGroup("plusdeck")) { return polkit.Result.YES; } return polkit.Result.NOT_HANDLED; });
Применение
-
Наладка конфигурации DBus:
Во-первых, ваша конфигурация DBus кажется корректной по части разрешений на отправку сообщений. Однако, для метода Eject может потребоваться дополнительно добавить
<allow send_interface="..."/>
или<allow send_member="Eject"/>
, чтобы разрешить доступ к конкретному методу. -
Роль Systemd и Polkit:
Ваша проблема, скорее всего, связана с тем, что метод Eject помечен аннотацией
org.freedesktop.systemd1.Privileged
, что вызывает интеграцию с системой авторизации polkit. Убедитесь, что политику polkit создана правильно и файлы находятся в нужной директории (обычно это/usr/share/polkit-1/actions/
для файлов конфигурации XML и/etc/polkit-1/rules.d/
для JavaScript правил). -
Диагностика и логирование:
Поскольку вы не видите записей в
/var/log/audit/audit.log
, следует сконцентрироваться на других логах, связанных с polkit и DBus. Убедитесь, что устройство использует правильные политические файлы, и проверьте статус процессов dbus-daemon и polkit, чтобы увидеть, если возникают ошибки при загрузке или применении политик. -
Отладка и протоколирование:
Политики polkit могут дать дополнительное протоколирование. Активируйте подробный лог polkit, чтобы фиксировать каждую операцию. Это может быть полезно для наблюдения за обработкой действий. Используйте команды вроде
pkcheck
для проверки разрешений отдельно.
Учитывая вышеизложенное, следует обратить внимание на интеграцию API системы с polkit для авторизации действий и отвергнуть возможные проблемы, связанные с размерами применения. Это комплексная задача, требующая тщательной диагностики и тестирования конфигурации вашей системы безопасности.