#node.js #unix #ubuntu #forever #setuid
#node.js #unix #ubuntu #навсегда #setuid
Вопрос:
Обычно мы можем выполнять задания от имени другого пользователя sudo -u <user> <cmd>
. Однако в случае процесса forever мы должны поступить таким образом:
exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]
Ссылка:https://superuser.com/questions/213416/running-upstart-jobs-as-unprivileged-users
Чем это отличается? Что это значит? Кроме того:
su -s /bin/bash -c bash username -- /path/to/command [parameters...]
похоже, не работает!
Ответ №1:
Первый:
exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters]
для запуска upstart
заданий от имени пользователя, отличного от root, предназначено разрешить изменение идентификатора пользователя, не прерывая промежуточные процессы; поэтому оно выполняется следующим образом:
exec su -s sh
заменяет процесс, вызывающий эту команду, на su, запуская оболочкуsh
-c 'exec "$0" "$@"'
при вызове командной оболочкиsh
exec
команда и параметры передаются после--
($0
это первый параметр в командной строке, после--
,$@
это все, что после этого)
Конечный продукт этого выполняется, /path/to/command
как если бы он был вызван непосредственно из username
указанной команды; в результате чего дерево процессов выглядит как:
su [as root] -> /path/to/command [as username]
Если бы вы не вызывали его с помощью exec
, то в итоге у вас получилось бы дерево процессов, выглядящее как:
upstart_launcher [as root] -> su [as root] -> sh [as username] -> /path/to/command [as username]
(Я не знаю, как будет выглядеть процесс upstart_launcher на этом этапе; у меня нет системы с upstart, чтобы проверить это; но процесс останется)
Теперь важным элементом этого является то, что он просто вызывает exec /path/to/command [arguments…]
, как если бы он был введен подобным образом из командной строки.
Когда мы сравниваем это со второй командной строкой, большая часть происходящего похожа, но не совсем одинакова:
su -s /bin/bash -c bash username -- /path/to/command [parameters...]
Почему это не работает? Ну, вы попросили его сделать что-то другое; в данном случае; вы просите его выполнить команду bash
из командной строки bash
.
Поскольку вы не передали в $0
или $@
--
, все, что после -c
, игнорируется, потому что это не передается в в для вызываемой оболочки.
Примеры работы с exec и без exec
Это сворачивает дерево процессов, удаляя промежуточное звено sh
— это вспомогательный механизм для предотвращения глубоких деревьев процессов.
пропуск всех исполнителей ( su -s /bin/sh -c '"$0" "$@"' proxy -- pstree -aApl
):
bash,1
`-bash,1014
`-su,1017 -s /bin/sh -c "$0" "$@" proxy -- pstree -aApl
`-sh,1018 -c "$0" "$@" pstree -aApl
`-pstree,1019 -aApl
Добавление внутреннего исполнителя ( su -s /bin/sh -c 'exec "$0" "$@"' proxy -- pstree -aApl
) — обратите внимание на отсутствие второго уровня sh
:
bash,1
`-bash,1014
`-su,1020 -s /bin/sh -c exec "$0" "$@" proxy -- pstree -aApl
`-pstree,1021 -aApl
Добавление внутреннего и внешнего exec ( exec su -s /bin/sh -c 'exec "$0" "$@"' proxy -- pstree -aApl
) — обратите внимание на отсутствующий внешний уровень bash
и тот факт, что 1014
pid совпадает с pid, который присутствовал в предыдущем вызове bash:
bash,1
`-su,1014 -s /bin/sh -c exec "$0" "$@" proxy -- pstree -aApl
`-pstree,1022 -aApl
Комментарии:
1. Спасибо за ваш ответ. 1. Можете ли вы рассказать мне идею высокого уровня, почему это используется (я вижу пример exec, заменяющий текущий процесс) и 2. Почему
sudo -u <user-id> cmd
здесь не работает. В моем случае я запускаю команду,sudo su -s <my-app-id> forever list
которая всегда работает сmy-app-id
в командной строке?2. 1. su является более «стандартным», чем sudo; обычно вы найдете su в системах по умолчанию, в то время как sudo является дополнительным компонентом. su считается поддерживаемым оболочкой «правильным способом» изменения идентификатора пользователя запускаемой команды. Форма, которая была предоставлена в примере, была простым шаблоном. Вы просто вводите имя пользователя, а также команду и параметры после
--
, и это работает для любой команды, которую вы, возможно, захотите запустить 2. Конфигурация sudo по умолчанию в современных системах заключается в том, чтобы требовать псевдотерминал, прежде чем он заработает, и вещи, запущенные из launchd / upstart / init, не будут иметь терминала.