在权限分离的这次谈话中,that解释说,OpenBSD的ntpd有一个主进程,它调用settimeofday(),一个DNS进程负责查询DNS服务器,一个NTP协议进程负责向NTP服务器传递UDP。关于DNS进程,他要说的是:
我们得到的另一件事是一个单独的DNS服务进程,因为我们希望能够进行DNS,但我们不希望主进程这样做,因为DNS库有时会有错误,而且我们不希望网络扬声器这样做,因为.这是..。只是说不通。
让我们假设这个保证是不存在的(据我理解,这个设计早于它)。显然,这个设计本身是毫无意义的,就好像面对网络的服务被破坏了一样,攻击者在系统上有根。因此,主进程将分叉两个子进程,这将立即将特权丢弃给nobody或其他什么。这样,如果DNS库或NTP代码中存在安全漏洞,攻击者就无法对系统文件、主目录等进行写入访问。
这些对我来说都是有意义的。然而,我不明白为什么DNS和UDP进程之间的分离是有用的。不管哪一个被破坏,攻击者都是以同一用户的身份运行的。您可以将DNS进程放入例如nobody2用户中,但即便如此,nobody2也将与nobody一样没有特权。
有了质押,好处是显而易见的,因为例如DNS进程可以保证它只会进行DNS查询,这对攻击者来说是非常无用的。然而,我们假设质押不是一个因素,因为这种设计是在质押之前引入的。
我错过的三进程ntpd设计有什么安全好处吗?还是仅仅是一个与安全性无关的设计决策(也许考虑了未来类似质押系统的可能性)?
发布于 2017-01-04 23:04:40
(请注意,我对OpenBSD ntpd的设计一无所知,我只是回答有关分离进程的一般性问题。)
根据您的引用,我认为UDP进程与DNS进程的分离并不是出于安全考虑,而是出于架构方面的考虑:“因为.这是..。这根本没有道理“。UDP进程和DNS进程对完全不同的事件作出反应。如果它们处于相同的进程中,它们将使用单独的线程(显式的或隐式地使用围绕select调用的事件循环)。由于UDP进程和DNS进程独立运行,将它们放在同一个过程中将使设计复杂化,因此在默认情况下它们处于不同的进程中。
如果NTP服务器被设计为一个单一进程,那么设计就必须适应子系统的不同交互模式。那么线程就有意义了。但是,如果无论如何都存在进程分离,那么在同一个过程中分组不相关的子系统会使设计复杂化。
尽管如此,拥有单独的进程还是会带来安全好处的。一个好处是,并非所有的攻击都允许攻击者执行任意代码。有些攻击只允许本地化数据损坏,或暴露某些秘密数据,或可能导致崩溃,但总是以受控的方式(例如,只有空指针取消引用,而不是任意指针取消引用)。即使漏洞确实允许任意代码执行,有时编写漏洞是很复杂的,而利用更复杂的漏洞也会给防御方带来修复错误和部署更新的时间。
即使存在允许在进程中执行任意代码的漏洞,OS级别的机制也可能限制该进程。甚至在pledge之前,OpenBSD就允许对ptrace进行操作系统范围的限制,这应该在生产服务器上启用。以nobody形式运行的进程如果不能对其他进程进行裁剪,就不会直接损害它们。攻击者将不得不找到一些间接的方法,虽然DoS的机会很多,但是对DNS的破坏将不允许攻击者生成假的NTP通信量(它将无法绑定端口)。
发布于 2019-01-15 15:43:04
让我们假设这个保证是不存在的(据我理解,这个设计早于它)。显然,这个设计本身是毫无意义的,就好像面对网络的服务被破坏了一样,攻击者在系统上有根。
即使没有pledge,设计也不是毫无意义的。如果面向网络的服务被破坏,攻击者在系统上就没有root --这就是重点。
主进程生成NTPD子进程,该进程打开UDP套接字作为NTP服务器(端口123),然后子进程放弃特权。
在这种情况下,这意味着子进程将其真实、有效和保存的用户ID更改为_ntp用户的ID。
主进程保持为root,以便在必要时调用adjtime(2)系统调用。
面向网络的过程不再是root,完全消除了您提到的风险。root进程有一个严格控制的接口(通过IMSG系统),只允许它调用adjtime(2)。因此,破坏子进程的攻击者在系统上具有_ntp权限。并且只能在主机上发出adjtime(2)调用--必须比完全root折衷时的能力更低。
有关在这张幻灯片讲述的是OpenBSD中的安全控制之前的设计的早期版本,请参阅pledge(2):

https://security.stackexchange.com/questions/147295
复制相似问题