我很难看出pam_env.conf
和之间的区别/etc/environment
。对我来说,它们都做同样的事情,只是语法不同。手册页没有帮助。那么区别是什么?
此外,我想找到一种方法来为PATH
所有用户添加环境变量的路径。将它们添加到上述两个文件中对所有用户都有效,但不适用于 sudo,可以通过运行来验证sudo sh -c 'echo $PATH'
。
为了解决这个问题,我认为我应该编辑该文件/etc/pam.d/sudo
,但是我应该在里面放什么呢?
答案1
/etc/security/pam_env.conf
和之间有两个根本区别/etc/environment
。
PAM 处理它们的顺序。
/etc/environment
首先解析,但如果 中也存在这些变量,则此处定义的任何内容都会被这些相同变量的定义覆盖pam_env.conf
。但是,可以从/etc/environment
中包含 + 扩展 中的变量/etc/security/pam_env.conf
,例如:/etc/security/pam_env.conf PATH DEFAULT=${PATH}:/usr/sbin
变量扩展
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
因为session
PAM 应用程序定义提供的功能/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 中的自定义环境变量,那么这相当简单。
创建一个文件来包含您独有的 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} ...
复制
/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
在 PAM 应用程序定义中
/etc/pam.d/sudo
,进行替换:- session include system-auth + session include sudo-environment
打开新终端进行测试
$ 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_reset
和Default secure_path = ...
。
现在 sudo 将使用用户的环境。
pam_env.conf
和之间的区别/etc/environment
对我来说仍然不清楚,所以这个问题还没有得到解答。