这是基于我的另一个问题我试图阻止使用脚本执行某些命令。我让脚本在交互式 shell 中完美运行,但对于非交互式 shell,它不会阻止其执行。我确实看到了这个我也在做同样的事情。
/home/user/stop.sh(源自 .bashrc)
#!/usr/bin/env bash
shopt -s extdebug; stop_cmd () {
[ -n "$COMP_LINE" ] && return # not needed for completion
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # not needed for prompt
local this_command=$BASH_COMMAND;
echo $this_command" Not Allowed";
return 1
};
trap 'stop_cmd' DEBUG
/home/用户/temp.sh
#!/usr/bin/env bash
ls
我使用了建议的 BASH_ENV 变量@Inian将我的脚本放入使用非交互式 shell 的脚本文件中。
在新的外壳中
#:export BASH_ENV=/home/user/stop.sh
#:ls
ls Not Allowed --> This is because of the source in .bashrc
#: --> Prompt appears. ls did not run
#:./temp.sh
./temp.sh: /usr/share/bashdb/bashdb-main.inc: No such file or directory
./temp.sh: warning: cannot start debugger; debugging mode disabled
ls Not Allowed --> Because of the $BASH_ENV
Directory contents displayed --> ls ended up running
#: --> Prompt appears after executing temp.sh
但是,如果我直接在 temp.sh 中获取 stop.sh,则不会显示此行为,并且它的工作方式就像一个魅力。
答案1
恐怕无法在非交互式 shell 中使用 DEBUG 陷阱限制命令执行。
或者,您可以尝试不同的方法:
rbash、BASH_ENV 和 command_not_found_handle 的限制
- 设置测试用户
- 对 test-users homedir 中允许的命令进行符号链接
例子:
allow=(bash cat sed)
user="ruser"
homedir="/home/$user"
mkdir "$homedir/bin"
for c in ${allow[@]}; do
ln -s /bin/$c $homedir/bin
done
- 设置
PATH
变量/home/$user/.bashenvrc
并确保它只列出您想要允许的绑定目录,例如/home/$user/bin;...;...
- 设置
BASH_ENV=/home/$user/.bashenvrc
自/home/$user/.bashrc
- 使用受限制的 shell via,
bash -r
以便用户无法执行包含斜杠的命令名称,例如/bin/sh
。
但保留rbash 安全弱点心里。
您想要更细粒度的限制可能性吗?您可以使用该函数扩展此方法,以便可以详细处理command_not_found_handle ()
中未找到的每个命令。PATH
function command_not_found_handle () {
while read -r pattern; do
[[ "$1" =~ $pattern ]] \
&& command="/bin/restrict/$1" \
&& [ -h $command -a -x $command ] \
&& shift \
&& { $command "$@"; return $?; }
done </bin/restrict/whitelist
echo "Command '$1' not found."
}
rbash、黑名单和包装器的限制
- 以root身份设置黑名单
例子:
cat <<EOF >/home/cmd_blacklist
~/bin/ls -al
~/bin/rm -rf
EOF
chmod g-wx+r,o-wx+r /home/cmd_blacklist
- 添加
BASH_ENV=~/.bashenvrc
~/.bashrc
- 编辑
~/.bashenvrc
例子:
PATH="$HOME/bin"
errmsg='arguments not allowed: $cmd $pattern'
while read -r cmd pattern; do
[ ! -e "$cmd" ] && continue # skip nonexistent
[ "$cmd" == "$(basename $cmd)" ] && continue # prevent recursion
eval "function $(basename $cmd) () { [[ \"$(printf $'%s ' \$@)\" =~ $pattern ]] && echo \"$errmsg\" || $cmd \"\$@\"; }"
done </home/cmd_blacklist
现在应该读取 [cmd] [pattern] 形式的黑名单的每一行,从中生成包装函数。你也可以将包装函数导出到子 shell
进一步阅读和使用 sudo 的简单方法
对于很多情况编辑 sudoers 配置以限制命令执行是最好的选择。