如何始终对特定命令强制执行sudo密码?


12

前几天,我在Web服务器上执行一些维护任务。我很着急和困倦,所以我使用sudo命令进行了所有操作。

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

sudo rm -rf /*

对于那些想知道上面命令做什么的人:这删除了我的整个 Web服务器

幸运的是,我有备份,但不幸的是,我不得不花两个多小时醒着才能修复这个令人敬畏的错误。但是从那以后,我一直在想:

有没有办法始终为特定命令强制使用sudo密码?

如果服务器要求我输入密码,则可以避免很多麻烦。它没有,因为sudo在此重大错误发生之前,我运行了大约5条命令。

那么,有办法吗?我只需要密码和rm命令一起执行即可。我使用的其他命令通常是(nanocp在某种程度上)可恢复的。



2
@solsTiCe /*在传递给rm命令之前已展开。因此该命令看不到单个参数,而是一个参数列表(/bin /boot /cdrom /dev /etc /home...)

3
可以从中获得一个重要的教训的是,除非确实需要,否则不应该使用sudo进行操作。我知道这并不能回答您在这里提出的问题,但是最重要的问题是如何(希望)防止自己再次删除服务器,并且避免使用sudo应该是您对此的第一道防线。
David Z


2
@ WinEunuuchs2Unix根本不是重复的问题,这里的操作不希望rm命令输入密码。他们只想sudo在每次使用rm命令时提示一次。当您的第一个命令为时,您链接的问题的解决方案将变得有些烦人sudo rm。因为它将要求您输入两个密码,一个用于sudo一个rm

Answers:


17

您可以设置timestamp_timeout0在特定的命令/etc/sudoers。创建一个visudo -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,例如。


9

一种方法是使用safe-rm。这只会解决“ rm”的用法,并阻止运行“ rm”的特定版本。这包括删除根系统,但也可以用于防止删除与系统相关的目录,例如“ / usr /”或“ / var /”。从链接:

防止意外删除重要文件

Safe-rm是一种安全工具,旨在通过/bin/rm使用包装程序进行替换来防止重要文件的意外删除,该包装程序将对给定的参数与永不删除的可配置文件和目录黑名单进行检查。

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

$ rm -rf /usr   
Skipping /usr

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

恢复错误删除的重要文件可能非常困难。立即安装安全管理器保护自己,并减少您需要联系数据恢复服务的可能性!

在此处输入图片说明


支持安全牛
Michael Fulton

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”的任何命令行。


[[ "$1" == "rm" ]] && opt="-k";那又如何/bin/rm呢?
Rinzwind '18年

@Rinzwind我认为该功能很容易适应特定需求,尤其是case方法。
甜点

1

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

你可以别名rmrm -I

  • 要求删除目录或超过3个文件后立即进行确认
  • 只要您忽略-f哪个-I选项即可覆盖以前的选项。

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

设定

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

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

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

用法

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.