sudo内部如何工作?


74

sudo内部如何运作?不像root一样,怎么可能没有root密码就可以成为root su?该过程涉及哪些系统调用等?这不是Linux上一个巨大的安全漏洞吗(例如,为什么我不能编译一个补丁大sudo,既可以执行常规操作sudo却又不要求非特权用户使用的密码)?

我已经阅读过login和su internals。我还阅读了sudo应该如何使用?但尽管标题,他们主要是处理之间的差异susudo

Answers:


80

如果您看一下可执行文件sudo

$ which sudo
/usr/bin/sudo
$ ls -la /usr/bin/sudo
---s--x--x 2 root root 208808 Jun  3  2011 /usr/bin/sudo

您会注意到它带有许可位---s--x--x。这些可以细分如下:

-|--s|--x|--x
-      - first dash denotes if a directory or a file ("d" = dir, "-" = file)  
--s    - only the setuid bit is enabled for user who owns file
--x    - only the group execute bit is enabled
--x    - only the other execute bit is enabled

因此,当程序启用了setuid位(也称为SUID)时,这意味着当某人运行该程序时,它将以拥有该文件的用户的凭据(又名)运行。根在这种情况下。

如果我以saml用户身份运行以下命令:

$ whoami
saml

$ sudo su -
[sudo] password for saml: 

您会注意到,sudo实际上是以root身份运行的:

$ ps -eaf|grep sudo
root     20399  2353  0 05:07 pts/13   00:00:00 sudo su -

setuid机制

如果您好奇SUID的工作原理,请查看man setuid。这是手册页的摘录,比我能更好地解释了它:

setuid()设置调用进程的有效用户ID。如果呼叫者的有效UID是root,则还将设置实际UID和保存的set-user-ID。在Linux下,setuid()的实现类似于具有_POSIX_SAVED_IDS功能的POSIX版本。这允许set-user-ID(而不是root)程序删除其所有用户特权,执行一些未特权的工作,然后以安全的方式重新使用原始的有效用户ID。

如果用户是root或程序是set-user-ID-root,则必须格外小心。setuid()函数检查调用方的有效用户ID,如果它是超级用户,则所有与进程相关的用户ID均设置为uid。发生这种情况后,该程序将无法重新获得root特权。

这里的关键概念是程序具有真实的用户ID(UID)和有效的用户ID(EUID)。启用此位后,Setuid会设置有效用户ID(EUID)。

因此,从内核的角度来看,可以知道在我们的示例中,saml仍然是原始所有者(UID),但已将EUID设置为可执行文件的所有者。

塞吉德

我还应该提到,当我们分解sudo命令的权限时,第二组位用于组权限。组位还具有类似于setuid的名称,称为set group id(又称为setgid,SGID)。此功能与SUID相同,只是它使用组凭据而不是所有者凭据运行该进程。

参考文献


4
您应该使用sudo -s而不是,sudo su因为它是对的无用su。:)
Totor 2013年

4

真正的sudo二进制文件是setuid root,您不能只是将这样设置的文件存在。

setuid和setgid(分别是“在执行时设置用户ID”和“在执行时设置组ID”的缩写)[1]是Unix访问权限标志,允许用户分别在可执行文件的所有者或组的许可下运行可执行文件。更改目录中的行为。


好吧,这回答了我的部分问题。如果您详细说明sudo如何使用此位,以及更多有关此位的用途的信息,我很乐意接受此答案
strugee

2

为了回答似乎没有人接触过的有关系统调用的部分,重要的系统调用之一是setresuid()或setresgid()。我敢肯定还有其他人,但是这两个似乎很特定于setuid / sudo。

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.