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

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

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

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

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


当前回答

2015年9月:

ip6tables现在支持IPV6 NAT: http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt

您将需要内核3.7+

证明:

[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:80 redir ports 8080
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:443 redir ports 1443

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

其他回答

在启动时:

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

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

另外两种简单的可能性:Daemon和Proxy

守护进程

对于“一个绑定在低端口上的守护进程并将控制权交给您的守护进程”,有一个旧的(不流行的)解决方案。它被称为inetd(或xinetd)。

缺点是:

你的守护进程需要在stdin/stdout上对话(如果你不控制守护进程——如果你没有源代码——那么这可能是一个showstopper,尽管一些服务可能有inetd兼容性标志) 每个连接都会生成一个新的守护进程 这是链条上的一环

优点:

可以在任何旧的UNIX上使用 一旦系统管理员设置了配置,就可以开始开发了(当重新构建守护进程时,可能会失去setcap功能吗?然后你就得回到你的管理员那里,“请,先生……”) Daemon不需要担心网络的问题,只需要在stdin/stdout上进行对话 是否可以按照请求配置为以非根用户执行守护进程

代理

另一种替代方案:从特权端口到任意高编号端口(您可以在其中运行目标守护进程)的经过修改的代理(netcat或更健壮的代理)。(Netcat显然不是一个生产解决方案,但“只是我的开发盒”,对吧?)通过这种方式,您可以继续使用服务器的网络支持版本,只需要root/sudo启动代理(在引导时),而不依赖复杂/潜在的脆弱功能。

我的“标准解决方案”使用socat作为用户空间重定向器:

socat tcp6-listen:80,fork tcp6:8080

注意,这不会扩展,分叉是昂贵的,但这是socat工作的方式。

将8080端口绑定为80端口,开放80端口:

sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

然后以普通用户身份在8080端口上运行程序。

然后,您将能够在端口80上访问http://127.0.0.1

Systemd是一个sysvinit的替代品,它有一个选项来启动具有特定功能的守护进程。Options Capabilities=, CapabilityBoundingSet= in system .exec(5) manpage。