我们可以阻止 Linux 中 root 执行命令吗?

我们可以阻止 Linux 中 root 执行命令吗?

有一个脚本很难阅读和调试。

其中某处有如下命令:

sudo chmod -R 777 /$some_var/$another_var

换句话说,它动态创建一个路径,然后以递归方式授予该路径权限。

但是,由于它需要互联网连接并且下载东西,有时这些变量由于错误而为空,并且会执行以下命令:

sudo chmod -R 777 /

这会破坏操作系统。我们需要重新安装它。

我们正在改进脚本,使其更完善、更具弹性。但是,有没有办法阻止用户执行该命令root

我的意思是,如果路径是,我希望这个命令不可执行/,即使对于root用户来说也是如此:

sudo chmod -R 777 /

答案1

如果你专门询问关于sudo chmod -R 777 /Ubuntu 的问题,那么你很幸运。GNU 工具有一个选项:--preserve-root。来自GNU 文档

/2.9特殊对待

某些命令可能会破坏整个层次结构。[...] 由于此类命令的合法用途很少,因此 GNU rm通常拒绝对解析为 的任何目录进行操作 /。如果您确实想尝试删除系统上的所有文件,可以使用 选项--no-preserve-root,但 选项指定的默认行为--preserve-root对于大多数目的来说更安全。

命令chgrpchmodchown也可以对整个层次结构进行破坏性操作,因此它们也支持这些选项。 [...] 传统和 POSIX 要求这些命令对 进行递归操作/,因此它们默认为--no-preserve-root,但使用--preserve-root选项可以使它们在大多数情况下更安全。为方便起见,您可以--preserve-root在别名或 shell 函数中指定。

请注意,该--preserve-root选项还确保即使在取消引用指向的符号链接时也不会修改chgrp和 。chown//

因此,修改您的脚本以使用:

sudo chmod -R 777 --preserve-root /$some_var/$another_var

请注意,我不赞成使用chmod -R 777。这是极其罕见的,但chmod -R 777绝对必要。


您还可以使用set -u让脚本将未设置的变量视为错误,或者使用${var:?message}将变量未设置的特定实例视为错误:

$ message="Unset/empty variable not allowed"
$ sudo chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
bash: some_var: Unset/empty variable not allowed

(默认消息为:parameter null or not set。)

在 Docker 容器中测试:

root@d9c4e4427d7a:/# chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
bash: some_var: Unset/empty variable not allowed
root@d9c4e4427d7a:/# some_var=/
root@d9c4e4427d7a:/# another_var=////
root@d9c4e4427d7a:/# chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe

答案2

我们可以阻止 Linux 中 root 执行命令吗?

不。

我们可以阻止 Linux 中的脚本执行命令吗?

是的。不要使用它,自己创建一个。例如,您可以创建一个别名 fpr,chmod并进行一些有效性检查,然后执行它chmod

这很糟糕,就好像:

sudo chmod -R 777 /$some_var/$another_var
  • sudo不属于脚本内部。
  • 777总是不好的。750最多当您有超过 1 个用户时,并且700应该在单独的机器上优先使用。
  • 始终必须检查两者是否$some_var$another_var具有正确的值。健全性检查是脚本的重要组成部分。如果值来自不受信任的来源(例如用户通过命令行执行或编辑配置提供变量),则更是如此。

意思是我希望如果路径为,则此命令不可执行/,即使对于 root 用户也是如此:

显而易见的答案是在命令之前添加一个完整性检查来评估变量。您还可以使用别名chmod来执行自己的命令,该命令对值进行检查。

它必须在脚本里面:检查空是不够的:$some_var="/////////////"同样糟糕;)

答案3

您可以使用 Bash 的扩展测试括号[[ ... ]]来预先检查语句if... 以下将检查是否$path具有除正斜杠和空格之外的字符以及解析路径本身,并且如果两个参数中的一个或两个都未设置或为空,或者如果两者都是斜杠或全是空格,或者如果解析为...则它将评估为$some_varfalse$another_var$path这样/

path="/${some_var:-EMPTY}/${another_var:-EMPTY}"

if [[ "$path" = *[!\ /]* && "$(realpath "$path" 2>/dev/null)" != "/" && ! "$path" =~ "EMPTY" ]]
then
  # your command using those variables here
  # chmod -R 777 "$path"
  echo "Directory is not root"
fi

注意:改进解决黑客概率(抚养@grok 的评论...谢谢@grok) 除其他事项外。

答案4

做这个:

# if both of the variables are not empty
if [[ -n "$some_var" && -n "$another_var" ]]
then
    # run the chmod command as intended
    sudo chmod -R 777 /$some_var/$another_var
else
    # only do this if you don't want the script to continue, but to exit with an error message
    echo "Error - exiting"
    exit
fi

如果任何变量可能包含仅由斜杠(/字符)组成的字符串,那么您也需要检查这一点。

相关内容