为什么需要 sudo 在给定的 ip:port 上启动网络服务器?

Beg*_*e00 9 networking linux sudo

我正在我的 Debian 机器上设置一个基于 Python 的网络服务器。

设置:

  • Debian 操作系统是基于 VM 的,但我已将 VirtualBox 从 NAT 切换到桥接。
  • VM 设置的 IP = 192.168.1.7(根据我路由器的管理屏幕或ifconfig)。
  • 我已经成功地为 ssh 和 HTTP 设置了路由器的端口转发。
  • 我已经使用 dyndns.com 成功设置了路由器的动态 dns。

无论我使用的是什么特定的 Python 网络服务器(Django、CherryPy、标准库),我都必须使用sudo. 否则,我会收到关于无权访问该端口的错误。没有任何网络服务器教程提到sudo在指定 ip:port 时需要使用。

问题:为什么我需要使用sudo来启动这些网络服务器?这是否表明我不应该使用192.168.1.7?或者我没有在某处正确设置配置文件?

Sky*_*eam 14

不允许非特权用户绑定到特权端口(端口号低于 1024)是标准行为。因此,例如,想要绑定到端口 80 的应用程序必须以特权运行(通常这意味着以 root 身份运行)才能绑定到此端口。

一种常见的方法是使用特权用户运行一个小的“侦听器”进程,该进程接受连接,然后生成一个非特权进程来处理请求。出于安全原因,删除请求处理的权限。如果有人能够利用处理请求的进程,那么通常它允许入侵者使用与处理进程相同的特权来执行命令。因此,使用特权进程处理整个请求是不好的。

然而,对于许多应用程序来说,现在以非 root 身份运行是很常见的。但是这样的进程当然不能绑定到标准配置中的特权端口。因此,Tomcat 或 JBoss 等服务器过去常常绑定到 8080 等高端口,因此它们不需要特权侦听器。

当然,如果您将这样的进程暴露给 Internet,您可能会提供对端口 80 的访问,因为当使用 HTTP 协议时,每个浏览器都会首先尝试连接到端口 80。提供此功能的常见解决方法是在应用程序和公共 Internet 之间使用防火墙或端口转换器。所以请求到达防火墙请求端口 80,但防火墙将请求转发到端口 8080 上的某个内部主机。 这样,真正的 Web 服务器可以在高端口上运行,同时在端口 80 上公开可用。

- (internet request) ----> (port 80)[Firewall] ------> (port 8080)[Webserver]
Run Code Online (Sandbox Code Playgroud)

有时这种重定向只是使用iptablesNAT 规则完成的:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Run Code Online (Sandbox Code Playgroud)

这允许运行在端口 8080 上侦听的非特权应用程序,而对端口 80 的所有传入请求仅重定向到端口 8080。

然而,使用现代 Linux 内核还有另一种可能性:使用功能。

setcap CAP_NET_BIND_SERVICE=+ep /some/webserver/binary
Run Code Online (Sandbox Code Playgroud)

binary即使从非 root 用户启动,这也允许绑定到特权端口。有关man capabilities更多详细信息,请参阅。


Šim*_*óth 12

只有具有 root 权限的进程才能侦听特权端口。这是标准的 Unix 安全约定。

  • 不幸的是,对于现代 Unix 系统,这种说法并不完全正确。有关详细信息,请参阅我的答案,但例如现代 Linux 允许使用 CAPABILITIES 进行更细粒度的权限控制。Solaris 还具有称为 RBAC 的细粒度安全系统。这些机制允许将诸如绑定特权端口之类的权限分配给特定用户或程序。 (2认同)