即使以 root 身份运行,也可以使用 root 密码提示运行特定命令

fds*_*fad 4 command-line root password rm

我想rm在以 root身份登录时运行特定命令,例如,但我希望每次都显示 root 密码提示。当我su -c "command"以 root 身份运行时,没有提示我输入密码。

mur*_*uru 10

特别是对于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").
Run Code Online (Sandbox Code Playgroud)

如果您想su询问 root 的密码,请注释掉pam_rootok. 当然,su它不关心命令,所以suroot 的任何使用都会要求输入密码。

您无法在不冒很多损坏风险的情况下保护单个命令。离开时只需锁定终端即可。不要运行根会话。


Win*_*nix 8

您可以将此代码用于rm包装脚本,但您可能还想为mv和创建类似的版本find


编辑2017 年 3 月 5 日 - 更改在终端中运行时的检查方法。


此答案检查是否在终端上运行,如果在启动、cron 或 GUI 等后台脚本中运行,则不会提示输入密码。可以改进脚本以确保rm直接在终端中输入。然后,如果另一个脚本(如sudo update-grubsudo apt update称为rm第二个密码)将不需要。

我已经编写了一个脚本来rm像 OP 请求的那样进行密码保护,下面的代码是相同的,只是它需要来自 sudo / root 用户的密码。它还进行了编辑以防止您意外删除:

  • /
  • /家
  • /bin

创建脚本

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
Run Code Online (Sandbox Code Playgroud)

将密码“WE2U”更改为您喜欢的任何内容并保存文件。

将新rm脚本标记为可执行

rm使用以下命令将新脚本标记为可执行:

sudo chmod +x /usr/local/bin/rm
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

密码

除非密码是WE2U,否则第一次运行脚本时您将获得“无效密码”并显示您输入的密码的加密密钥。将此加密密钥从终端复制并粘贴到脚本中。然后用在终端上显示加密密钥的 echo 注释掉该行。

因为/usr/local/bin列表中的路径比/bin我们rm调用的命令要高。获得有效密码后,它会调用/bin/rm进行真正的删除。

logger每次rm使用终端手动调用脚本调用记录。命令使用记录到/var/log/syslog.

摘自 ( How can I set up a password for the 'rm' command? ) 并修改为也要求 root 用户提供密码。