我一直认为“sudo”只是启动另一个登录过程,特别是使用“root”作为用户名并要求输入密码才能登录。运行某个程序后,它会结束并注销(或者:将打开的会话保持一段时间,然后退出)。不知道我从哪里听说的,但这对我来说似乎很合理。
但现在我发现了这个 sudoers-option:
ALL ALL = (root) NOPASSWD: /my/command
这允许我以 root 身份运行任何用户的任何程序没有询问任何密码。这让我想知道:
这是如何运作的?程序如何获得用户权限? sudo 是否需要一个服务器(作为守护进程等以 root 身份运行)并连接到该服务器,向其发送应执行的内容,然后该服务器以 root 权限执行它?
其他用户怎么样?
有没有什么好的和简单的解释这是如何工作的?
答案1
sudo
是一个所谓的“SetUID 二进制文件”,正如您在以下输出中看到的ls -l
:
$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 159016 Mar 21 20:40 /usr/bin/sudo
s
第四列中的(您通常会在其中找到可执行x
文件)告诉您 SetUID 位已设置。该位有一个重要含义:当执行设置了 SetUID 位的二进制文件时,它不会使用调用用户的用户 ID 运行,而是使用二进制文件所有者的用户 ID(在本例中root
)运行。
这就是线索。 sudo
始终以超级用户权限运行(如root
)。因此sudo
能够执行一些特权任务,例如调用仅允许的系统函数root
。这些系统调用之一(最重要的)是setuid(2)
and Friends。通过调用setuid()
一个进程可以改变将其 UID 更改为它想要的任何 UID(从而冒充另一个用户)。
所做sudo
的是:
- 读取并解析
/etc/sudoers
,查找调用用户及其权限, - 询问调用用户的密码(这通常是用户的密码,但也可以是目标用户的密码或像 一样跳过
NOPASSWD
) - 创建一个子进程,在其中调用
setuid()
更改为目标用户 - 执行 shell 或在该子进程中作为 argumentmnts 给出的命令
答案2
简单的答案是二进制文件suid
上的标志sudo
:
ls -l /usr/bin/sudo
---s--x--x. 1 root root 130712 02-26 13:31 /usr/bin/sudo
可执行文件上的标志suid
允许二进制文件运行setuid()
系统调用,无论执行者是谁 - root 用户或非 root 用户。
其余的取决于各个二进制文件的指令和配置。在 的情况下sudo
,它会解析配置文件(通常为/etc/sudoers
)来确定是否继续升级。
在某些文件上,时间戳信息仅限于 root 用户。以下来自示例服务器的示例演示了升级如何sudo
提供时间戳信息:
[artur@asus-ux21e ~]$ sudo ls -l /var/db/sudo/artur
total 12
-rw-------. 1 root artur 48 04-24 14:07 0
-rw-------. 1 root artur 48 04-24 11:27 1
-rw-------. 1 root artur 48 04-24 11:26 2