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

Jos*_*eph 65 networking dns apache-http-server http ip

某些 Web 服务器在使用其 IP 地址访问时返回不允许直接 IP 地址访问的错误。

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

iAd*_*nct 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
Run Code Online (Sandbox Code Playgroud)

如果您使用其 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
Run Code Online (Sandbox Code Playgroud)

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

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

  • @bytec0de 这不是*限制*。这更像是使用了正确的电话号码,但使用了错误的分机号——您呼叫了正确的建筑物,但不是正确的人。其引入的原因也与手机几乎相同 - 它允许您在同一 IP 地址(和 TCP 端口)上托管多个单独的站点。例如,我们的开发服务器同时托管了数百个独立的网站,并且大量的网络托管解决方案使用相同的方法(“注册一个域,将其指向我们的 IP 地址,其余的我们会处理”) . (14认同)
  • 啊,现在更有意义了!因此,基本上,浏览器将带有 IP 或域的标头发送到 IP,并且站点对此做出假设。那么真的,这些限制很容易绕过吗? (7认同)
  • 这并不是说你绕过了限制,只是你没有打球,你会得到一些奇怪的结果。 (7认同)
  • bytec0de:另一部分是 Web 服务器配置通常会根据主机名进行设置。IP包指定IP地址,TCP段指定端口号,HTTP头指定主机名。所以通常服务器被配置为“如果客户端/浏览器要求 example.com,那么给他们这个”。它们也可以设置为响应 IP 地址或通配符(响应任何内容),但许多人只是复制示例,而许多预先存在的示例都是基于浏览器提供的域名。 (2认同)

moo*_*int 21

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

GET / HTTP/1.1
Run Code Online (Sandbox Code Playgroud)

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

Host: example.com
Run Code Online (Sandbox Code Playgroud)

因此,如果 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 执行此操作。

  • 请注意:主机标头也在 HTTP 1.0 中使用,只是不是*必需的*。HTTP 1.1 使该字段成为强制性的。实际上,如果浏览器不发送主机头(出于上述所有原因),许多 HTTP 1.0 服务器根本无法工作,因此大多数浏览器无论如何都会发送它。 (3认同)

Des*_*son 6

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

对于 HTTPS,正如@Toothbrush 指出的那样,他们使用 TLS 服务器名称指示,因为 Host 标头是加密请求的一部分,如果没有这个,服务器不知道要提供哪个证书。

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


par*_*oid 5

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

使用直接 IP 地址时 Web 服务器的操作是可配置的。在 Apache 的情况下,默认情况下它将转到启用站点中第一个命名的 vhost,这些站点按字母数字排序。

这是我在快速搜索后发现的 Apache 文档中最相关的部分:

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