![为什么 Web 服务器传统上以超级用户身份启动?](https://linux22.com/image/52952/%E4%B8%BA%E4%BB%80%E4%B9%88%20Web%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BC%A0%E7%BB%9F%E4%B8%8A%E4%BB%A5%E8%B6%85%E7%BA%A7%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E5%90%AF%E5%8A%A8%EF%BC%9F.png)
考虑到未来的 Web 服务器设置,我突然意识到,出于某种原因,Web 服务器通常以 root 身份启动,然后放弃setuid
工作进程的某些权限 ( )。此外,还经常chroot
涉及到,这并不完全是一种安全措施。
我想知道的是,为什么 Web 服务器(我已经管理了从 Apache、lighttpd 到 nginx 的所有内容)不能使用功能系统(capabilities(7)
),例如CAP_NET_BIND_SERVICE
,在 Linux 上并以非 root 用户身份启动? ...这样仍然侦听低于 1024 的特权端口。
或者更好的是,我认为大多数人都可以,但为什么这不是常见的做法呢?为什么不 ...
- 使用
setcap(8)
正在CAP_NET_BIND_SERVICE
运行的二进制文件? - 设置日志文件夹以允许(非 root)用户在其中写入
- ...,如果您觉得
chroot
有帮助,请使用chroot
或lxc
“监禁”网络服务器?
除了(工人)子进程可能会杀死父进程之外,我能想到的没有什么比直接开始为root
.
那么,为什么它们传统上以 root 身份启动,而之后却采取了一切措施来消除随之而来的隐含安全问题呢?
答案1
尽管 POSIX 有一个功能标准,我认为其中包括 CAP_NET_BIND_SERVICE,但这些对于一致性并且可能在某些方面是不相容在Linux等平台上实现。
由于像 apache 这样的网络服务器并不是只为一种平台编写的,因此使用 root 权限是最便携的方法。我想它可以专门在 Linux 和 BSD(或检测到支持的任何地方)上执行此操作,但这意味着行为会因平台而异,等等。
在我看来,你可以配置你的系统,以便任何网络服务器都可以这样使用;这里有一些关于这个 WRT apache 的(也许是笨拙的)建议:非根端口绑定。
那么为什么他们传统上当之后一切都已完成以消除随之而来的隐含安全问题时,是否以 root 身份启动?
他们以 root 身份启动,因为他们通常需要访问特权端口,并且传统上这是唯一的方法。他们后来降级的原因是因为他们随后不需要特权,并限制服务器常用的无数第三方附加软件带来的潜在损害。
这并非不合理,因为特权活动非常有限,并且按照惯例,许多其他系统守护进程连续运行 root,包括其他 inet 守护进程(例如,sshd
)。
请记住,如果服务器被打包以便可以使用 CAP_NET_BIND_SERVICE 作为非特权用户运行,这将允许任何非特权用户启动HTTP(S)服务,这或许是一个更大的风险。
答案2
在基于 Unix 的系统上,侦听特权端口的服务需要系统管理员的许可。这表明该服务正在由受信任的(至少是管理员)用户运行。此类服务的用户可以相信服务器应用程序有一定的管理监督。这种信任的价值可能不如前几十年那么大。
许多 Web 服务器运行在较旧的操作系统内核上,这些内核可能不支持允许其作为非特权用户启动和运行所需的功能。所需的内核更改相对较新,并且没有跨操作系统内核标准化。可以有条件地为此类环境编译软件。然而,此类更改无法在大多数平台中使用,并且可能未经过充分测试或未达到预期的安全性。
守护进程通常以 root 身份运行来执行需要 root 访问权限的所有操作,然后切换到非特权 UID。这可以保护资源,同时防止程序运行后造成太大损害。对于 Web 服务器,应防止 SSL 密钥被恶意服务器应用程序读取,但必须读取 SSL 密钥才能配置 SSL 侦听器。分裂特权允许对资源进行裂脑访问,这可用于显着提高安全性。
虽然可以监禁 Web 服务器,但在许多系统上,监狱可能包含文件系统的重要部分。这可能既难以配置又容易出错。监禁应用程序通常意味着它是一种更安全的配置。在这种情况下,由于监狱配置不正确的风险,这种信任可能会被错误地放置。即使没有监狱,也很难诊断访问问题。将大块文件系统排除在监狱之外会使这变得更加困难。
答案3
以 root 身份启动 Web 服务器有多种原因:
- 绑定到端口 80(低于 1024 的端口保留给 root,因此,如果远程用户连接到低端口上的服务,他们就知道该服务已获得 root 批准);
- 设置限制,例如 chroot;
- 在适用的情况下阅读和服务用户的网页。
最不重要的原因是设置不当;保护此类设置的最简单方法是要求用户公开网页。当用户可能想要拥有具有访问控制的私人网页(例如,教授希望通过网络共享考试文本但不想让学生看到它们的大学机器)时,这不起作用。在这种情况下,需要更复杂的方法(例如,要求网页具有允许 Web 服务器读取它们的 ACL)。
以 root 身份启动的 Web 服务器通常仅以 root 身份启动,然后将权限降至专用用户。在放弃权限之前,他们会绑定端口80,可能会读取一些文件(例如SSL私钥文件),并可能执行其他遏制。
[为什么不]在正在运行的二进制文件上使用
setcap(8)
with ?CAP_NET_BIND_SERVICE
这是可以做到的,但需要一个支持功能的系统。相对于 Unix 的历史,甚至相对于 Web 服务器的历史来说,这是相对较新的。
[为什么不]设置日志文件夹以允许(非root)用户在那里写入?
通常这样做;否则,Web 服务器进程通过 Unix 或 Internet 套接字将日志记录到日志守护进程。
[为什么不]如果您觉得 chroot 有帮助,请使用 chroot 或 lxc 来“监禁”Web 服务器?
这意味着 Web 服务器将能够读取其所有配置文件,例如 SSL 私钥。有时,漏洞允许远程攻击者检索任意文件;以阻止服务器访问配置文件的方式限制服务器可以避免在这种情况下暴露。
大多数 UNIX 系统的一个弱点是它们不允许非特权进程设置一个它无法突破的限制区域。在 Linux 下,这是可能的,因为内核 3.8 中的命名空间改进,尚未广泛使用。