我正在我的 Debian 机器上设置一个基于 Python 的网络服务器。
设置:
- Debian 操作系统是基于 VM 的,但我已将 VirtualBox 从 NAT 切换到 Bridged。
- VM 设置的 IP =
192.168.1.7
(根据我的路由器的管理屏幕或ifconfig
)。 - 我已成功设置了路由器的 ssh 和 HTTP 端口转发。
- 我已成功使用 dyndns.com 设置了我的路由器的动态 DNS。
无论我使用的是哪种特定的 Python 网络服务器(Django、CherryPy、标准库),我都必须使用 启动网络服务器 @ 192.168.1.7:80 。否则,我会收到一条错误消息,提示我无权访问端口。所有网络服务器教程均未提及在指定 ip:port 时sudo
需要使用。sudo
问题:为什么我需要使用sudo
来启动这些 Web 服务器?这是否表明我不应该使用192.168.1.7
?或者我没有在某处正确设置配置文件?
答案1
只有具有 root 权限的进程才能侦听特权端口。这是标准的 Unix 安全约定。
答案2
标准行为是非特权用户不得绑定到特权端口(端口号低于 1024)。因此,例如,想要绑定到端口 80 的应用程序必须以特权身份运行(通常这意味着以 root 身份运行)才能绑定到此端口。
一种常见的方法是运行一个小型的“监听器”进程,该进程具有特权用户,接受连接,然后生成一个非特权进程来处理请求。放弃请求处理的特权是出于安全原因。如果有人能够利用处理请求的进程,那么通常它允许入侵者使用与处理进程相同的特权执行命令。因此,使用特权进程处理整个请求是不好的。
然而,如今许多应用程序通常以非 root 身份运行;但此类进程当然无法在标准配置中绑定到特权端口。因此,Tomcat 或 JBoss 等服务器过去常常绑定到 8080 等高端口,这样它们就不需要特权侦听器了。
当然,如果您将这样的过程暴露给互联网,您可能会提供端口 80 上的访问权限,因为使用 HTTP 协议时,每个浏览器都会首先尝试连接到端口 80。提供此功能的常见解决方法是在应用程序和公共互联网之间使用防火墙或端口转换器。因此,请求到达防火墙并请求端口 80,但防火墙会将请求转发到端口 8080 上的某个内部主机。这样,真正的 Web 服务器就可以在高端口上运行,同时在端口 80 上公开可用。
- (internet request) ----> (port 80)[Firewall] ------> (port 8080)[Webserver]
有时,此重定向只需使用 NAT 规则即可完成iptables
:
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
这允许运行在端口 8080 上监听的非特权应用程序,同时所有对端口 80 的传入请求都被重定向到端口 8080。
但是使用现代 Linux 内核还有另一种可能性:使用功能。
setcap CAP_NET_BIND_SERVICE=+ep /some/webserver/binary
这将允许binary
即使以非 root 用户身份启动也能绑定到特权端口。请参阅man capabilities
以了解更多详细信息。