我需要允许用户(与root用户不同)运行在端口80上侦听的服务器。
有什么办法吗?
我需要允许用户(与root用户不同)运行在端口80上侦听的服务器。
有什么办法吗?
Answers:
setcap 'cap_net_bind_service=+ep' /path/to/program
这将适用于特定过程。但是要允许特定用户绑定到1024以下的端口,您必须将其添加到sudoers。
看看这个讨论更多。
(这些方法中的某些已在其他答案中提到;我会按优先顺序给出几种可能的选择。)
您可以将低端口重定向到高端口,并在高端口上侦听。
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
-A INPUT -p tcp --dport 1080 -j ACCEPT
否则它将无法正常工作(我也拥有一个-j DROP
包罗万象的东西。)因此,我剩下两个侦听套接字。
简而言之,这是设计无法实现的。
长答案是,在开源世界中,有很多人在玩设计并想出其他方法。通常,这是不可能的,这是广为接受的惯例。您尝试进行操作的事实可能意味着您的系统中存在另一个设计错误,并且应根据* nix最佳实践和安全隐患重新考虑整个系统架构。
也就是说,一个用于授权非root用户访问低端口的程序是authbind。双方的SELinux和grsecurity的也是这样的微调认证提供框架。
最后,如果您希望特定用户以root用户身份运行特定程序,而您真正需要的只是允许用户重新启动apache之类的操作,那sudo
就是您的朋友!
您可以使用netcat或xinetd或iptables端口转发,也可以使用apache作为前端代理并在非特权端口上运行该过程。
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
向上运行,直到找到可以使用的最小深度为止。
我尝试了iptables PREROUTING REDIRECT方法,但发现它也影响转发的数据包。也就是说,如果机器还在接口之间转发数据包(例如,如果它充当连接到以太网的Wi-Fi接入点),则iptables规则还将捕获已连接客户端到Internet目的地的连接,并将它们重定向到机器。那不是我想要的-我只想重定向定向到机器本身的连接。
一种可能性是使用TCP端口转发。例如使用socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
但是,该方法的一个缺点是,正在端口8080上侦听的应用程序不知道传入连接的源地址(例如,用于日志记录或其他标识目的)。