如何让非特权进程监听特权端口(下)

上回书说了一小撮别有用心的其它操作系统,现在要说广大人民群众喜闻乐见的 Linux 了。

Linux 下用 POSIX.1e capabilities [PRIVS] 来实现我们的需求。这个 patch 已经集成进 mainstream 了。

pam_cap

一开始的 linux-privs 只支持基于进程的 capability 控制,这对我们的要求并没有什么帮助,因为仍然需要从特权身份启动来降低权限。理论上,可以编写一个利用了 capability 的 pam 模块,来指定哪些用户的会话继承哪些权限,但和早期内核配套的 libcap 包里并没有这样的模块,直到后面的 libcap2 才有 pam_cap 实现此功能。

  • /etc/pam.d/login 里加入
auth    optional                        pam_cap.so

注意一定要加在任何 auth sufficient 之前,否则就被跳过了。当然,在 Debian 上可以加到 /etc/pam.d/common-auth 里。这是针对 login 用户的,如果是 su 用户,还需要改相应的 pam 文件,因为 @common-auth 在 su 里排在后面。

  • /etc/security/capability.conf 里加入对应用户的设置,比如
cap_net_bind_service    adoal

表示以用户 adoal 身份运行的进程可以绑定到特权端口。

文件系统 capability

从 2.6.24 内核开始, linux-privs 又支持了基于文件系统的 capability 功能,能够给文件系统里特定的可执行程序指定一个 capability,详见 [FCAP] 。简而言之执行

$ sudo setcap cap_net_bind_service=ep /usr/sbin/httpd

之后,任何用户(当然前提是对 /usr/bin/httpd 有 x 权限)都可以启动 apache 监听 80 端口而不需要特权身份。据说可以用 SELinux 来限制哪个用户只能绑定哪个端口,来做精细的控制,类似 FreeBSD 的 portacl 那样吧。但是 SELinux 太复杂,我等新手暂且敬而远之。

杯具的 Red Hat

非常值得一提的是,在企业用户里很流行的 Red Hat Enterprise Linux 5 由于生命周期太长而又坚持 ABI 不变动的原则,于是其古老的内核并不能支持基于文件系统的 capability 模型。另一方面,也没人把 pam_cap 移植过来,所以这里说的方法对 RHEL5 用户(以及 CentOS 5 之类的派生版用户)只能是梦想了。

RHEL6 里内核和 libcap 都更新了,已经可以支持上面两种方法。基于文件系统的方法我做了测试,正常。但是基于 pam_cap 的方法尝试未遂,虽然登录进去之后执行

getpcaps $$

可以看到 cap_net_bind_service 但是在 bind() 时仍然没有权限。究竟问题出在哪里,有待进一步研究。

[PRIVS]Linux POSIX.1e Capabilities <http://www.kernel.org/pub/linux/libs/security/linux-privs/>
[FCAP]POSIX Capabilities & File POSIX Capabilities <http://www.friedhoff.org/posixfilecaps.html>

评论

学习。 :)

学习。 :)

发表新评论

此内容将保密,不会被其他人看见。
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.