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

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

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

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

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


当前回答

使用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

其他回答

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

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

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

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

使用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

还有一种“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