在我的开发盒上有这种限制是非常令人讨厌的,因为除了我之外再也没有其他用户了。

我知道一些标准的变通办法,但没有一个能完全满足我的要求:

authbind (Debian测试中的版本,1.0,仅支持IPv4) 使用iptables REDIRECT目标将低端口重定向到高端口(iptables的IPv6版本ip6tables尚未实现“nat”表) sudo(作为根是我试图避免的) SELinux(或类似的)。(这只是我的开发框,我不想引入很多额外的复杂性。)

是否有一些简单的sysctl变量允许非根进程绑定到Linux上的“特权”端口(端口小于1024),或者我只是运气不好?

编辑:在某些情况下,您可以使用功能来做到这一点。


当前回答

好的,感谢那些指出系统和CAP_NET_BIND_SERVICE功能的人。如果您有一个最新的内核,确实可以使用它来以非root身份启动服务,但绑定低端口。简单的回答是:

setcap 'cap_net_bind_service=+ep' /path/to/program

然后在任何程序执行之后,它都将具有CAP_NET_BIND_SERVICE能力。Setcap在debian包libcap2-bin中。

现在要注意的是:

You will need at least a 2.6.24 kernel This won't work if your file is a script. (i.e. uses a #! line to launch an interpreter). In this case, as far I as understand, you'd have to apply the capability to the interpreter executable itself, which of course is a security nightmare, since any program using that interpreter will have the capability. I wasn't able to find any clean, easy way to work around this problem. Linux will disable LD_LIBRARY_PATH on any program that has elevated privileges like setcap or suid. So if your program uses its own .../lib/, you might have to look into another option like port forwarding.

资源:

能力(7)手册页。如果您打算在生产环境中使用功能,请仔细阅读这篇文章。这里详细介绍了如何在exec()调用之间继承功能的一些非常棘手的细节。 Setcap手册页 “在GNU/Linux上绑定1024以下的端口,没有根”:第一次让我想到setcap的文档。

注意:RHEL首次在v6中添加了这个功能。

其他回答

Linux支持支持更细粒度权限的功能,而不仅仅是“此应用程序以根用户身份运行”。其中一个功能是CAP_NET_BIND_SERVICE,它是关于绑定到特权端口(<1024)的。

不幸的是,我不知道如何利用它来运行一个应用程序作为非根,同时仍然给它CAP_NET_BIND_SERVICE(可能使用setcap,但肯定有一个现有的解决方案)。

还有一种“djb方式”。您可以使用此方法以运行在tcpserver下任何端口上的根用户身份启动您的进程,然后在进程启动后,它将把进程的控制权立即交给您指定的用户。

#!/bin/sh

UID=$(id -u username)
GID=$(id -g username)
exec tcpserver -u "${UID}" -g "${GID}" -RHl0 0 port /path/to/binary &

更多信息,请参见:http://thedjbway.b0llix.net/daemontools/uidgid.html

使用systemd,您只需要稍微修改您的服务以接受预激活的套接字。

稍后可以使用systemd套接字激活。

不需要任何功能、iptables或其他技巧。

这是这个简单的python http服务器示例中的相关systemd文件的内容

文件httpd-true.service

[Unit]
Description=Httpd true 

[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic

PrivateTmp=yes

文件httpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target

使用privbind实用程序:它允许非特权应用程序绑定到预留端口。

出于某种原因,没有人提到降低sysctl net.ipv4。Ip_unprivileged_port_start到您需要的值。 示例:我们需要将应用程序绑定到443端口。

sysctl net.ipv4.ip_unprivileged_port_start=443

有些人可能会说,存在潜在的安全问题:非特权用户现在可能绑定到其他特权端口(444-1024)。 但是你可以用iptables通过阻塞其他端口轻松解决这个问题:

iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP

与其他方法的比较。这个方法:

from some point is (IMO) even more secure than setting CAP_NET_BIND_SERVICE/setuid, since an application doesn't setuid at all, even partly (capabilities actually are). For example, to catch a coredump of capability-enabled application you will need to change sysctl fs.suid_dumpable (which leads to another potential security problems) Also, when CAP/suid is set, /proc/PID directory is owned by root, so your non-root user will not have full information/control of running process, for example, user will not be able (in common case) to determine which connections belong to application via /proc/PID/fd/ (netstat -aptn | grep PID). has security disadvantage: while your app (or any app that uses ports 443-1024) is down for some reason, another app could take the port. But this problem could also be applied to CAP/suid (in case you set it on interpreter, e.g. java/nodejs) and iptables-redirect. Use systemd-socket method to exclude this problem. Use authbind method to only allow special user binding. doesn't require setting CAP/suid every time you deploy new version of application. doesn't require application support/modification, like systemd-socket method. doesn't require kernel rebuild (if running version supports this sysctl setting) doesn't do LD_PRELOAD like authbind/privbind method, this could potentially affect performance, security, behavior (does it? haven't tested). In the rest authbind is really flexible and secure method. over-performs iptables REDIRECT/DNAT method, since it doesn't require address translation, connection state tracking, etc. This only noticeable on high-load systems.

根据具体情况,我将在sysctl、CAP、authbind和iptables-redirect之间进行选择。我们有这么多选择真是太好了。