如何始终强制特定命令使用 sudo 密码?

如何始终强制特定命令使用 sudo 密码?

有一天,我正在对我的 Web 服务器进行一些维护任务。当时我很匆忙,也很困,所以我用sudo命令完成了所有工作。

然后,我不小心按下了Ctrl+ V,将此命令发送到我的 Web 服务器:

sudo rm -rf /*

对于那些想知道上述命令做什么的人来说:这删除了我的所有的网络服务器

幸运的是,我有备份,但不幸的是,我不得不花两个小时来修复这个可怕的错误。但从那时起,我一直在想:

有没有办法始终强制执行特定命令的 sudo 密码?

如果服务器要求我输入密码,我就可以省去很多麻烦。但事实并非如此,因为sudo在出​​现这个严重错误之前,我运行了大约 5 条命令。

那么,有办法吗?我只需要rm始终强制执行命令的密码。我使用的其他命令通常是nanocp两者都(在某种程度上)可恢复。

答案1

您可以在 中为特定命令timestamp_timeout设置。创建一个包含以下内容的文件:0/etc/sudoersvisudo -f /etc/sudoers.d/pduck

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

现在,即使用户是该组的成员并且记得其他命令的密码,运行时也总是会要求用户pduck输入密码sudo rm(无论给出什么附加参数) 。sudosudo

缺点是您无法轻松地在/bin/rm文件中的行中添加参数来进一步限制这一点。好吧……您可以,例如:

Cmnd_Alias DANGEROUS = /bin/rm -f

但是随后您只会被提示准确输入sudo rm -f,而不是(再次)输入sudo rm -rf,例如。

答案2

一种方法是使用安全保证。这将仅解决“rm”的使用问题并阻止运行特定版本的“rm”。这包括删除根系统,但也可用于阻止删除系统相关目录,如“/usr/”或“/var/”。来自链接:

防止意外删除重要文件

Safe-rm 是一种安全工具,旨在通过替换/bin/rm包装器来防止意外删除重要文件,该包装器会根据可配置的黑名单(包含永远不应删除的文件和目录)检查给定的参数。

尝试删除这些受保护文件或目录的用户将无法执行此操作,而是会显示一条警告消息:

$ rm -rf /usr   
Skipping /usr

(受保护的路径可以在站点和用户级别设置。)

恢复误删的重要文件可能非常困难。立即安装 safe-rm 保护自己,降低需要联系数据恢复服务的可能性!

在此处输入图片描述

答案3

sudo提供了一个选项-k, --reset-timestamp,请参阅man sudo

当与可能需要密码的命令或选项结合使用时,此选项将导致 sudo 忽略用户的缓存凭据。因此,sudo 将提示输入密码(如果安全策略需要密码),并且不会更新用户的缓存凭据。

您可以编写一个简单的包装器来sudo测试rm -rf /*和运行

sudo -k rm -rf /*

相反,例如像这样:

sudo ()                                                                                                                                                 
{ 
    [[ "$*" == "rm -rf /*" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

示例用法

在这里测试echo a

$ sudo echo
[sudo] password for dessert: 

$ sudo echo

$ sudo echo a
[sudo] password for dessert: 
a
$ sudo echo a
[sudo] password for dessert: 
a

如果你想被问到每一个通常情况下rm,您可以按如下方式调整上述函数:

sudo () 
{ 
    [[ "$1" == "rm" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

如果你想结合我建议使用通用命令调用和特定命令行case,例如:

sudo () 
{ 
    case "$*" in 
        rm*)            opt="-k" ;;
        "mv /home"*)    opt="-k" ;;
        "ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
        *)              opt="" ;;
    esac;
    /usr/bin/sudo $opt "$@"
}

请注意,如果您使用选项运行,这些方法将不起作用sudo- 可能的解决方案是[[ "$*" =~ " rm " ]]检查被空格包围的字符串“rm”或*" rm "*)捕获case包含“rm”的任何命令行。

答案4

这个答案并没有解决sudo你的问题的一部分,但另一方面,它解决了一种减轻意外rm调用危险的方法任何用户。

你可以rm使用rm -I别名

  • 一旦删除目录或 3 个以上文件,就会要求确认
  • 只要你省略-f它将覆盖先前的-I选项。

--one-file-system是我在别名中使用的另一种可能的防止意外删除的保护措施rm

sudo此外,您需要要求 Bash在别名定义后面用尾随空格扩展别名(见下文)。

设置

要创建这样的别名,请使用以下命令:

alias rm='rm -I --one-file-system'
alias sudo='sudo '

您可以将其放入您的~/.bashrc甚至/etc/bash.bashrc

用法

$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?

要确认,请输入yes或将其翻译成您的语言环境或任一单词的首字母,然后按Enter。任何其他输入(包括 none)都会中止操作。

相关内容