虽然 80 和 443 是系统端口,但是大多数 Web 服务器如何能够绑定到它们呢?

虽然 80 和 443 是系统端口,但是大多数 Web 服务器如何能够绑定到它们呢?

运行绑定到端口 80 的 Web 服务通常不需要 sudoer 权限。由于端口 80/443 是系统端口,这意味着它们只能由特权用户使用,那么这些服务如何仍然能够绑定到这些端口呢?

答案1

基本上有两种不同的方法:

  1. 最初以 root 身份运行,绑定到特权端口,然后降为非特权用户。

  2. inetd 或 xinetd 以特权运行,并将请求转发到以非特权运行的 Web 服务器。

答案2

由于端口 80/443 是系统端口,这意味着它们只能由特权用户使用

我认为你错了。任何人都可以使用这些端口。捆绑对他们来说这是一项特权操作。

这里的理由是,某些用户 Joe 不应该能够编写恶意 Web 服务器,然后创建一些他没有任何管理权限的主机。当然,这是一个相当薄弱的模型,通常没有什么可以阻止 Joe 将自己的计算机放在网络上,并且他可以对他有物理访问权限的任何机器拥有管理权限。

我将用 netcat 做一个演示。

作为普通用户,我无法绑定到80端口:

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

我可以绑定到端口 8080:

$ nc -l -p 8080

同时在另一个终端,我可以连接到端口 80 并发送一些数据,并看到它出现在我刚刚启动的服务器端:

$ nc 127.0.0.1 8080 <<<"Hello world"

如果我想绑定到端口 80,我需要成为 root :

$ sudo nc -l -p 80

或者我可以将CAP_NET_BIND_SERVICE功能分配给nc二进制文件:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

另一种选择是编写服务器程序,使其在调用后listen()放弃 root 权限。这是一种非常常见的解决方案,您会在大多数守护进程中看到它。例如,Apache 从 init 以 root 身份启动,然后在绑定到端口www-data80 后放弃 root 权限并成为用户或类似角色。尝试/etc/init.d/apache start以非 root 身份运行,Apache 可能会启动失败。

相关内容