在 Wireshark 中查看我的网络适配器的 DNS 和 SNI,我看到的只有域名和子域名,但斜杠后面什么都没有,就像没有提到example.com/page
或twitter.com/mypage
所以,我想知道,应用程序或浏览器如何知道在斜杠后要访问哪个页面?
浏览器或应用程序是否只需要知道/查询主域或子域的 IP 地址,然后在其后面添加斜线?例如192.168.1.1/mypage
Twitter 的情况?
我认为这是可行的,但如果斜线后的地址有不同的 IP 地址怎么办?例如,Twitter.com
位于192.168.1.1
但Twitter.com/mypage
位于192.168.2.1
?这样做是主流吗?
最后但也是最重要的一点,如果 DNS 请求/响应和 TLS SNI 字段仅包含网站的子域和主域,这是否意味着例如我的 ISP 不会确切知道我访问了哪些 Twitter 或 Instagram 页面,并且只能看到我访问 Twitter.com 和 Instagram.com,只要连接是 HTTPS?
PS 请考虑在端口 53 上仅使用纯文本 DNS,根本不使用像 DoH 或 DoT 这样的安全 DNS。
更新: 阅读所选答案下的评论在此 Server Fault 帖子上回答了我的第一个问题。
答案1
在处理 http(s) 请求时,DNS 所做的只是将域名转换为 IP 地址。然后,Web 浏览器连接到该 IP 地址并请求资源(例如斜线后的部分)——不涉及 DNS。
您认为 twitter.com 位于 192.168.1.1,而 twitter.com/mypage 位于 192.168.2.1,这种说法是错误的。从 Web 客户端的角度来看,twitter.com 和 twitter.com/mypage 都位于同一个 IP 地址上。twitter.com 上的服务器可以充当反向代理并从 192.168.2.1 获取最终数据,但它将通过浏览器和 192.168.1.1 之间建立的安全连接路由请求。
DNS 和 SNI 几乎不相关。SNI 由 Web 服务器协商,与 DNS 无关(暂时忽略 CAA 记录等,它们与 DNS 有关但与 SNI 无关,并且并非无处不在)。事实上,拿一个网站,将其移动到另一台服务器上的另一个 IP 地址 - 但请确保您也移植了证书,修改您的主机文件以指向新的 IP 地址,即使您已覆盖 DNS,您的 HTTPS 站点仍将正常运行。
答案2
补充其他答案:这里是对 URL 的快速剖析:
https://www.example.com:99/some/path?a=b&c=d#1223
https://
- 协议又称浏览器用来与网络服务器对话的“语言”。www.example.com:99
- 地址,进一步分为两部分:www.example.com
- 主机名,又称“域名”。浏览器会在连接前将其转换为 IP 地址:99
- 浏览器将用于建立网络连接的 TCP 端口号。此部分通常会被省略,然后浏览器将使用所选协议的默认端口号(80
对于http
;443
对于https
)
/some/path
以及?a=b&c=d
“资源路径”和“查询字符串”。浏览器在建立连接后将所有这些一起发送到服务器(对于包含所有 TLS 协商的 HTTPS,因此会以加密方式发送)。浏览器不会修改此文本,只需确保它不包含非法字符即可。它实际上可以是任何内容,只是约定俗成,第一部分是“资源”的路径,第二部分是某种参数。实际上,您可以发送几乎任何内容,服务器可以随意处理它。#1223
- 这被称为“片段”,浏览器根本不会将其发送到服务器。这 100% 供客户端使用。例如,如果 URL 导致 HTML 页面,浏览器将尝试查找具有此 ID 的 HTML 元素并滚动到它。它也可以通过浏览器中运行的 Javascript 访问(然后可以对其进行任何操作)。但它永远不会被发送到任何地方。
因此,如您所见,在 DNS 系统中查找的确实只是域部分。并且您不能根据路径使用不同的 IP 地址。
答案3
如果斜线后的地址有不同的 IP 地址怎么办?
它实际上永远不会有不同的 IP 地址。HTTP URL 语法无法实现这一点;它定义了仅有的斜线部分是“权威”(要连接的服务器域名或 IP 地址)——同一个服务器始终负责其域下的所有 HTTP 路径。
(实际的服务器可以按照自己喜欢的任何方式处理不同路径的 HTTP 请求,例如,它可以在本地提供某些路径,同时将其他路径代理到不同的后端主机,但这些都是客户端不可见的服务器端逻辑。)
答案4
所以,我想知道,应用程序或浏览器如何知道在斜杠后要访问哪个页面?
浏览器发送小路和询问信息发送给从域名找到地址的服务器。服务器决定它希望返回什么。
当你要求浏览器(或其他用户代理)检索时http://www.example.com/foo/bar?a=1&b=2#baz
,它会将该 URL 分解为标准指定的组件URL 语法并执行以下操作:
确定从方案部分,,
http:
它是使用HTTP协议。确定
//
紧接着发生的事情将是权威,在本例中,它只是一个服务器名称:www.example.com
。然后它将通过 DNS 查找服务器名称以获取其 IP 地址。如果您的过滤器允许,您应该会在 Wireshark 跟踪中看到此 DNS 请求和响应。由于机构没有指定端口,浏览器将采用默认端口
80
,就像您输入了一样http://www.example.com:80/foo/bar
。然后它将连接到该主机和 TCP 端口上的服务器并发送小路和询问字符串作为 HTTP 请求的一部分。这些将在请求行启动请求:
GET /foo/bar?a=1&b=2 HTTP/1.0
。(请注意,它确实不是发送片段。)如果您在 Wireshark 中检查 HTTP 请求的内容,您将看到这一点。服务器将按照其意愿解释请求并返回某种结果。
如果返回的结果是 HTTP 文档,则浏览器将查找具有
id="baz"
属性的元素(即与上面指定的片段匹配)并滚动到它。
在这个过程中,实际上还有一些微妙之处;为了简单起见,我故意省略了对其他方案、其他部分的提及。HTTP 请求超过请求行(例如 HTTP 标头)、有关 HTTP 响应格式的任何详细信息,以及当响应不是 HTML 文档时浏览器可能对片段执行的操作。
最后但也是最重要的一点,如果 DNS 请求/响应和 TLS SNI 字段仅包含网站的子域和主域,这是否意味着例如我的 ISP 不会确切知道我访问了哪些 Twitter 或 Instagram 页面,并且只能看到我访问 Twitter.com 和 Instagram.com,只要连接是 HTTPS?
这是正确的,只要你没有在浏览器中安装任何允许代理或透明代理通过解密和重新加密来代理 HTTPS 连接。
事实上,对于任何给定的 HTTPS 请求(或它们认为是 HTTPS 请求,因为它会转到端口 443 并使用 TLS),他们所能看到的只是你连接的 IP 地址,在某些情况下,这可能是一个托管许多不同网站的系统(特别是如果它是内容分发网络 (CDN)端点)。也就是说,他们通常也会看到您的 DNS 请求,这些请求是明文的,因此他们肯定能猜到,如果您在 example.com 上查找到 192.168.1.1,然后很快连接到 192.168.1.1 上的端口 443,那么您连接的就是 example.com,而不是可能从该地址提供服务的其他站点。