我有1台单机,IP 1.2.3.4。这台机器有2个Web服务器和一个ftp服务器:
这就是DNS映射的样子:
ws1.example.com CNAME example.com
ws2.example.com CNAME example.com
ftp.example.com CNAME example.com
example.com A 1.2.3.4
案例1:我在浏览器URL ws1.example.com:82发出请求,DNS将我重定向到example.com但使用Host标头:ws1.example.com。
案例2:我在浏览器URL ws2.example.com:83处发出请求,并且DNS将我重定向到example.com但使用主机标头:ws2.example.com。
在这两种情况下:
据我所知,主机头用于通知接收主机识别哪个服务器(来自该IP托管的多个服务器)是该请求的意图,并相应地将请求定向到适当的应用程序。
我的问题是:
首先是一个重要的术语修复:
DNS中没有“重定向”。在您的情况下,DNS仅用于将名称映射到IP。有时,由于CNAME,名称会映射到另一个名称,然后映射到IP。是否存在类似的中间步骤并不重要,最后名称映射到IP(或者DNS解析失败)
这也意味着如果URL具有特定端口,那么不会更改,将通过URL中提到的端口查询最终IP。
重定向是HTTP级别的功能:在查询网络服务器以获取https://www.mygreatsite.example/foo
时,它将使用HTTP返回代码301,302,303,307或308进行回复,并为您(HTTP客户端,即浏览器)提供要转到的新URL。
在过去的好时光,IP地址是充足的。如果您在同一个物理盒上托管www.site1.example
和www.site2.example
,则可以为每个物理盒附加一个不同的IP地址。因此,在某种特定情况下,在某种程度上,HTTP host
标头是无用的,仅仅连接到192.0.2.37
或192.0.2.42
的事实已经让你知道你想要的网站。事实上在HTTP/0.9
没有host
标题,因为根本没有标题。
但随后,随着大规模虚拟主机的发挥,以及IPv4地址变得稀缺,你不能再为每个站点附加一个IP地址,因为它也是一种浪费。因此,您通过DNS直接或间接(CNAME
记录),两个网站都解析为相同的IP。
因此,当HTTP客户端连接到服务器时,默认情况下服务器无法知道您想要哪个网站。这就是为什么客户端填写的HTTP host
标头让服务器知道您想要访问哪个网站,而不管其IP地址,这是通过DNS之前解决的。
默认情况下,HTTP使用端口80,因此在URL中通常不可见。当然如果你强迫你的客户在一边使用http://www.site1.example:4569
而在另一边使用http://www.anothersite2.com:9873
,那么你就是对了host
标头并不是真的需要。除了该计划因许多原因而失败:
因此,通常不会这样做,如果您想通过HTTP公开某些给定服务,但在非默认端口中,您通常会在其前面安装反向代理。或者你从http://www.coolpublicname.example/
到http://www.complicatedinternalname.example:9713
进行HTTP重定向,但是客户端看到了这个赤裸裸的事实。
顺便提一下,HTTPS增加了一定程度的复杂性,因为HTTPS网络服务器需要将其证书发送到客户端,但由于每个网站都有不同的证书,因此需要知道客户想要使用哪个网站,这可以通过host
HTTP标头,但随后在TLS握手完成后出现,因此在服务器发送证书的早期阶段,这还不可用。
因此,在HTTPS最早的时候,我们再次被迫做基于IP的虚拟主机,而不是基于名称的虚拟主机,因为在纯HTTP中可以使用host
标头。
找到的解决方案是TLS扩展,服务器名称指示(SNI),客户端早期发送到服务器并提供网站名称,以便服务器可以发送相应的证书,因此我们重新开始营业基于名称的情况,理论上你可以有一个无限数量的名称解析为同一个IP,由一个给定的网络服务器提供服务。