如何:请使用 sudo,不要设置任何环境,尤其是 $SUDO_USER?

如何:请使用 sudo,不要设置任何环境,尤其是 $SUDO_USER?

我想启动一个进程作为另一个进程uid,并且它不需要来自 的任何信息,因此我在运行$(env)之前剥离了环境sudo -u powerlessuser /bin/processCmd

env -i sudo -u powerlessuser /bin/processCmd

事实证明 sudo 认为有必要重新填充环境,我想要求它不要这样做。例如,有$SUDO_USER一个 set 甚至可以告诉有关调用该命令的我(tm)的powerlessuser信息,我发现这非常不离散。/bin/processCmd有什么帮助吗?

我认为也可以env -i在 sudo 之后使用剥离,即这样做:

sudo -u powerlessuser /usr/bin/env -i /bin/processCmd

这在一定程度上解决了问题,但我真的很想知道是否有一种方法可以sudo不添加任何信息,我浏览了男人 8 须藤我在其中找到了sudo添加环境的文档,但没有帮助如何sudo不这样做

@terdon♦:我希望清理所有不必要的环境变量。我无法判断哪些环境变量是必要的,但只是为了坚持这个问题,我还没有找到$SUDO_USER进程需要被称为非特权用户的原因。因此我很高兴知道如何告诉sudo不要泄漏SUDO_USER

更新- xy问题

尽管我非常有兴趣避免任何 xy 问题,但我担心这里的情况并非如此。那是因为,我实际上没有遇到与问题中所述不同的问题,即寻找一种方法让 sudo 不做某事,我可以合理地预期: Sudo 获得一个清理过的环境,并且最多不应向其中添加内容,即$SUDO_USER.因此,我非常确信不会有任何其他问题,因为我已经解决了这个问题sudo,即我可以这样做:

sudo -u powerlessuser /usr/bin/env -i /bin/processCmd

它“在 sudo 之后清理”,所以我的问题绝不是其他问题,因为使用后续env -i解决了那里的任何问题。我唯一要求的是知道是否确实存在一种方法, sudo --empty-env可以在一个空的环境中生成新的进程,至少不会告诉$SUDO_USER哪个进程uid运行原始的sudo.

对于所有有兴趣帮助我解决这个问题的人,我要感谢他们!我也留下一些时间,也许还有这样的--empty-env转机可能。如果不是,也许里面的人sudo可以告诉,即参考消息来源,这样的任务是不可能的,因为 sudo 只能把不需要的东西放进$SUDO_USER去。

再次没有 xy 问题,因为事实上,这并不是一个真正的问题,即我没有遭受sudo这里的缺点,因为它是由后续的 解决的env -i,这在“unix 哲学”中是一件事效果env -i很好,即清洁环境。我什至不应该期望从sudo那里出现任何合理的行为,因为 sudo 有一个不同的单一目的,它不关心环境变量泄漏。尽管如此,它确实sudo提供了一些与环境变量相关的标志,这一事实会误导人们认为它可以很好地处理环境变量。

答案1

如果该工具不能满足您的要求,您可以使用包装脚本对其进行改进。我使用这个脚本(noenv)以保持构建环境清洁。使用它就像

sudo -u powerlessuser noenv /bin/processCmd

会做你所要求的。 (脚本应该位于标准路径中,否则您必须在命令中提供它的路径)。

脚本:

#!/bin/sh
# $Id: noenv,v 1.3 2014/05/10 22:43:32 tom Exp $
# trim the environment to minimal (PATH may still be long...)
env | sed -e 's/=.*//' -e '/^[  ].*/d' | \
while true
do
    read value
    if test -z "$value" ; then
        # honor assignments to variables in the parameter list
        while test $# != 0
        do
            case "x$1" in
            *=*)
                eval $1
                name=`echo "$1"|sed -e 's/=.*//'`
                export $name
                shift 1
                ;;
            *)
                break
                ;;
            esac
        done
        exec "$@"
        break
    fi
    case "$value" in
    HOME|PATH|USER|_|SHLVL|TMPDIR|LOGNAME)
        ;;
    *\ *|*\(*|*\)*|*\!*)
        #echo "...skipping $value"
        ;;
    *)
        #echo value:"$value"
        unset "$value"
        ;;
    esac
done

为了澄清,我没有使用 来编写这个/usr/bin/env,因为我正在构建的一些系统没有问题提到的 POSIX 功能:选项-i。这些都是旧的 BSD 系统,包括太阳操作系统4HPUX 10(根据 FreeBSD 上的“env”手册页检查我的记忆)。

顺便说一句,该脚本会删除多行值(但您可能遇到的唯一一个是TERMCAP,并且仅在非常旧的机器上)。第二个 sed 表达式应该是带有tab和 的范围space

对于 POSIX(您可能对此更感兴趣),您可以执行一些操作,使用该功能从父环境传递选定的值,例如,

env -i foo="bar"

所以两者都是可定制的。对于大量变量来说,这可能很笨拙,而脚本是更好的选择。

sudoTERMCAP无论如何都不赞成。这是一个(长)变量列表,它有助于从环境中删除这些变量。

sudo坚持设置某些变量。阅读源码plugins/sudoers/env.c,您将在接近末尾处看到该块rebuild_env

/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
CHECK_SETENV2("SUDO_USER", user_name, true, true);
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_uid);
CHECK_SETENV2("SUDO_UID", idbuf, true, true);
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
CHECK_SETENV2("SUDO_GID", idbuf, true, true);

debug_return_bool(true);

也就是说,就在该函数(唯一)成功返回之前,它设置自己的变量,使用自己的价值观

答案2

如果您只想取消设置特定的环境变量,例如 SUDO_USER,则可以在调用 sudo 时使用“env -u”选项将其过滤掉。

例如,

sudo -u powerless env -u SUDO_USER -u SUDO_UID ./some_script.sh

在运行脚本 ./some_script.sh 的环境中取消设置 SUDO_USER 和 SUDO_UID。

请注意顺序,因为 -u 在 sudo 与 env 后面时具有不同的含义。

相关内容