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

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

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

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

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


当前回答

端口重定向对我们来说是最有意义的,但我们遇到了一个问题,我们的应用程序将在本地解决一个url,也需要重新路由;(意思是你在狂欢)。

这也将允许您在访问本地机器上的url时被重定向。

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

其他回答

在启动时:

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

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

2017年更新:

使用authbind

免责声明(2021年更新):请注意,authbind通过LD_PRELOAD工作,这只在你的程序使用libc时使用,如果你的程序用GO编译,或任何其他避免使用c的编译器,这是(或可能)不是情况。如果你使用GO,为受保护的端口范围设置内核参数,请参阅post底部。< / EndUpdate > Authbind比CAP_NET_BIND_SERVICE或自定义内核好得多。

CAP_NET_BIND_SERVICE授予二进制文件信任,但不提供 控制每个端口的访问。 Authbind向对象授予信任 用户/组,并提供对每个端口访问的控制 支持IPv4和IPv6 (IPv6支持已添加到后期)。

安装:apt-get Install authbind 为所有用户和组配置访问相关端口,例如80和443: 触摸/etc/authbind/byport/80 触摸/etc/authbind/byport/443 Sudo chmod 777 /etc/authbind/byport/80 Sudo chmod 777 /etc/authbind/byport/443 .使用实例 通过authbind执行命令 (可选地指定——deep或其他参数,参见man authbind): Authbind——deep /path/to/binary命令行参数 如。 authbind——deep java -jar SomeServer.jar


作为Joshua关于破解内核的绝妙建议(=不推荐,除非你知道自己在做什么)的后续:

我首先把它贴在这里。

简单。对于普通内核或旧内核,则不需要。 正如其他人指出的那样,iptables可以转发端口。 正如其他人所指出的,CAP_NET_BIND_SERVICE也可以完成这项工作。 当然,如果你从脚本启动你的程序,CAP_NET_BIND_SERVICE将会失败,除非你在shell解释器上设置了上限,这是毫无意义的,你也可以作为root运行你的服务… 例如,对于Java,你必须把它应用到Java JVM上

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

显然,这意味着任何Java程序都可以绑定系统端口。 对于mono/. net也是如此。

我也很确定xinetd不是最好的主意。 但既然这两种方法都是黑客,为什么不通过解除限制来解除限制呢? 没有人说你必须运行一个普通的内核,所以你可以运行你自己的内核。

您只需下载最新内核的源代码(或您当前拥有的相同内核)。 之后,你去:

/usr/src/linux-<version_number>/include/net/sock.h:

看这条线

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

把它改成

#define PROT_SOCK 0

如果你不想有一个不安全的SSH情况,你可以这样修改:

#define PROT_SOCK 24

通常,我会使用您需要的最低设置,例如http设置为79,在端口25上使用SMTP时设置为24。

这就够了。 编译内核,并安装它。 重新引导。 完成——这个愚蠢的限制已经消失了,这也适用于脚本。

下面是编译内核的方法:

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package `linux-source`, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

简而言之,

如果你想保持安全,使用iptables, 如果您想确保这个限制不再困扰您,请编译内核。


sysctl方法

注意: 到目前为止,不再需要更新内核。 你现在可以设置

sysctl net.ipv4.ip_unprivileged_port_start=80

还是坚持

sysctl -w net.ipv4.ip_unprivileged_port_start=80.

如果产生错误,只需用nano编辑/etc/sysctl.conf,并在那里设置参数,以便在重启期间保持不变。

或者通过procfs

echo 80 | sudo tee /proc/sys/net/ipv4/ip_unprivileged_port_start

由于OP只是开发/测试,不那么圆滑的解决方案可能会有帮助:

可以在脚本解释器上使用Setcap来为脚本授予功能。如果全局解释器二进制文件上的setcaps是不可接受的,那么就对二进制文件做一个本地副本(任何用户都可以),并在这个副本上获取root到setcap。Python2(至少)使用脚本开发树中的解释器的本地副本正常工作。不需要suid,因此根用户可以控制用户可以访问哪些功能。

如果你需要跟踪解释器的系统范围的更新,可以使用下面这样的shell脚本来运行你的脚本:

#!/bin/sh
#
#  Watch for updates to the Python2 interpreter

PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7

cmp $PRG_ORIG $PRG || {
    echo ""
    echo "***** $PRG_ORIG has been updated *****"
    echo "Run the following commands to refresh $PRG:"
    echo ""
    echo "    $ cp $PRG_ORIG $PRG"
    echo "    # setcap cap_net_raw+ep $PRG"
    echo ""
    exit
}

./$PRG $*

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

好的,感谢那些指出系统和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中添加了这个功能。