我想rm
在以 root 身份登录时运行特定命令(例如),但每次都希望显示 root 密码提示。当我su -c "command"
以 root 身份运行时,系统并未提示我输入密码。
答案1
具体来说su
,root 不需要输入密码,因为su
的 PAM 规则允许这样做:
$ grep root /etc/pam.d/su
# This allows root to su without passwords (normal operation)
auth sufficient pam_rootok.so
# Uncomment this to force users to be a member of group root
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").
如果要让su
root 询问密码,请注释掉 的使用pam_rootok
。当然,su
不关心命令,因此su
root 使用 时都会询问密码。
您无法保护单个命令免受 root 攻击,否则会面临大量破坏风险。离开终端时请锁定终端。不要运行 root 会话。
答案2
您可以将此代码用于包装器脚本,但您可能也rm
希望为mv
和创建类似的版本。find
编辑2017 年 3 月 5 日 - 更改在终端运行时检查的方法。
此答案检查是否在终端上运行,如果在启动、cron 或 GUI 等后台脚本中运行,则不会提示输入密码。可以改进脚本以确保rm
直接在终端中输入。然后,如果另一个脚本(如sudo update-grub
或sudo apt update
调用)rm
不需要第二个密码。
我编写了一个脚本来rm
像 OP 要求的那样进行密码保护,下面的代码是相同的,只是它要求 sudo / root 用户输入密码。它还进行了一些编辑以防止您意外删除:
- /
- /家
- /垃圾桶
创建脚本
使用gksu gedit /usr/local/bin/rm
并复制以下行:
#!/bin/bash
tty -s;
if [ "0" == "$?" ]; then Terminal="Y"; else Terminal="N"; fi
if [ $Terminal == "Y" ] ; then
# Running from terminal don't allow delete of / or /toplevel directory even if sudo
for i in ${@:1}
do
# Skip options -i -r -v -d
if [[ ${i:0:1} != "-" ]] ; then
# if parameter doesn't begin with '-' it's file or directory, so get real path.
fullname=$(realpath "$i" 2>&1) # No error messages if file doens't exist
# We must have at least two `/` in the full path
levels=$(echo "$fullname" | tr -cd '/' | wc -c)
if (( $levels == 1 )); then # Test for 1, will be zero when file doesn't exist.
echo "Attempting to remove top level directory '$fullname'"
echo "Use 'sudo /bin/rm $@' instead."
exit 1 # error
fi
fi
done
fi
if [ $Terminal == "Y" ] ; then
# Only running from a terminal needs password (ie not cron)
# log rm usage to /var/log/syslog
PARENT_COMMAND="$(ps -o comm= $PPID)"
logger "$PARENT_COMMAND"" - rm command was used on file: ""$fullname"
# Get password
Password=$(zenity --password --title="Password for rm")
encryptPassword=$(echo -n "$Password" | md5sum)
echo "md5sum: $encryptPassword" # Comment out after viewing one time and updating line below.
if [[ "$encryptPassword" != "d2c30dc65e59558c852ea30b7338abbe -" ]]; then
echo "Invalid password!"
exit 1
fi
fi # non-terminals can't enter password.
# Call REAL rm command with parameters passed to this wrapper sript
/bin/rm "$@"
exit 0
将密码“WE2U”更改为您喜欢的任何密码并保存文件。
将新rm
脚本标记为可执行
使用以下方法将新rm
脚本标记为可执行:
sudo chmod +x /usr/local/bin/rm
怎么运行的
除非密码是WE2U,第一次运行脚本时,您将收到“无效密码”提示,并显示您输入的密码的加密密钥。将此加密密钥从终端复制并粘贴到脚本中。然后注释掉在终端上显示加密密钥的 echo 行。
因为路径/usr/local/bin
在列表中的位置高于我们调用的/bin
命令。获取有效密码后,它会调用该命令进行真正的删除。rm
/bin/rm
logger
每次rm
使用终端手动调用时,脚本都会调用记录。命令使用情况会记录到/var/log/syslog
。
摘自(如何为‘rm’命令设置密码?) 并修改为也要求 root 用户输入密码。
答案3
我能想到的最简单的解决方案是切换su
到不同的用户然后root
再返回:
su userx -c 'su -c "ls"'
这样做的一个缺点是,如果命令中需要特殊字符,则转义会变得很棘手。