【问题标题】:Can my Python script distinguish between if it was run as root or if it was run through sudo?我的 Python 脚本能否区分它是以 root 身份运行还是通过 sudo 运行?
【发布时间】:2018-11-09 19:03:08
【问题描述】:
[root@hostname ~]# python script.py                  # allow this

[user@hostname ~]$ sudo python script.py             # deny this
[user@hostname ~]$ sudo -E python script.py          # deny this
[user@hostname ~]$ sudo PATH=$PATH python script.py  # deny this
[user@hostname ~]$ python script.py                  # kindly refuse this

我正在尝试实现上述行为。如果您关心原因或示例不够充分,请进一步阅读。很抱歉言辞犀利,但我的大多数 Stack Exchange 问题都得到了敌对的问题而不是答案。

这个问题源于需要管理员来运行我的脚本,但脚本的性质需要root 的环境变量(而不是sudo 的)。

我对此进行了深入研究...below is from this answer

if os.geteuid() == 0:
    pass  # sufficient to determine if elevated privileges

但后来我开始需要在我的脚本中访问PATH。我注意到了

sudo -E env | grep PATH; env | grep PATH

打印不同的PATH 值。我发现这是因为PATH 的安全策略。我还发现the workaroundPATHsudo PATH=$PATH ...

但是,它不是唯一受策略保护的环境变量,在这一点上,为什么要将此环境变量枚举推送给脚本用户?似乎明确要求root 是最好的方法,否则只需警告管理员在脚本中明确使用root

有没有这种方法可以用 Python 区分 rootsudo

【问题讨论】:

  • 根提示符应以“#”结尾。
  • @IgnacioVazquez-Abrams 已修复,我很傻。谢谢
  • @IgnacioVazquez-Abrams 不必。根提示以 PROMPT 变量告诉它的任何结尾。
  • “但是脚本的性质需要root的环境变量(而不是sudo的)”——然后检查你需要的环境变量?
  • @JaredSmith 使用username = commands.getoutput("echo $(whoami)") 作为sudo 返回root

标签: python environment-variables python-2.x sudo rhel


【解决方案1】:

尽管讨论了不采用此解决方案的原因,但实际上我确实为其他想知道it's possible 的人找到了它。

[user@hostname ~]$ sudo python
>>> import os
>>> os.environ["SUDO_UID"]  # UID of user running sudo
'uid'

当以 root 身份登录时...

[root@hostname ~]# python
>>> import os
>>> try:
...     uid = os.environ["SUDO_UID"]
        raise AssertionError("Ran with sudo")
... except KeyError, e:
...     ...  # SUDO_UID, SUDO_USER, etc. not set without sudo

我还有found 一种访问rootPATH 的方法,只是与sudo 一起运行。

path = os.popen("su - -c env | grep ^PATH= | cut -d'=' -f2-").read().strip()

我认为比起依赖脚本的运行方式,我更喜欢这个解决方案。

【讨论】:

    【解决方案2】:

    你会收到“敌对的问题”,因为你的问题的前提没有多大意义。一般来说,如果一个命令可以通过sudo以root用户身份运行,那么无论它是通过sudo(或runas等)还是通过其他将UID设置为root的机制运行都无关紧要例如以 root 用户身份进行交互式登录。您不应该要求以 root 用户帐户的身份运行基于交互式登录的程序,而不是通过像 sudo 这样的 setuid 程序或您的程序(如果它是 setuid root)。

    一个廉价而肮脏的解决方案是确保交互式 root 登录设置一个唯一的 env var,当您的程序通过 sudo 运行时不太可能设置该环境变量。然而,这显然很容易被欺骗,所以如果你这样做是为了安全,那么这种方法是不可接受的。

    【讨论】:

    • 谢谢。我现在意识到我所要求的可能不是正确的解决方案,但是您和其他人帮助我更好地理解了 sudo 的真正作用。尽管如此,我认为其他人将来也会有这个问题,也许可以像我一样从我的错误中吸取教训。我选择@Andriy 的建议来记录它并保留它。但是,因为这是基于安全性的,所以我无法验证我是否真的在检查 rootPATH 目录,这有点令人讨厌。
    【解决方案3】:

    使用 subprocess 模块运行命令并检查输出:

    from subprocess import check_output
    

    uid = check_output(['bash', '-c', 'echo $UID']).decode().strip()
    if uid != '0':
        sys.exit()  # or return
    

    user = check_output(['whoami']).decode().strip()
    if user != 'root':
        sys.exit()  # or return
    

    似乎除了检查 $PATH 之外,root 和 sudo 是无法区分的。

    【讨论】:

    • 只要getpass.getuser()
    猜你喜欢
    • 2014-04-29
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 2011-08-08
    • 2023-03-16
    • 2014-05-21
    相关资源
    最近更新 更多