Web服务器如何知道您是否正在使用直接IP地址访问?


64

某些Web服务器在使用其IP地址进行访问时,会返回错误,指出不允许直接IP地址访问。

我一直想知道它是如何工作的。我的意思是,浏览器不是总是解析IP地址并连接到它吗?“直接IP地址访问”不只是跳过DNS吗?远程服务器如何知道您跳过了DNS?


2
我记得,他真正要求的内容很早就添加到了http协议中,以便在同一真实主机上提供虚拟服务器。
JDługosz

3
它基本上是相同的过程,允许单个服务器在不同的虚拟主机之间进行区分。真实服务器将URL映射到其虚拟主机之一。无论是设计还是默认设置,许多服务器都没有未映射URL的回退。
曼戈

您可以跳过DNS,但如果在主机文件中为相关域名创建条目,则可以避免此错误。您的浏览器将查找域名,并将其包含在Host:标头中,但是由于主机文件条目而不会进行DNS查询。
Monty Harder

这些问题的答案通常是,因为您告诉了他们
托马斯

Answers:


91

要回答有关它如何知道的问题,它与浏览器发送服务器的内容有关。

没错,系统总是将其解析为IP地址,但是浏览器会在HTTP标头中发送您尝试访问的URL。

这是我在网上找到的示例标头,经过修改后看起来就像您在Windows上使用Firefox一样,并键入apple.com了地址栏:

GET / HTTP/1.1
Host: apple.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

如果您使用标题的IP地址,则标题如下所示:

GET / HTTP/1.1
Host: 17.142.160.59
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

两者都将通过套接字发送到相同的IP地址,但是浏览器告诉服务器它访问了什么。

为什么?因为具有相同IP地址的Web服务器可能托管多个站点,并为每个站点提供不同的页面。它不能通过IP地址来区分谁想要哪个页面,因为它们都具有相同的页面-但是它可以通过HTTP标头来区分它们。


7
啊,现在变得更有意义了!因此,基本上,浏览器向IP发送带有IP或域的标头,然后站点对此进行假设。真的,这些限制很容易绕开吗?
约瑟夫·A.

7
这不是您绕过的限制,只是您没有在打球,您将获得一些奇怪的结果。
iAdjunct

这些HTTP请求是使用代理服务器时得到的。没有代理,信息将出现在host标题中。请参阅此示例
0xFE

2
bytec0de:另一个问题是,通常将基于主机名来设置Web服务器配置。IP数据包指定IP地址,TCP段指定端口号,HTTP标头指定主机名。因此,通常将服务器配置为说“如果客户端/浏览器要求example.com,则给他们。” 可以将它们设置为也响应IP地址或通配符(响应任何内容),但是许多人只是复制示例,并且许多先前存在的示例都基于浏览器提供的域名。
TOOGAM

14
@ bytec0de这不是限制。这更像是使用正确的电话号码,但使用了错误的分机号-您呼叫的是正确的建筑物,而不是正确的人。引入它的原因也与电话几乎相同-它使您可以在同一IP地址(和TCP端口)上托管多个单独的站点。例如,我们的开发服务器同时托管了数百个单独的网站,许多Web托管解决方案都使用相同的方法(“注册域,将其指向我们的IP地址,剩下的事我们会处理”) 。
a安

21

使用HTTP 1.1协议(先前的HTTP 1.0版本已经过时了一段时间,因此不太可能被任何最新版本的浏览器使用),host引入了标头。对于HTTP 1.1,这是必须由浏览器发出的必需的标题行。浏览器在该行中包含域名,例如Host: example.com。因此,Web服务器知道浏览器要从该行访问哪个网站。由于Web服务器可能支持数十个网站,因此该行对于确定请求页面所在的网站很重要。假设浏览器要访问example.com上某个网站的主页,则当连接到服务器时,它将向服务器发出以下行:

GET / HTTP/1.1

该行指定浏览器希望获取根文档,即网站的“ /”。如果您想访问/somedir/testpage.htmlGET /somedir/testpage.html将在“获取”行中。该行之后是以下行:

Host: example.com

因此,如果Web服务器支持网站example.com,someothersite.com,yetanothersite.org等,它知道它应该返回example.com的主页。如果没有得到该行,或者没有在该Host行中列出域名,则它不知道应该返回哪个网站的主页。因此,它可能返回一条错误消息,或者返回服务器的“默认”站点的主页。

您可以向浏览器使用telnet协议发出相同的命令,例如telnet example.com 80从Linux shell提示符或Apple OS X 终端窗口发出命令,以连接到默认的HTTP端口80端口- 有关步骤,请参阅使用PuTTY测试对网站的访问在Windows系统上使用PuTTY可以做到这一点。


3
请注意:HTTP 1.0也使用了host标头,但这不是必需的。HTTP 1.1将该字段设为必填字段。实际上,如果浏览器未发送主机标头(出于上述所有原因),许多HTTP 1.0服务器根本无法工作,因此大多数浏览器仍会发送它。
a安

6

这是由于Host:HTTP标头。这对于在同一IP地址上托管多个站点非常有用。例如,http://www.k7dxs.net/http://www.philipgrimes.com/都位于同一IP地址上。但是,由于有Host:标题,它们可以显示两个不同的站点。

对于HTTPS,正如@Toothbrush指出的那样,它们使用TLS服务器名称指示,因为主机标头是加密请求的一部分,并且服务器不知道没有此证书将提供哪个证书。

有趣的实验:获取Firefox的篡改数据(我无法找到适用于Chrome的等效文件)并开始篡改。打开http://slipstation.com/并将Host:请求中的标题编辑为http://www.zombo.com/。您会看到一个可能熟悉的网站,在那里一切皆有可能。


实际上,这些站点使用服务器名称指示。如果两个站点都通过不带SNI的HTTPS托管在同一服务器上,则无法确定要显示哪个站点,因为服务器不知道要使用哪个证书。
牙刷

哦,有趣。我的实验还能继续吗?
Duncan X Simpson

是的,如果您发现两个通过HTTP托管在相同IP地址上的站点。
牙刷

但是我要的不是HTTPS。
Duncan X Simpson

不,它不应该在HTTPS上运行。如果存在,则Web服务器中存在一个安全漏洞。
牙刷

5

可以将Web服务器配置为仅接受到特定域或子域的连接。它可以托管多个域。

使用直接IP地址时Web服务器的操作是可配置的。对于Apache,默认情况下,它将转到已启用站点中第一个命名的虚拟主机,该站点按字母数字排序。

经过快速搜索,这是我找到的Apache文档中最相关的部分:

https://httpd.apache.org/docs/current/vhosts/name-based.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.