Как запустить сервис init.d под systemd без рут-аутентификации (обновлено)

7492
user5860663

Моя компания установила какое-то программное обеспечение, которое разрабатывает для запуска в качестве службы с использованием init.d в более старой версии SLES. Недавно мы начали настройку новой среды на экземпляре SLES 12 в Amazon EC2 и обнаружили, что SLES 12 теперь использует systemd, а не init.d. Однако, похоже, что службы, определенные в скриптах init.d (то есть в /etc/init.d), все еще могут запускаться как обычно, потому что systemd выполняет некоторую магию в фоновом режиме для обработки уже существующих скриптов init.d, что замечательно.

Однако мы не хотим запускать наш сервис от имени пользователя root - вместо этого мы создаем нового пользователя для запуска нашего сервиса. Проблема заключается в том, что когда мы пытаемся запустить наш сервис от имени пользователя без полномочий root, то все, что делает systemd, чтобы подготовиться к запуску старой службы init.d, запрашивает аутентификацию root, что, по нашему мнению, не требуется. В более старой среде SLES (с использованием фактического init.d) мы можем без проблем запустить службу от имени пользователя без полномочий root. Насколько я могу судить, наши права доступа без полномочий root и права владения файлами одинаковы в обеих средах.

Причина, по которой я думаю, что это скрытая обработка старой вещи init.d системой systemd, заключается в том, что скрипт для запуска нашего сервиса отображает строку текста непосредственно перед фактической командой для запуска / остановки сервиса, но эта строка не выводится, т. е. у нас запрашивают root-аутентификацию перед оператором echo. Аутентификация требуется для определенного пакета / модуля, похороненного в systemd, но я не могу вспомнить его имя в данный момент.

Обратите внимание, что мы хотели бы избежать создания специфичного для сервиса файла .service для нашего сервиса, если это возможно - мы хотим придерживаться имеющегося у нас скрипта init.d и просто запустить его как пользователь без полномочий root. Кроме того, мы хотели бы запустить сервис без использования sudo (нам не нужен sudo в старой среде).

Извиняюсь за отсутствие деталей в этом вопросе - я обновлю его более конкретными деталями, как только вернусь в офис и смогу взять конкретные детали и т. Д. Кажется, что это может быть распространенной проблемой, хотя, я надеюсь, кто-то может пролить свет на это.

В частности: мы хотим запустить службу, определенную старым сценарием init.d, как пользователь без полномочий root, используя systemd в SLES 12.

(обновление 1) Точный результат попытки запустить наш скрипт /etc/init.d/my_service stop:

/etc/init.d/my_service остановка
перенаправления на systemctl stop electrum-gateway-main.service
==== АУТЕНТИФИКАЦИЯ ДЛЯ org.freedesktop.systemd1.manage-units === Аутентификация необходима для остановки «my_service.service».
Аутентификация как: root
Пароль:

Служба не работала, когда мы пытались ее остановить, но это не относится к проблеме аутентификации.

Я немного покопался в нашем сценарии, и сценарий достигает следующей строки, прежде чем запрашивать auth:

. /etc/rc.status 

Так вот в чем проблема. Нужны ли права суперпользователя для вызова /etc/rc.status?

5

2 ответа на вопрос

6
grawity

В systemd (и других современных системах инициализации) запуск службы строго разделен на два этапа:

  1. Инструменты пользователя (например, systemctl) удаленно запрашивают init (pid 1) для запуска определенной службы.
  2. Init читает конфигурацию службы, настраивает среду (включая переключение на нужную учетную запись пользователя) и запускает исполняемый файл.

Из-за этой косвенности сервисы всегда будут иметь одинаковую среду независимо от того, кто и как их запустил. (Раньше обычная проблема - пользовательская среда, такая как контексты локали, пути или SELinux, просачивающиеся в сервисы).

(Для сценариев init.d файл lsb-functions дистрибутива содержит магические перенаправления на «запуск systemctl», поэтому они также получают ту же косвенную информацию.)

Это также означает, что вы не можете запустить службу «как тот же пользователь» - вы должны настроить конкретное имя пользователя в соответствующем файле systemd .service (и если его нет, вам действительно следует написать его).

Вызов 'start service' обычно является привилегированным, но вы можете написать правило polkit, разрешающее его для каждого пользователя или для каждого сервиса (если версия systemd достаточно свежая):

/* /etc/polkit-1/rules.d/allow-whatever.rules */  polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units") { var verb = action.lookup("verb"); var unit = action.lookup("unit"); if (subject.user == "manager" && unit == "app.service" && (verb == "start" || verb == "stop" || verb == "restart")) { return polkit.Result.YES; } } }); 

В качестве альтернативы можно было бы отказаться от косвенного обращения в сценарии init.d, но тогда вы также полностью потеряете отслеживание службы systemd - ваш демон будет выглядеть как обычный пользовательский процесс.

Итак, поскольку я не указал пользователя через файл .service, systemd заканчивает тем, что пытался запустить службу, используя root для команды start service? user5860663 7 лет назад 0
Да. Но это не имеет абсолютно никакого отношения к показанной подсказке пароля. Для запуска службы вам нужно иметь права root (или права polkit) для _ask_ systemd. grawity 7 лет назад 0
Работает как шарм! flotto 6 лет назад 0
0
Mark Stosberg

Запускать ваши сервисы как пользователь без полномочий root - хорошая идея. Помимо предложения Polkit в другом ответе, есть пара более традиционных способов запуска службы, не являющейся root:

  1. Используйте sudo . Правило Судо может позволить конкретному пользователю для запуска startи restartкоманд для конкретной службы, но не делать никаких действий, как корень, обеспечивая такую же ограниченную привилегию.
  2. Используйте userрежим systemd . systemd предлагает пользователям возможность управлять службами под управлением пользователя с помощью экземпляра systemd для каждого пользователя, позволяя пользователям запускать, останавливать, включать и отключать свои собственные устройства.

Я думаю, что системный пользовательский режим может существовать больше с учетом настольных сценариев использования. Для сервера я рекомендую разрешить использование sudoрешения. В .serviceфайле systemd вы также можете установить User=директиву для указания пользователя, от имени которого запускается служба, - возможно, того же пользователя, у которого вы могли его запустить.

Решение «polkit» - это решение на расстоянии - кажется, трудно понять, что позволяет пользователю запускать службу. Тем не менее, sudoвы явно звоните по телефону sudo, и systemd user modeвы явно используете эту функцию.

Если бы я находился в среде, где было разработано решение Polkit, я бы не мог понять, почему запуск службы работал, если только коллега не оставил некоторую документацию об этом.

Похожие вопросы