服务器如何知道使用了哪个域名?

How does a server know which domain name was used?

据我所知,我们从 dns 查询中得到的是一个 ip 地址。所以归根结底,如果那是真的,我们仍在使用 IP 地址连接服务器,并且域是它们的漂亮名称。

那么服务器如何知道我使用哪个域查询该 ip 地址? 虚拟主机如何工作并了解在 dns 查询期间是否丢失了域数据?

The Internet works in layers。每层使用不同类型的参数来完成其工作。

第 3 层通常是 IP 又名互联网协议。为了工作,它使用 IP 地址,每台计算机至少有一个能够与另一台讨论。实际上有两个系列:版本 4 和版本 6。

由于在某个时候任何给定的计算机上都可以有多个服务,因此您需要在其之上添加一个层,即第 4 层来处理传输。 “主要”是 TCP 又名传输控制协议,但也有 UDP。 TCP 和 UDP 使用端口:为特定协议编码的 2 字节整数。

例如,HTTP 的端口号为 80(完全任意),HTTPS 的端口号为 443。

DNS 本身使用 UDP 和 TCP(在端口 53 上),除其他外,它允许将给定的主机名映射到给定的 IP 地址或多个 IP 地址。这是典型的 AAAAA 记录。还有一个 CNAME 记录将一个域名映射到另一个。还有一个 SRV 记录将服务(协议名称 + 传输)映射到给定的主机名和端口号。

当一台计算机连接到另一台计算机时,执行上述所有操作的第一步是找出用于连接的 IP 地址。它可以为此使用 DNS。通常它只会获得 IP 地址,但是,取决于协议(第 4 层以上),也可能获得端口(如果使用 SRV 记录)。

HTTP 世界不使用 SRV 记录。所以浏览器只使用硬编码的 80 或 443 端口,或者 URL.

中出现的端口号

然后我们在传输层,让我们说 TCP。 连接完成(因为现在远程 IP 地址和端口已知)并且 TCP 之上的协议,如 HTTP,可以自由传送任何类型的额外数据,例如客户端最初使用的主机名(取自 URL) 找出IP地址。 这是通过 HTTP host header 完成的,参见 RFC 2616

请注意,如果您通过 TLS(概念上位于 TCP 和 HTTP 之间)执行操作,甚至还会发生其他事情:SNI 或服务器名称指示。

进行 TLS 握手时,在任何类型的 HTTP header 或内容之前,客户端将发送某些特定 TLS 消息中所需的最终主机名。为什么?这样服务器就可以找到它应该回答哪个特定证书,否则它将无法知道请求哪个主机名,因为它位于某些 HTTP header 中,在 TLS 握手完成之前不存在。

网络服务器将能够看到 SNI 内容以找出要发回的证书,然后 host header 以找出哪个 VirtualHost(在 Apache 中)部分与正在处理的查询相关。

如果您不在 HTTP 世界中,那么这完全取决于所使用的协议。较旧的协议,如 FTP,一开始并没有计划“多宿主”,例如,给定的 IP 地址仅意味着一个主机名和服务。