如何在使用特定命令时强制`sudo`每次都要求输入密码?

有没有办法强制sudo命令在我使用sudo rm /path/file时每次都要求输入密码?
我想保护自己免受因为注意力不集中而导致的低级错误,尤其是在运行一些历史命令时。

3在一个正常设置的系统中,无论你运行什么命令,sudo 都会要求输入密码。 - Pilot6
7@Pilot6,是的,但正如你所知,默认情况下,在接下来的15分钟内不会要求输入密码。因此,我希望在每次使用rm命令时强制要求输入sudo密码。 - pa4080
1请问您需要将以下英文内容翻译成中文:"Translate from English to Chinese. Return translated text only: something like this: https://askubuntu.com/questions/636092/how-to-get-sudo-to-prompt-you-for-a-password-each-time"请将翻译后的文本返回,不要进行解释。 - user986805
你好,@Kulfy,你说的k选项是什么意思? - pa4080
@Kulfy,我已经纠正了问题。它是一个(随机的)普通文件。 - pa4080
@Kulfy,谢谢,我明白了。我在我的.bashrc中添加了以下函数:function sudo() { if [[ $@ =~ ^rm ]]; then /usr/bin/sudo -k $@; else /usr/bin/sudo $@; fi; }。它运行得很好。一旦问题重新开放,我会请你写一个答案 :) - pa4080
4虽然这个问题与之前的问题有关且引起了我的兴趣,但我不认为它是如何让sudo每次都提示输入密码的重复问题,因为那个问题是关于如何对所有命令进行设置,而这个问题是关于如何对特定命令进行设置。至少按照目前的描述,那里的答案并没有解释如何适应这里所问到的单个命令情况。 - Eliah Kagan
4个回答

如其他答案中所述,sudo 可以设置缓存凭据时间戳的超时时间。可以使用 sudoers 中的 Defaults 为特定命令执行此操作:
Defaults!/bin/rm timestamp_timeout=0

永远记得使用visudo编辑sudoers。我建议在/etc/sudoers.d中使用一个插入文件,而不是直接编辑/etc/sudoers。例如:

sudo visudo -f /etc/sudoers.d/always-ask-pass-for-rm

sudoers的manpage中:

Defaults

Certain configuration options may be changed from their default values at run-time via one or more Default_Entry lines. These may affect all users on any host, all users on a specific host, a specific user, a specific command, or commands being run as a specific user. Note that per-command entries may not include command line arguments. If you need to specify arguments, define a Cmnd_Alias and reference that instead.

Default_Type ::= 'Defaults' |
                 'Defaults' '@' Host_List |
                 'Defaults' ':' User_List |
                 'Defaults' '!' Cmnd_List |
                 'Defaults' '>' Runas_List

Default_Entry ::= Default_Type Parameter_List

Parameter_List ::= Parameter |
                   Parameter ',' Parameter_List

Parameter ::= Parameter '=' Value |
              Parameter '+=' Value |
              Parameter '-=' Value |
              '!'* Parameter
请注意,它确实提到了您可以影响“以特定用户身份运行的命令”,但没有提及由特定用户运行的命令,因此可能无法仅限制为您的用户。manpage中的示例中没有包含相关内容。

ln -s /bin/rm rmdo; sudo ./rmdo <file> - user986805
7@bac0n 我的理解是,这个措施更多是为了防止意外的自毁行为,而不是防止有意的攻击。否则,任何具有 shell 访问权限的账户都允许随意使用 "sudo" 命令的话,那就相当愚蠢了。 - sudo mcsudoface
今天刚创建的用户账户给出了一个非常棒的第一次回答!简直就像是我自己的回答加强版。干得好! - WinEunuuchs2Unix
当没有特定的可执行二进制文件时,例如Shell内置命令,我该如何采用这种方法? - Kulfy
@Kulfy 你如何使用sudo运行一个shell内置命令? - Eliah Kagan
@EliahKagan 例如 sudo alias?这可能听起来有点奇怪,但我只是好奇。 - Kulfy
2@Kulfy sudo 只能运行外部命令。在不寻常的情况下,除非你有一个名为alias的外部命令,否则sudo alias会报错“sudo: alias: command not found”。一些shell(如Bash)具有一些内置命令,它们会覆盖外部命令。如果尝试使用sudo运行它们,实际上是运行同名的外部命令。例如,sudo killsudo printfsudo echo都是运行外部命令。请参阅为什么`sudo cd /var/named`无法工作?为什么有/bin/echo,我为什么要使用它? - Eliah Kagan
@EliahKagan 我明白了。谢谢你提供的信息。 - Kulfy

你可以使用sudo命令的-k选项来重置时间戳。

如果将sudo -k作为一个命令使用,它会立即过期/失效缓存的凭据。

但是,如果将sudo -k与某个命令一起使用,例如sudo -k rm /some/file,则即使已经缓存了某些凭据,shell也会要求输入密码。在这种情况下,新的凭据不会被缓存。这意味着如果之后执行另一个带有sudo的命令,它将不会要求输入密码(如果之前已经缓存了凭据)。

来自sudo的手册页

-k [命令] 当单独使用时,sudo的-k(kill)选项会使用户的缓存凭据失效。下次运行sudo时将需要输入密码。此选项不需要密码,并且添加了该选项以允许用户从.logout文件中撤销sudo权限。并非所有安全策略都支持凭证缓存。
当与可能需要密码的命令或选项一起使用时,-k选项将导致sudo忽略用户的缓存凭据。因此,sudo将提示输入密码(如果安全策略要求),并且不会更新用户的缓存凭据。
如果您希望使sudo在特定命令中每次都要求密码而无需每次使用k选项,您可以在.bashrc中定义自定义函数。例如,来自pa4080的评论
sudo() { if [[ $@ =~ ^rm ]]; then /usr/bin/sudo -k "$@"; else /usr/bin/sudo "$@"; fi; }

使用完整路径来绕过sudo是很容易的,所以我认为它给人一种虚假的安全感。 - user986805
3@bac0n,我同意这个是容易规避的,但我不认为这意味着它会给人一种虚假的安全感。这里的用例就像一个带有盖子的火警报警器;盖子并不是为了阻止恶意用户触发警报,而是为了防止粗心的用户意外靠近按钮。事实上,它很容易被故意绕过,这算是设计之意,而不是一种漏洞。 - ymbirtt

你可以设置sudo始终要求输入密码:

$ sudo cat /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults    env_reset, timestamp_timeout=120, pwfeedback
#Defaults   mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

在我的配置中,我将sudo超时设置为2小时(120分钟),在再次要求输入密码之前。将其设置为0将要求每次使用sudo时输入密码。

为什么将它设置为1分钟?OP要求不要缓存凭据;将其设置为0。 - chepner
但为什么如此强调用户并未询问的价值观呢?将其设为0似乎是事后的想法,而它应该是完整的答案。 - chepner
@chepner 我已经修改了答案。谢谢。 - WinEunuuchs2Unix

rm包装脚本

不久前,我为rm命令编写了一个包装脚本:

一些值得注意的特点:

  • 每次调用rm时,必须使用加密密码,除非它在类似sudo apt-getsudo update-grub的批处理作业中使用。
  • 确保顶级目录永远不会被删除,即使传递了相对路径。
  • 每次使用rm时,都会将其记录到journalctl/var/log/syslog中。