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

Nor*_*wap 6 sudo environment-variables pam environment

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

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

为了解决这个问题,我相信我应该编辑该文件/etc/pam.d/sudo,但是我应该在其中放入什么?

Aar*_*son 7

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

  1. PAM 处理它们的顺序。

    /etc/environment首先解析,但是如果这些相同变量也存在于pam_env.conf. 但是,可以包含+扩展/etc/environmentin中的变量/etc/security/pam_env.conf,例如:

    /etc/security/pam_env.conf
    
    PATH   DEFAULT=${PATH}:/usr/sbin
    
    Run Code Online (Sandbox Code Playgroud)
  2. 变量扩展

    A。 /etc/environment不是脚本,而是一组赋值表达式,即${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}(比较@$)在 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}
    
    Run Code Online (Sandbox Code Playgroud)

对于您在此处描述的特定问题,您配置的值/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}
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    -   session    include       system-auth
    +   session    include       sudo-environment
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    /etc/sudoers
    Defaults env_keep += "var1 var2, etc..."
Run Code Online (Sandbox Code Playgroud)