/etc/security/pam_env.conf 和 /etc/environment 之间的区别 + 让 sudo 读取 pam_env.conf

/etc/security/pam_env.conf 和 /etc/environment 之间的区别 + 让 sudo 读取 pam_env.conf

我很难看出pam_env.conf和之间的区别/etc/environment。对我来说,它们都做同样的事情,只是语法不同。手册页没有帮助。那么区别是什么?

此外,我想找到一种方法来为PATH所有用户添加环境变量的路径。将它们添加到上述两个文件中对所有用户都有效,但不适用于 sudo,可以通过运行来验证sudo sh -c 'echo $PATH'

为了解决这个问题,我认为我应该编辑该文件/etc/pam.d/sudo,但是我应该在里面放什么呢?

答案1

/etc/security/pam_env.conf和之间有两个根本区别/etc/environment

  1. PAM 处理它们的顺序。

    /etc/environment首先解析,但如果 中也存在这些变量,则此处定义的任何内容都会被这些相同变量的定义覆盖pam_env.conf。但是,可以从/etc/environment中包含 + 扩展 中的变量/etc/security/pam_env.conf,例如:

    /etc/security/pam_env.conf
    
    PATH   DEFAULT=${PATH}:/usr/sbin
    
  2. 变量扩展

    a. /etc/environment并不是脚本,而是一组赋值表达式,ie${PATH}并不是展开的,而是按字面意思来用的。

    b. /etc/security/pam_env.conf则完全不同。它本身并不是一个脚本;它仍然只是一组 KEY=VALUE 赋值,但 PAM 可以扩展现有变量(例如:${PATH}${DISPLAY})和其他 PAM_ITEM(例如:@{PAM_SERVICE}@{PAM_USER}等)。请特别注意此处的$vs。@

    PAM 还处理特殊变量@{HOME}@{SHELL},它们扩展为中定义的任何内容/etc/passwd。 *注意:在大多数 PAM 应用程序中,传统变量${HOME}${SHELL}(比较@vs $)在 PAM 流程的早期阶段不可用。

    使用注释中给出的示例/etc/security/pam_env.conf,这种替换/扩展行为可用于修改DISPLAY远程登录会话的变量。

    /etc/security/pam_env.conf
    REMOTE_HOST     DEFAULT=localhost           OVERRIDE=@{PAM_RHOST}
    DISPLAY         DEFAULT=${REMOTE_HOST}:0.0  OVERRIDE=${DISPLAY}
    

对于您在此处描述的具体问题,您在临时环境中配置的值/etc/environment不可用,sudo因为sessionPAM 应用程序定义提供的功能/etc/pam.d/sudo从不调用会话pam_env.so

在 中/etc/pam.d/sudo,会话仅从 导入规则/etc/pam.d/system-auth。顺着线索看,在 中/etc/pam.d/system-auth,会话堆栈没有 的条目pam_env.so


有几种方法可以自定义sudo环境中可用的变量。

如果您需要一些仅存在于 sudo-land 中的自定义环境变量,那么这相当简单。

  1. 创建一个文件来包含您独有的 sudo 环境变量。

    /etc/security/sudo_custom_vars.conf
    GREET   DEFAULT="hello from sudo land"
    VAR1    DEFAULT="${GREET}"
    _VAR2   DEFAULT="VAR2 not passed to sudo, ...but"
    VAR2    DEFAULT="${_VAR2} ${GREET}"                 OVERRIDE=${VAR2}
    VAR3    DEFAULT="Nope. Unknown users cannot sudo."  OVERRIDE=@{PAM_RUSER}
    ...
    
  2. 复制/etc/pam.d/system-auth,按照 的格式重命名/etc/pam.d/sudo-environment,然后在堆栈底部添加一条指令session

    session     required    pam_unix.so
    session     optional    pam_permit.so
    # Add a line for using pam_env.so
    session     optional    pam_env.so conffile=/etc/security/sudo_custom_vars.conf
    

    如果要从非 sudo 环境传递变量,请包含user_readenv=1标志

    session     optional    pam_env.so      conffile=/etc/security/sudo_custom_vars.conf    user_readenv=1
    
  3. 在 PAM 应用程序定义中/etc/pam.d/sudo,进行替换:

    -   session    include       system-auth
    +   session    include       sudo-environment
    
  4. 打开新终端进行测试

    $ su <your username>                    # Testing PAM without logging out
    $ export VAR1=""
    $ export VAR2="hello from down here"    # Set var in non-sudo environment
    
    $ echo $VAR1
    <nothing>
    $ sudo sh -c 'echo $VAR1'               # Test sudo's DEFAULT value
    hello from sudo land
    
    $ echo $VAR2
    hello from down here
    $ sudo sh -c 'echo $VAR2'               # VAR2 not passed to sudo
    VAR2 not passed to sudo, ...but hello from sudo land
    $ sudo -E su -c 'echo $VAR2'            # VAR2 (and everything else) passed to sudo
    hello from down here
    $ sudo env VAR2="inline override" su -c 'echo $VAR2'
    inline override
    
    $ sudo sh -c 'echo $VAR3'               # Testing we can read a PAM_ITEM
    aaron
    

修改 PAM 模块的另一种方法是使用 进行编辑/etc/sudoers# visudo就像您所做的那样。我意识到这是一个老问题,而且很久以前,评论Default env_reset是应该做的事情。

sudoers展望未来,使用从环境中提取变量定义时公认的最佳做法是将变量附加到env_keep。(...也就是说,除非您需要一组如上所示的唯一变量)

    /etc/sudoers
    Defaults env_keep += "var1 var2, etc..."

答案2

我设法或多或少地获得了我想要的 sudo 内容:

我编辑了该/etc/sudoers文件(使用sudo visudo)并注释掉了行Default env_resetDefault secure_path = ...

现在 sudo 将使用用户的环境。

pam_env.conf和之间的区别/etc/environment对我来说仍然不清楚,所以这个问题还没有得到解答。

相关内容