Next func 的想法来自于 suse,但是被完全重写了。

Next func 的想法来自于 suse,但是被完全重写了。

我如何保护我的环境不被 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。

诚挚的问候,埃德加。

相关内容