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

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

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

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

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


当前回答

您可以进行端口重定向。这就是我为运行在Linux机器上的Silverlight策略服务器所做的工作

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

其他回答

标准方法是将它们设置为“setuid”,以便它们以根用户身份启动,然后在它们绑定到端口但开始接受到该端口的连接之前丢弃根用户特权。您可以在Apache和INN的源代码中看到这样的好例子。我听说莱特特警局是另一个很好的例子。

另一个例子是Postfix,它使用多个通过管道通信的守护进程,其中只有一两个守护进程(除了接受或发出字节外几乎不做任何事情)以根身份运行,其余的守护进程以较低的权限运行。

在启动时:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

然后可以绑定到您转发的端口。

您可以进行端口重定向。这就是我为运行在Linux机器上的Silverlight策略服务器所做的工作

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

文件功能并不理想,因为它们可能在包更新后失效。

恕我直言,理想的解决方案应该是能够创建具有可继承CAP_NET_BIND_SERVICE集的shell。

这里有一个有点复杂的方法:

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

capsh实用程序可以在Debian/Ubuntu发行版的libcap2-bin包中找到。事情是这样的:

sg将生效的组ID修改为守护用户的组ID。这是必要的,因为capsh会使GID保持不变,而我们肯定不想要它。 设置位“保持UID更改的能力”。 修改UID为$DAEMONUSER 删除所有的大写(此时所有的大写仍然存在,因为——keep=1),除了可继承的cap_net_bind_service 执行命令(“——”是分隔符)

结果是一个具有指定用户和组以及cap_net_bind_service特权的进程。

例如,ejabberd启动脚本中的一行:

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"

现代Linux支持/sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0。