某些Web服务器在使用其IP地址进行访问时,会返回错误,指出不允许直接IP地址访问。
我一直想知道它是如何工作的。我的意思是,浏览器不是总是解析IP地址并连接到它吗?“直接IP地址访问”不只是跳过DNS吗?远程服务器如何知道您跳过了DNS?
某些Web服务器在使用其IP地址进行访问时,会返回错误,指出不允许直接IP地址访问。
我一直想知道它是如何工作的。我的意思是,浏览器不是总是解析IP地址并连接到它吗?“直接IP地址访问”不只是跳过DNS吗?远程服务器如何知道您跳过了DNS?
Answers:
要回答有关它如何知道的问题,它与浏览器发送服务器的内容有关。
没错,系统总是将其解析为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标头来区分它们。
使用HTTP 1.1协议(先前的HTTP 1.0版本已经过时了一段时间,因此不太可能被任何最新版本的浏览器使用),host
引入了标头。对于HTTP 1.1,这是必须由浏览器发出的必需的标题行。浏览器在该行中包含域名,例如Host: example.com
。因此,Web服务器知道浏览器要从该行访问哪个网站。由于Web服务器可能支持数十个网站,因此该行对于确定请求页面所在的网站很重要。假设浏览器要访问example.com上某个网站的主页,则当连接到服务器时,它将向服务器发出以下行:
GET / HTTP/1.1
该行指定浏览器希望获取根文档,即网站的“ /”。如果您想访问/somedir/testpage.html
,GET /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可以做到这一点。
这是由于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/。您会看到一个可能熟悉的网站,在那里一切皆有可能。
可以将Web服务器配置为仅接受到特定域或子域的连接。它可以托管多个域。
使用直接IP地址时Web服务器的操作是可配置的。对于Apache,默认情况下,它将转到已启用站点中第一个命名的虚拟主机,该站点按字母数字排序。
经过快速搜索,这是我找到的Apache文档中最相关的部分:
https://httpd.apache.org/docs/current/vhosts/name-based.html