我想知道如何创建(如果可能的话)一个在 Debian 上以 root 身份运行的 bash 脚本,无论执行它的用户是谁,而不要求任何类型的身份验证。
该文件将像 root 用户一样运行其所有命令,但只有真正的 root 用户才能读取或写入它。
我需要这个,因为我想运行swapoff
、swapon
、apt
等命令...但是通过另一个应用程序,我希望它不询问我任何密码。
这些命令将被修复(这些根命令将在文件中包含它们的参数,而不是作为输入),因此安全影响并不是我关心的问题,但我也接受解释。
答案1
您无法创建运行 setuid 的 bash 脚本。但是,您可以使用sudo
(或类似的程序,如 calife)来确保它们以 root 权限运行。
有两种基本方法可以做到这一点。
假设您的脚本被调用reset-swap
并执行以下操作:
#!/bin/sh
swapoff /dev/sdb
shred -n0 -z /dev/sdb
mkswap /dev/sdb
swapon /dev/sdb
选项A: 将允许任何用户运行这些单独的命令,并在它们前面加上 sudo:
#!/bin/sh
sudo swapoff /dev/sdb
sudo shred -n0 -z /dev/sdb
sudo mkswap /dev/sdb
sudo swapon /dev/sdb
并添加/etc/sudoers
一系列让每个人都可以这样做的行:
ALL ALL = NOPASSWD: /sbin/swapoff /dev/sdb
ALL ALL = NOPASSWD: shred -n0 -z /dev/sdb
ALL ALL = NOPASSWD: mkswap /dev/sdb
ALL ALL = NOPASSWD: swapon /dev/sdb
然而,虽然每个人都可以安全地执行指定的操作正如脚本所做的那样,它可能不是那么独立。例如,mkswap
在处理交换分区之前检查交换分区是否未安装,但shred
很乐意擦除已安装的交换分区。
因此,最好使用
选项B:只让该脚本使用 sudo 运行。
ALL ALL = NOPASSWD: /usr/local/bin/reset-swap
然后您可以将其称为 assudo reset-swap
而不是reset-swap
。如果您喜欢的话,如果脚本不以 root 身份运行,它可以提升自身,让它在不指定前缀的情况下运行sudo
:
#!/bin/sh
if [ "`id -u`" -ne 0 ]; then
echo "Switching from `id -un` to root"
exec sudo "$0"
exit 99
fi
swapoff /dev/sdb
shred -n0 -z /dev/sdb
mkswap /dev/sdb
swapon /dev/sdb
最后,让我用 sudo 讲座中的几点来结束:打字前三思,能力越大,责任越大。
答案2
让程序始终在特定 UID 下运行的低级方法是二进制文件上的 setuid 位。这就是例如获得 root 权限的方式sudo
,su
即使它们通常是通过正常使用启动的。但一般情况下,类Unix系统不支持setuid脚本, 看:允许在 shell 脚本上设置 setuid
但是,您可以做的是配置sudo
或其他类似工具,以允许用户以适当的权限运行某些特定文件。例如,这将允许名为的用户使用任何参数viceadmin
运行/usr/local/bin/sudoswapon
,并且无需身份验证:
viceadmin ALL = NOPASSWD:/usr/local/bin/sudoswapon
现在,由于sudo
涉及更改权限本身,因此sudoswapon
可以是 shell 脚本。
您注意到脚本需要小心处理命令行参数的方式是正确的,并且全部shell 语言的陷阱将适用。幸运的是,sudo
过滤掉大多数环境变量,至少如果env_reset
设置了该选项。
答案3
很久以前就意识到 setuid 脚本带来了难以克服的安全问题(它们很容易被欺骗而破坏IFS
),所以我们不再这样做了。 Linux 已被更改以帮助我们避免 setuid 脚本。
sudo
您可以使用来实现您的愿望NOPASSWD
。读man sudoers sudo
。