我如何保护我的环境不被 sudo 删除一半?
看来我可以保护变量,但是变量(例如提示)所依赖的函数未定义。
这意味着下次显示提示时,它不会运行环境中的只读函数,而是在磁盘上搜索可执行文件并执行找到的第一件事。
根据具体情况,这可能是有害的,也可能不是,但看起来,保留“一半”的环境并删除所依赖的东西,例如,显示下一个提示,都是灾难的根源。
此外,在清除了 env 的安装中,会保留“TERM”等变量,但不会保留“DISPLAY”。如今,GUI 不是比 TTY 更常见吗?可能更糟糕的是,sudo 鼓励使用“auth-time-only”pam_env 函数。在 pam_env 的文档中,建议仅在第一次授权系统时使用它,因为如果用户从远程系统进入,那么这是 pam 唯一可以访问用户登录位置并设置 REMOTEHOST 和 DISPLAY 等内容的时间。通过 sudo 清除登录痕迹并告诉发行版使用 pam_env,几乎可以保证原始用户的主机和显示器将被清除。除了混淆用户的来源外,它还会终止任何远程登录会话。
考虑到许多系统不允许您通过远程会话直接登录到 root - 但要求您通过您的用户登录,然后通过 sudo 到 root,这似乎是取消此安全模型的明显方法。
是否有其他不那么不安全的 sudo 版本?
更新
对于提示,1) 我不想每次提示时都调用基于磁盘的函数(就像您切换颜色时那样)。还有要求:当我列出我的全局变量时,或者当我进行跟踪时,我不希望颜色切换代码显示在原始文件中,也不想在不需要的地方更改颜色。
此外,我不想让这个问题与我的具体设置有关,因为它已经在多个 unix 和 Windows 上运行了好几年,只是现在需要“修复”,因为 sudo 无法完整地复制我的环境。
对于颜色设置,这相对简单。使用“read”并将代码从 tput 读入 vars,因此列出或在跟踪中,代码都在未扩展的 bash 输入中。示例:
read _CRST <<<"$(tput sgr0)" #Reset
read _CRed <<<"$(tput setaf 1)" #Red
read _CBLD <<<"$(tput bold)" #Bold
变成: _CBLD=$'\E[1m' _CRST=$'\E[0;10m' _CRed=$'\E[31m'
注意:我的要求已经经过了数年的发展和完善,这不是一时兴起的创作。
但是对于提示,这要复杂得多——请记住,本地主机没有主机,但也希望它出现在窗口标题中。
除了“spwd”之外的所有内容都在这里:# 构建提示符 ########### #specific to xterm & linux console compat emulations read _CRST <<<"$(tput sgr0)" #Reset read _CRed <<<"$(tput setaf 1)" #Red read _CBLD <<<"$(tput bold)" #Bold declared _prompt_open="" _prompt_close="" _prompt=">" declared _disp_port=${DISPLAY/[^:]*:/} printf -v qUSER "%q" $USER typeset -x qUSER
[[ $UID -eq 0 ]] && {
_prompt_open="$_CBLD$_CRed"
_prompt="#"
_prompt_close="$_CRST"
}
PS1='\['"$_prompt_open"'\]$(spwd "$PWD" )'"$_prompt"'\['"$_prompt_close"'\] ';
if [[ -n ${REMOTEHOST:-""} ]]; then
function titlebar { \
printf "\033]1;${qUSER}@${HOSTNAME}:%q\007" "$(spwd "$PWD")" ;\
}
export -f titlebar
PS1='\[$(titlebar)'"$_prompt_open"'\]${HOSTNAME}:$(spwd "$PWD")'"$_prompt"'\['"$_prompt_close"'\] '
fi
FWIW,PS4 有这个:
PS4='>>${BASH_SOURCE:+${BASH_SOURCE[0]/$HOME/~}}#${LINENO}> '
请注意,spwd 函数不在上面,它位于一个单独的文件中,只有在初始化新环境时才会被获取。
但是该函数及其数据是: if [[ ! ${qUSER:-""} ]]; then printf -v qUSER "%q" $USER export qUSER fi export _home_prefix=${HOME%/*}/
Next func 的想法来自于 suse,但是被完全重写了。
当显示路径占据屏幕宽度的 50% 以上时,返回一条短路路径:
alias int=declare\ -i _e=echo _pf=printf exp=export ret=return
exp __dpf__='local -a PF=(
"/$1/$2/$3/../\${$[$#-1]}/\${$#}"
"/$1/$2/../\${$[$#-1]}/\${$#}"
"/$1/../\${$[$#-1]}/\${$#}"
"/$1/../\${$#}"
".../\${$#}"
"..." )'
function spwd () { \
(($#)) || { _e "spwd called with null arg"; return 1; }; \
int w=COLUMNS/2 ;\
( _pf -v _p "%s" "$1" ; export IFS=/ ;\
set $_p; shift; unset IFS ;\
t="${_p#$_home_prefix}" ;\
int tl=${#t} ;\
if (($#<=6 && tl<w));then ((tl<=2)) && \
{ _e -En "${_p}";return 0; } ;\
else \
eval "$__dpf__" ;\
int i pfl=${#PF[*]} ;\
for ((i=0; i<pfl; ++i)); do eval \
"_pf -v _pa %s \"${PF[i]}\"" ;\
_p="$(eval "_pf %s \"$_pa\"")" ;\
((${#_p}<w)) && break; done ;\
fi ;\
_e -En "${_p#$_home_prefix}" )
}
排版-xrf spwd
关于资源只读值或函数:
如果您尝试重新获取只读变量或函数的来源,则会收到错误。由于变量仍然是只读的...只有当 sudo 破坏了一半以上的环境时,才能安全地读取只读函数。在所有其他情况下,再次读取它们会导致多个运行时错误(无法重新定义只读变量或函数)。
我的例程必须以某种方式知道内存中一半的只读值(那些看起来像函数的值)已被删除,并且只能读取它们。我不确定如何编写 hack 代码来测试覆盖的只读变量或函数——我也不应该这样做。
至于覆盖我的函数:
1) 持久用户首先不会拥有 sudo 访问权限。2) 由于我是系统管理员,这些功能是为我准备的……如果我破解了自己的系统,“这就是生活”。
回复:PAM:是的,sudo 使用 pam 作为大多数发行版的配置。
我想要的只是 sudo 按照它说的做:当我告诉它不要触碰我的环境时,它不会触碰。它没有这样的选项,这就是我询问更安全的替代品的原因。通过剥夺用户的配置选择来“帮助”用户的程序不是好的安全程序,因为它们不尊重本地站点的安全策略,而是因为它们认为自己更了解情况而覆盖它。我还没有看到这样的程序是正确的。
希望这能回答你的问题,关于为什么我要问如何解决这个问题以及为什么这是一个问题,尽管这肯定远远超出了询问某人已经标记下来甚至被问到的问题......(我怎么敢!)......
答案1
您也将其发送到了 sudo 邮件列表,不是吗?
环境变量
好吧,在 sudoers 中,您可以配置应保留哪些环境变量。查看默认的 env_reset 和 env_keep。这些也可以按用户或组进行设置。只需添加 REMOTEHOST 和 DISPLAY,然后,瞧!
迅速的
为什么你在提示中使用函数?
++ 看起来您希望您的提示是这样的:
PS1='${REMOTEHOST}${REMOTEHOST+->}\u@\h:\w\$ '
这当然不是切换颜色。要切换颜色,请执行以下操作:
PS1='\[$(tput bold)$(tput setaf 1)${REMOTEHOST}${REMOTEHOST+->}\u@\h:\w\$$(tput sgr0) \]'
源函数
为什么不重新获取包含这些功能的文件呢?
++ 你说你确实这么做了,但你使用标志来优化函数并防止它们被重新读取。如果你忽略了这种优化,那么它还能正常工作吗?
只读函数
对于 root 用户,为什么要将功能保留在用户可以更改的环境中?作为 root 用户,您需要一个定义良好的环境,并且该环境的设置不会受到用户切换到 root 用户的任何影响。
++ 持久用户始终可以重置 shell 中的所有内容。重点是,您不能依赖函数保持不变。因此,您必须每次都从可靠的位置获取它们。
聚丙烯酰胺
并且 sudo 在其源代码中不使用 pam_env()。但是,它是通过 PAM 堆栈调用的。那么,您能提供支持您说法的链接吗?
++ 是的,如果您这样配置,sudo 可以使用 PAM。
诚挚的问候,埃德加。