允许用户监听低于1024的端口


63

我需要允许用户(与root用户不同)运行在端口80上侦听的服务器。

有什么办法吗?


1
这个问题是可以解释的。我希望您的意思是“您已经创建了一个新的系统服务,出于安全原因,您(作为根用户)希望在无特权的帐户中运行”(被认为是良好的做法),而不是“我有一个询问用户是否可以在我的系统上运行他们自己的Web服务器,如何允许他们访问?” (被认为是相当糟糕的做法)
Michael Shaw

3
@Ptolemy,实际原因是:我的机器位于防火墙之外,该防火墙阻止了除80端口之外的任何端口。我想托管一台服务器(不放弃特权!),因此需要使其监听80端口,但不要不信任它以root身份运行(出于明显的安全原因)。如果您愿意,我可以这样做。
peoro 2011年

Answers:


50

setcap 'cap_net_bind_service=+ep' /path/to/program

这将适用于特定过程。但是要允许特定用户绑定到1024以下的端口,您必须将其添加到sudoers。

看看这个讨论更多。


31

(这些方法中的某些已在其他答案中提到;我会按优先顺序给出几种可能的选择。)

您可以将低端口重定向到高端口,并在高端口上侦听。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

您可以在特权端口上开始侦听服务器后,以root用户和特权删除服务器。最好不要自己编写代码,而是从为您完成工作的包装器启动服务器。如果您的服务器为每个连接启动一个实例,请从inetd(或类似的程序xinetd)启动它。对于inetd,请在以下代码中使用以下行/etc/inetd.conf

http  stream  tcp  nowait  username:groupname  /path/to/server/executable  argv[0] argv[1]…

如果您的服务器侦听单个实例,请从诸如之类的程序启动它authbind。创建一个空文件/etc/authbind/byport/80并使它对运行服务器的用户可执行;或create /etc/authbind/byuid/1234,其中1234是运行服务器的UID,其中包含line 0.0.0.0/0:80,80

如果您的服务器可执行文件存储在支持功能的文件系统上,则可以为其提供功能。请注意,功能仍然相对较新,并且仍然存在一些缺陷cap_net_bind_service

setcap cap_net_bind_service=ep /path/to/server/executable

4
在我不得不处理的每种情况下,可执行文件都是启动Java或python的脚本。作为一个没有10个小时花在精要点上的人,您的iptables解决方案可以轻松解决这一问题。
2012年

对于iptables解决方案,我还必须添加一个过滤器规则,-A INPUT -p tcp --dport 1080 -j ACCEPT否则它将无法正常工作(我也拥有一个-j DROP包罗万象的东西。)因此,我剩下两个侦听套接字。
thom_nic

4

简而言之,这是设计无法实现的。

长答案是,在开源世界中,有很多人在玩设计并想出其他方法。通常,这是不可能的,这是广为接受的惯例。您尝试进行操作的事实可能意味着您的系统中存在另一个设计错误,并且应根据* nix最佳实践和安全隐患重新考虑整个系统架构。

也就是说,一个用于授权非root用户访问低端口的程序是authbind。双方的SELinuxgrsecurity的也是这样的微调认证提供框架。

最后,如果您希望特定用户以root用户身份运行特定程序,而您真正需要的只是允许用户重新启动apache之类的操作,那sudo就是您的朋友!


8
在现代世界中,“安全性”港口并不能真正给您带来太多好处。
pjc50 2011年

3
@ pjc50:是的。这与隐含的信任有关。端口号低意味着信任度高。SSH,POP,FTP和其他守护程序在打开端口时要求输入系统级密码和其他凭据。如果允许用户在盒子的低端端口上监听,他们可以在未使用的(或崩溃的)端口上启动虚拟后台驻留程序,并从毫无戒心的用户那里获取密码。然后可以在该框中使用这些密码来破坏其他帐户,包括root。
Caleb

8
那是一种非常薄弱的​​安全形式。如果您已连接到某物并且未完成证书交易,那么您将不知道与谁谈话(即MITM攻击)。
pjc50 2011年

5
我想需要对端口进行chown:然后您可以“ chown mail port25”,然后(a)您的邮件守护进程不需要以root privs启动,并且(b)没有其他人可以劫持它。
pjc50 2011年

7
尽管在Linux刚起步时这可能是“设计使然”,但从现在到现在都没有多大意义。安全就是用户可以做什么和不能做什么。例如,仅允许root用户使用端口80是巨大的安全风险,因为这意味着您必须将root用户权限授予需要使用port 80但不应具有root用户访问权限的人员。如果您信任非root用户X使用端口80,则应该能够在您的OS中对该信任进行编码。幸运的是,就像您提到的那样,有一些糟糕的解决方法可以做到这一点,例如authbind。
英国电信


3

Authbind,@Gilles已经提到了它,但是我想对其进行扩展。

它具有方便的访问控制(手册页中的详细信息):您可以按端口,接口地址,uid,地址或端口范围以及它们的组合来过滤访问。

它具有非常有用的参数--depth

-深度级别

使authbind影响在调用图中较深级别的程序。预设值为1。

“深层次”是指当脚本(或程序)运行另一个脚本时,它会下降一个层次。因此,如果您拥有--depth 5它,则意味着在1级(或0?)到5级之间具有绑定的权限,而在6级及更高级别则没有绑定的权限。当您希望脚本具有访问权限,而在您不知不觉中运行脚本时,该功能很有用。


为了说明这一点,您可能会遇到类似这样的情况:为了安全起见,您有一个java只打算运行Java 的用户,并且想让他访问端口80:

echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80

我已经创建了../byport/80 file,并将其分配给java用户组(每个用户都有它自己的组),并使其可以按组执行,这意味着它可以按java用户执行。如果要通过端口授予访问权限,则该文件必须由具有访问权限的用户可执行,因此我们做到了。

对于普通的Joe来说,这可能就足够了,但是因为您知道如何使用该--depth参数,所以您(以java用户身份)authbind --depth [depth] my_web_app's_start_script开始运行并逐步--depth 1向上运行,直到找到可以使用的最小深度为止。

阅读手册页以获取详细信息


1

我尝试了iptables PREROUTING REDIRECT方法,但发现它也影响转发的数据包。也就是说,如果机器还在接口之间转发数据包(例如,如果它充当连接到以太网的Wi-Fi接入点),则iptables规则还将捕获已连接客户端到Internet目的地的连接,并将它们重定向到机器。那不是我想要的-我只想重定向定向到机器本身的连接。

一种可能性是使用TCP端口转发。例如使用socat

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

但是,该方法的一个缺点是,正在端口8080上侦听的应用程序不知道传入连接的源地址(例如,用于日志记录或其他标识目的)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.