在我的开发盒上有这种限制是非常令人讨厌的,因为除了我之外再也没有其他用户了。
我知道一些标准的变通办法,但没有一个能完全满足我的要求:
authbind (Debian测试中的版本,1.0,仅支持IPv4)
使用iptables REDIRECT目标将低端口重定向到高端口(iptables的IPv6版本ip6tables尚未实现“nat”表)
sudo(作为根是我试图避免的)
SELinux(或类似的)。(这只是我的开发框,我不想引入很多额外的复杂性。)
是否有一些简单的sysctl变量允许非根进程绑定到Linux上的“特权”端口(端口小于1024),或者我只是运气不好?
编辑:在某些情况下,您可以使用功能来做到这一点。
出于某种原因,没有人提到降低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之间进行选择。我们有这么多选择真是太好了。
另外两种简单的可能性:Daemon和Proxy
守护进程
对于“一个绑定在低端口上的守护进程并将控制权交给您的守护进程”,有一个旧的(不流行的)解决方案。它被称为inetd(或xinetd)。
缺点是:
你的守护进程需要在stdin/stdout上对话(如果你不控制守护进程——如果你没有源代码——那么这可能是一个showstopper,尽管一些服务可能有inetd兼容性标志)
每个连接都会生成一个新的守护进程
这是链条上的一环
优点:
可以在任何旧的UNIX上使用
一旦系统管理员设置了配置,就可以开始开发了(当重新构建守护进程时,可能会失去setcap功能吗?然后你就得回到你的管理员那里,“请,先生……”)
Daemon不需要担心网络的问题,只需要在stdin/stdout上进行对话
是否可以按照请求配置为以非根用户执行守护进程
代理
另一种替代方案:从特权端口到任意高编号端口(您可以在其中运行目标守护进程)的经过修改的代理(netcat或更健壮的代理)。(Netcat显然不是一个生产解决方案,但“只是我的开发盒”,对吧?)通过这种方式,您可以继续使用服务器的网络支持版本,只需要root/sudo启动代理(在引导时),而不依赖复杂/潜在的脆弱功能。