在Linux中免密使用sudo

sudo apt update sudo systemctl restart nginx sudo reboot

使用Linux时,我们经常会用到sudo命令。然而,每次都输入密码确实有些麻烦。

当这种麻烦达到极致时,我们最终会下定决心,去配置sudo免密码输入。想必,找到这篇文章的您,也和我有着类似的心情吧。

本文将整理如何在Linux中免密码使用sudo的方法。

带有Tux和钥匙的Linux安全

sudo的配置在哪里?以及如何修改?

sudo的配置文件位于此处:

/etc/sudoers

sudo的配置语法非常严格,一旦出错可能会带来大麻烦。如果配置错误导致sudo本身无法使用,恢复起来会很棘手。因此,我们应该使用专用的命令visudo

sudo visudo

visudo在保存时会进行语法检查,如果存在拼写错误会立即提示。查看官方手册,也强烈建议使用visudo

但是,不要直接修改/etc/sudoers

输入sudo visudo后,/etc/sudoers文件会立即打开,您可以直接进行修改。

然而,直接打开并修改/etc/sudoers文件并不是一个好习惯。

我通常倾向于不触动主配置文件,而是在/etc/sudoers.d/目录下创建一个新文件。

这样做的好处是,将来更容易找到自己做了哪些更改,也更容易恢复。

sudo被设计为包含此目录下文件的配置。

实际上,/etc/sudoers文件的最后一行会看到include /etc/sudoers.d/

sudo visudo -f /etc/sudoers.d/no-password-common-commands

文件名可以自由选择,只要以后容易识别即可。但是,最好不要随意命名,否则将来会给自己带来麻烦。

哦!请注意,文件名中包含~.的文件会被sudoers忽略。该目录下的README文件中也对此进行了说明。

了解配置格式

sudoers的配置格式大致如下:

说实话……这语法根本记不住。最好把它们写下来,或者将本页面添加到收藏夹。

虽然不常用,但偶尔需要用到时,总是记不起来。

用户名 主机=(执行用户) 选项: 命令

例如,如果用户名为potter,并且希望免密码执行apt update,可以这样写:

potter ALL=(ALL) NOPASSWD: /usr/bin/apt

各部分的含义如下:

  • potter:要应用配置的用户名。
  • ALL:在所有主机上应用。
  • (ALL):表示可以用哪个用户的权限来执行。有时也会看到有人写成(root)。我通常使用ALL。
  • NOPASSWD:不询问密码。
  • /usr/bin/apt:允许执行命令的“绝对路径”。

如果您不确定命令的路径,可以使用which命令进行确认:

~$which apt
/usr/bin/apt

~$which apt-get
/usr/bin/apt-get

~$which reboot
/usr/sbin/reboot

~$which systemctl
/usr/bin/systemctl

开放所有权限的诱惑

这里有一个非常强烈的诱惑:

potter ALL=(ALL) NOPASSWD: ALL

这看起来非常简洁,所有sudo命令都可以免密码执行,非常方便,简直太方便了。

虽然这是个人选择,但我认为最好还是克制这种诱惑。我实在不想想象,一个错误的命令直接以root权限执行的后果。

即使脚本运行出错,也没有了密码输入这个最后的“刹车”。如果终端暂时打开,有人操作了,那后果不堪设想。这个世界上有很多奇怪的人……

选择权在您。

只允许常用命令免密码

我倾向于“只对常用命令开放”这种折衷方案。这种方式相当不错。

例如,如果只想让aptapt-getrebootsystemctl这些命令免密码使用,可以这样做:

首先打开配置文件:

sudo visudo -f /etc/sudoers.d/no-password-common-commands

然后像下面这样编写:

potter ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/sbin/reboot, /usr/bin/systemctl

现在,potter用户可以免密码执行以下命令:

sudo apt update
sudo apt -y upgrade
sudo apt-get update
sudo reboot
sudo systemctl reload nginx

如果觉得开放systemctl的所有权限负担太大,也可以只允许特定的systemctl命令:

potter ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx

分行书写更易读

当命令过多时,一行会变得很混乱。这时可以使用\来分行。

对于Linux用户来说,分行是很常见的操作,但奇怪的是,实际操作时却很少使用\。不过,使用它确实可以提高可读性。

potter ALL=(ALL) NOPASSWD: \
    /usr/bin/apt, \
    /usr/bin/apt-get, \
    /usr/sbin/reboot, \
    /usr/bin/systemctl

这样看起来既美观又整洁。

应用于特定组

这个设置也非常有用。在多人管理的服务器中,以组为单位进行管理会更方便。

如果想应用于特定组,可以使用%组名的格式。

例如,如果是admin组,可以这样写:

%admin ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/apt, /usr/bin/apt-get

延长密码输入保持时间

如果彻底取消密码输入让您感到不安,还有另一种方法:调整密码再次询问的时间。

通常,输入一次密码后,在10到15分钟内不会再次询问,这个时间是可以调整的。

可以使用timestamp_timeout设置来实现。

例如,这样设置可以让sudo在60分钟内不再询问密码:

Defaults timestamp_timeout=60

单位是“分钟”,但如果设置为“0”,那将是每次都必须输入密码的噩梦。如果设置为“-1”,则一旦输入sudo密码,直到终端关闭都不会再询问。这几乎与ALL带来的便利性相当,但使用时仍会有些不安。

当然,免密码允许和延长保持时间这两种设置可以共存。

例如,可以这样组合:

Defaults timestamp_timeout=30

potter ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/sbin/reboot

对于经常使用的命令免密码,其他sudo命令则在一次认证后保持30分钟有效期。

我认为这在便利性和安全之间找到了一个很好的平衡点。毕竟,减少麻烦是好事,但我不希望以增加不安为代价。

总结

取消sudo密码输入并不难。

虽然上面的说明很长,但简单总结一下就是:

  1. 使用visudo/etc/sudoers.d/目录下创建单独的配置文件。
sudo visudo -f /etc/sudoers.d/no-password-common-commands
  1. 添加NOPASSWD规则即可。
Defaults timestamp_timeout=30

potter ALL=(ALL) NOPASSWD: \
    /usr/bin/apt, \
    /usr/bin/apt-get, \
    /usr/sbin/reboot

至于开放多少密码权限,取决于您自己的判断,但我希望您记住这一点:

只有手指的舒适和内心的安宁同时得到满足,才是真正的舒适。