了解 Linux 系统编程中的能力

功能允许在与当前进程不同的单独线程中评估一些重要的系统权限。 这样,您无需以 root 身份运行程序即可访问系统的某些部分。

POSIX.1e 的第 25 节作为一种需求的解决方案是关于这个问题的。 随着 Linux 内核版本 2.6.26 的发布,该部分中定义的权限以及更多权限的开发已经完成。 这是您需要了解的有关 Linux 内核功能的所有信息。

了解 Capabilities API 逻辑

基于 Unix 的系统中的授权控制包括两个步骤:

  • 如果正在运行的应用程序的当前所有者(有效用户 ID,EUID)为零,则系统不会检查授权
  • 如果 EUID 值不为零,则系统根据相关应用的有效用户和组的权限执行控制过程

一些应用程序在运行时需要拥有更广泛的权限(SUID、SGIT 位)。 作为最典型的 example,你可以想到 passwd 应用程序。 有了这个,系统中的用户可以更改他们的密码。 但是,要写入 /etc/影子 保存加密密码的文件,必须使用 root 用户权限(即用户 ID = 0)。

为了解决这个问题,passwd 应用程序有一个 SUID 位。 无论哪个用户运行此应用程序,活动所有者 (EUID) 将始终是 root:

ls -l /usr/bin/passwd

# Output
-rwsr-xr-x. 1 root root 32552 Jul 23 2021 /usr/bin/passwd

在传统的 Unix 身份验证模型中运行 SUID 应用程序的能力似乎已经解决了这个问题。 但是,具有 SUID 位的应用程序中的严重错误为在系统中具有完全权限的用户打开了运行不需要的代码的大门。 如果可能,理想的应用程序应该能够在不需要 root 用户权限的情况下运行。

问题不仅限于 SUID 位。 当您想在基于 Unix 的系统上侦听小于 1024 的特权 TCP 或 UDP 端口时,您还必须具有 root 用户权限。 为了 example,为了能够侦听 Web 服务器的 TCP 80 端口,您必须以 root 用户身份运行应用程序。

多年来,人们已经明白,使用完全授权的用户帐户运行为网络环境提供服务的软件是多么具有破坏性。 作为一种临时解决方案,采用了只有一小部分程序以root身份侦听特权端口,然后将活动用户ID更改为另一个用户以进行后续进程(例如 example,权限受限的nobody用户)。

这个系统已经使用了多年,它的简单性运行良好,并且仍然有效地使用。 但是,如今,除了上述系统之外,还可以通过 Linux 功能 API 获得一些特定于应用程序的附加功能,而无需 root 权限。

Linux 能力模型,解释!

您可以在 Linux 内核中找到最全面的功能 API 实现。 现代 Linux 发行版也尝试在系统范围内尽可能多地使用这种新模型。

为了 example,要使 ping 应用程序正常工作,它必须能够打开 RAW 套接字,这些套接字通常只为 root 用户保留。 在旧的 Linux 发行版中,问题是给应用程序提供 SUID 位,以便普通用户可以使用它。 在这些版本中,当您从应用程序中删除 SUID 位并尝试以普通用户身份运行应用程序时,您会收到以下错误:

ping 8.8.8.8

# Output
ping: icmp open socket: Operation not permitted

而在现代 Linux 发行版上,ping 应用程序可能没有 SUID 位:

ls -l /bin/ping 

# Output
-rwxr-xr-x. 1 root root 95232 Jul 25 2021 /bin/ping

不过,您可以作为普通用户成功运行该应用程序。 使这成为可能的机制是 ping 应用程序具有特殊的能力 CAP_NET_RAW.

您可以通过以下方式了解应用程序的其他功能 盖帽 命令如下:

sudo getcap /bin/ping

# Output
/bin/ping cap_net_raw=ep

如果 getcap 命令返回空响应,您可以手动设置此值:

sudo setcap cap_net_raw+ep /bin/ping

过程能力模型

在 Linux 实现中,每个进程的功能分为三个标题:

能力陈述
允许在这个集群中,有一个相关进程允许的附加功能列表。 授予权限并不意味着当时可以积极使用。 可以通过附加操作将此处的授权包含在有效能力集中。
有效的它显示了相关进程的当前活动能力列表。 借助调节技能系统的辅助功能,可以放弃或重新获得技能。 然而,在任何情况下,这只能在允许组中已授权的人员中进行。
可继承当应用程序启动一个新进程时,新启动的进程会显示它将从允许列表继承的功能列表。

任何时候运行进程的允许、有效和可继承的能力列表在行上显示为位掩码 CapPrm, 盖夫, 和 盖印 在文件中 /proc//状态. 除此之外 CapBnd 行包含在能力边界控制操作中使用的位掩码。

为了 example,尝试从 /proc/自我/状态 文件:

cat /proc/self/status | grep Cap

# Output
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

Linux 中的文件能力模型

文件能力系统的运行依赖于这些属性可以存储在虚拟文件系统(VFS)层的前提。 与流程模型类似,文件的功能分为三个标题:

1. 允许

当相应的可执行文件在该集群中运行时,系统确定进程的允许能力。

2.有效

与过程能力模型不同,此标头仅存储一位:活动或非活动。 如果该位有效,则在运行该文件并创建进程时,将自动将文件允许列表中定义的能力转移到相关进程的有效能力列表中。 如果该位未激活,则不会将文件上允许的功能自动传输到正在运行的进程。

但是,如果相关应用的代码与能力系统集成,则可以通过系统调用激活文件的许可集中的权限。 这种行为的主要目的是确保不包含能力系统特定代码的旧应用程序,在软件代码级别的开发可以与能力系统一起工作,而无需更改任何源代码。

您可能认为编写得更好的应用程序只会在需要时使用功能。 如果该位处于活动状态,则允许列表中的所有功能在应用程序启动时都将变为活动状态。

3. 可继承

与流程模型一样,相关文件运行并发生流程。 如果在此之后另一个应用程序从该进程中运行,它会包含在新进程的允许列表中。 总而言之,它表示要继承的能力列表。

能力在 Linux 系统中的作用

当您以普通用户身份运行某个进程时,您没有任何权限。 因此,您只能访问系统允许普通用户访问的分区。 这背后的主要原因是加强系统安全并实施此类措施。

允许所有用户访问所有资源会造成严重的安全漏洞。 出于恶意目的使用系统的人很容易利用系统漏洞。 Linux 功能在这些问题上派上用场。 您可以使用由内核提供支持的 API 功能轻松增强应用程序的安全性。

Linux 能力只是需要考虑的问题之一,需要考虑执行非常强大的方法,例如划分 root 用户的权限,为非特权用户分配各种权限,以及对 Linux 服务器的 Internet 服务中的开放端口采取各种预防措施。