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

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

我想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").

如果要让suroot 询问密码,请注释掉 的使用pam_rootok。当然,su不关心命令,因此suroot 使用 时都会询问密码。

您无法保护单个命令免受 root 攻击,否则会面临大量破坏风险。离开终端时请锁定终端。不要运行 root 会话。

答案2

您可以将此代码用于包装器脚本,但您可能也rm希望为mv和创建类似的版本。find


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


此答案检查是否在终端上运行,如果在启动、cron 或 GUI 等后台脚本中运行,则不会提示输入密码。可以改进脚本以确保rm直接在终端中输入。然后,如果另一个脚本(如sudo update-grubsudo 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"'

这样做的一个缺点是,如果命令中需要特殊字符,则转义会变得很棘手。

相关内容