我有 1台单机,并且具有 IP 1.2.3.4 。这台机器有2个Web服务器和一个ftp服务器:
Web服务器1侦听端口82;它的域: ws1.example.com
Web服务器2侦听端口83;它的域: ws2.example.com
FTP Server侦听端口21;它的域: ftp.example.com
这是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 ,但带有 Host 标头: ws2.example.com 。
在两种情况下:
请求最终到达同一台物理计算机
请求到达时:
在情况1中,请求到达此计算机,并且正在通过端口82侦听的应用程序(即Web服务器1)来处理请求。
在情况2中,请求到达此计算机,并且正在侦听端口83(即Web服务器2)的应用程序处理请求。
Host 标头用于通知接收主机以标识哪个服务器(从该 IP 已托管的多个服务器中)请求用于并相应地将请求定向到适当的应用程序。
我的问题是:
在此示例中, Host 标头的目的是因为具有相同IP的同一台物理计算机具有多个应用程序在其相应的端口进行侦听。一旦请求到达此计算机,无论如何,适当的端口将被占用,其他应用程序将忽略该请求,因为该端口与该请求不匹配。那么,当适当的端口正常工作时, Host 标头在这里发挥什么作用呢?
我可以推断出
仅当您使用反向代理之类的东西时才有意义。 1台计算机与客户端进行交互,并将用户请求重定向到位于不同计算机上的相应Web服务器,这些服务器均在同一端口上进行侦听,例如80,在反向代理后面的网络中,您拥有 ws1.example.com 和 ws2.exmple.com 都被重定向到反向代理 example.com ,现在该反向代理根据 Host 将其转发到适当的主机标头?
答案 0 :(得分:0)
首先重要的术语修复:
DNS中没有“重定向”。在您的情况下,DNS仅用于将名称映射到IP。有时,由于CNAME,一个名称会映射到另一个名称,然后再映射到IP。不管是否有类似的中间步骤,最后一个名称都映射到IP(或者DNS解析失败)
这也意味着,如果URL具有特定端口,则该端口不会更改,则将通过URL中提到的端口查询最终IP。
重定向是HTTP级别的功能:在向网络服务器查询https://www.mygreatsite.example/foo
时,它将以HTTP返回码301、302、303、307或308进行回复,并为您提供(HTTP客户端,又名浏览器)新的网址。
在过去的好日子里,IP地址很多。如果您将www.site1.example
和www.site2.example
托管在同一个物理设备上,则可以为每个IP地址附加一个不同 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 Web服务器需要将其证书发送给客户端,但是由于每个网站都可以具有不同的证书,因此它需要知道客户端要使用哪个网站,可以使用哪个网站。通过host
HTTP标头进行学习,但是在TLS握手完成之后才进行学习,因此在服务器发送证书的早期阶段,此功能尚不可用。
因此,在HTTPS最早的时候,由于host
标头,我们不得不再次进行基于IP的虚拟托管,而不是基于名称的虚拟托管,就像在纯HTTP中一样。
找到了带有TLS扩展名,服务器名称指示(SNI)的解决方案,客户端将其早期发送到服务器并提供了网站名称,以便服务器可以发送适当的证书,因此我们回来了在基于名称的业务中,理论上您可以将无数个名称解析为相同的IP,以便由一个给定的Web服务器为其提供服务。