【问题标题】:Executing Jobs as other user以其他用户身份执行作业
【发布时间】:2017-03-04 13:13:29
【问题描述】:

通常以其他用户身份执行作业,我们可以执行sudo -u <user> <cmd>。但是,如果是永久过程,我们必须这样做:

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...]

好像不行!

【问题讨论】:

    标签: node.js unix ubuntu forever setuid


    【解决方案1】:

    第一个:

    exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters]
    

    以非 root 用户身份启动 upstart 作业旨在允许更改用户 ID 而不会留下中间进程;所以它以以下方式运行:

    • exec su -s sh
      用 su 替换调用此命令的进程,运行 shell sh
    • -c 'exec "$0" "$@"'
      从shell的调用shexec--之后传递的命令和参数($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...]
    

    为什么它不起作用?好吧,您已经要求它做一些不同的事情;在这种情况下;您要求它从 shell bash 运行命令 bash

    因为您没有传入$0$@,所以-- 之后的所有内容都将被忽略,因为它没有传入-c 以供调用的shell。

    有和没有 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
    

    添加内部 exec (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 与先前 bash 调用中存在的 pid 相同的事实:

    bash,1
      `-su,1014 -s /bin/sh -c exec "$0" "$@" proxy -- pstree -aApl
          `-pstree,1022 -aApl
    

    【讨论】:

    • 感谢您的回复。 1. 你能告诉我为什么使用它的高级想法(我看到 exec 替换当前进程的示例)和 2. 为什么sudo -u <user-id> cmd 在这里不起作用。在我的情况下,我正在运行命令 sudo su -s <my-app-id> forever list,它始终与 shell 上的 my-app-id 一起使用?
    • 1. su 比 sudo 更“标准”;通常,默认情况下您会在系统上找到 su,而 sudo 是一个附加组件。 su 被认为是 shell 支持的“正确方法”来更改正在运行的命令的用户 ID。示例中提供的表单是一个简单的模板。您只需插入用户名、-- 之后的命令和参数,它适用于您可能想要运行的任何命令 2. 现代系统上 sudo 的默认配置是需要一个伪终端才能运行,并且从 launchd/upstart/init 启动的东西不会有终端。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多