# 在Linux中免密使用sudo `sudo apt update` `sudo systemctl restart nginx` `sudo reboot` 使用[[Linux]]时,我们经常会用到`sudo`命令。然而,每次都输入密码确实有些麻烦。 当这种麻烦达到极致时,我们最终会下定决心,去配置sudo免密码输入。想必,找到这篇文章的您,也和我有着类似的心情吧。 本文将整理如何在`Linux`中免密码使用`sudo`的方法。 ![带有Tux和钥匙的Linux安全](/media/whitedec/blog_img/vaBoSfdn.webp) ## sudo的配置在哪里?以及如何修改? sudo的配置文件位于此处: `/etc/sudoers` sudo的配置语法非常严格,一旦出错可能会带来大麻烦。如果配置错误导致`sudo`本身无法使用,恢复起来会很棘手。因此,我们应该使用专用的命令`visudo`。 ```bash sudo visudo ``` `visudo`在保存时会进行语法检查,如果存在拼写错误会立即提示。查看官方手册,也强烈建议使用`visudo`。 ## 但是,不要直接修改/etc/sudoers 输入`sudo visudo`后,`/etc/sudoers`文件会立即打开,您可以直接进行修改。 然而,直接打开并修改`/etc/sudoers`文件并不是一个好习惯。 我通常倾向于不触动主配置文件,而是在`/etc/sudoers.d/`目录下创建一个新文件。 这样做的好处是,将来更容易找到自己做了哪些更改,也更容易恢复。 sudo被设计为包含此目录下文件的配置。 实际上,`/etc/sudoers`文件的最后一行会看到`include /etc/sudoers.d/`。 ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 文件名可以自由选择,只要以后容易识别即可。但是,最好不要随意命名,否则将来会给自己带来麻烦。 哦!请注意,文件名中包含`~`和`.`的文件会被sudoers忽略。该目录下的README文件中也对此进行了说明。 ## 了解配置格式 sudoers的配置格式大致如下: 说实话……这语法根本记不住。最好把它们写下来,或者将本页面添加到收藏夹。 虽然不常用,但偶尔需要用到时,总是记不起来。 ```bash 用户名 主机=(执行用户) 选项: 命令 ``` 例如,如果用户名为`potter`,并且希望免密码执行`apt update`,可以这样写: ```bash potter ALL=(ALL) NOPASSWD: /usr/bin/apt ``` 各部分的含义如下: * potter:要应用配置的用户名。 * ALL:在所有主机上应用。 * (ALL):表示可以用哪个用户的权限来执行。有时也会看到有人写成(root)。我通常使用ALL。 * NOPASSWD:不询问密码。 * /usr/bin/apt:允许执行命令的“绝对路径”。 如果您不确定命令的路径,可以使用`which`命令进行确认: ```bash ~$which apt /usr/bin/apt ~$which apt-get /usr/bin/apt-get ~$which reboot /usr/sbin/reboot ~$which systemctl /usr/bin/systemctl ``` ## 开放所有权限的诱惑 这里有一个非常强烈的诱惑: ```bash potter ALL=(ALL) NOPASSWD: ALL ``` 这看起来非常简洁,所有sudo命令都可以免密码执行,非常方便,简直太方便了。 虽然这是个人选择,但我认为最好还是克制这种诱惑。我实在不想想象,一个错误的命令直接以root权限执行的后果。 即使脚本运行出错,也没有了密码输入这个最后的“刹车”。如果终端暂时打开,有人操作了,那后果不堪设想。这个世界上有很多奇怪的人…… 选择权在您。 ## 只允许常用命令免密码 我倾向于“只对常用命令开放”这种折衷方案。这种方式相当不错。 例如,如果只想让`apt`、`apt-get`、`reboot`、`systemctl`这些命令免密码使用,可以这样做: 首先打开配置文件: ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 然后像下面这样编写: ```ini potter ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/sbin/reboot, /usr/bin/systemctl ``` 现在,`potter`用户可以免密码执行以下命令: ```bash sudo apt update sudo apt -y upgrade sudo apt-get update sudo reboot sudo systemctl reload nginx ``` 如果觉得开放`systemctl`的所有权限负担太大,也可以只允许特定的`systemctl`命令: ```bash potter ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx ``` ## 分行书写更易读 当命令过多时,一行会变得很混乱。这时可以使用`\`来分行。 对于Linux用户来说,分行是很常见的操作,但奇怪的是,实际操作时却很少使用`\`。不过,使用它确实可以提高可读性。 ```bash potter ALL=(ALL) NOPASSWD: \ /usr/bin/apt, \ /usr/bin/apt-get, \ /usr/sbin/reboot, \ /usr/bin/systemctl ``` 这样看起来既美观又整洁。 ## 应用于特定组 这个设置也非常有用。在多人管理的服务器中,以组为单位进行管理会更方便。 如果想应用于特定组,可以使用`%组名`的格式。 例如,如果是`admin`组,可以这样写: ```bash %admin ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/apt, /usr/bin/apt-get ``` ## 延长密码输入保持时间 如果彻底取消密码输入让您感到不安,还有另一种方法:调整密码再次询问的时间。 通常,输入一次密码后,在10到15分钟内不会再次询问,这个时间是可以调整的。 可以使用`timestamp_timeout`设置来实现。 例如,这样设置可以让sudo在60分钟内不再询问密码: ```bash Defaults timestamp_timeout=60 ``` 单位是“分钟”,但如果设置为“0”,那将是每次都必须输入密码的噩梦。如果设置为“-1”,则一旦输入sudo密码,直到终端关闭都不会再询问。这几乎与`ALL`带来的便利性相当,但使用时仍会有些不安。 当然,免密码允许和延长保持时间这两种设置可以共存。 例如,可以这样组合: ```bash 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/`目录下创建单独的配置文件。 ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 2. 添加`NOPASSWD`规则即可。 ```ini Defaults timestamp_timeout=30 potter ALL=(ALL) NOPASSWD: \ /usr/bin/apt, \ /usr/bin/apt-get, \ /usr/sbin/reboot ``` 至于开放多少密码权限,取决于您自己的判断,但我希望您记住这一点: > 只有手指的舒适和内心的安宁同时得到满足,才是真正的舒适。