为啥使用 ping 到的 IP 不能访问知乎的网站,而百度就可以

大型网站依靠自身稀稀落落的服务器很难满足网页“秒开”的用户需求,会加入CDN加速的队伍。

当用户访问http://www.zhihu.com时,域名解析到距离用户最近的CDN服务器的公网IP,浏览器于是与公网IP对应的CDN服务器建立连接。

问题来了,CDN服务器一个公网IP,可能hosted多个客户网站(a.com,b.com,http://c.com)。
当浏览器主动连接时,CDN服务器如何知道是连接哪个客户网站呢?

SNI
Server Name Indication,那么用户浏览器只要填入:

SNI = “www.zhihu.com”

CDN服务器可以根据SNI的值知晓,浏览器原来想连接的网站,完成TLS安全连接,并把资源返回浏览器。

裸IP地址访问
用户突然不使用域名,而是直接使用IP地址访问了,这让CDN服务器有点茫然失措。

为啥使用 ping 到的 IP 不能访问知乎的网站,而百度就可以



SNI = “54.223.189.245”

SNI已经无法帮助CDN服务器,分辨用户到底是想访问哪个网站了。

与其返回错误的资源,还不如拒绝服务。

直接使用IP=111.13.101.208为何可以访问http://baidu.com?

计算机通信里,如果一个地址或端口会引起歧义或冲突,是需要坚决避免的。

反过来说,如果一个地址不会引起歧义,可以放心大胆使用。

如果IP=111.13.101.208对应的就是http://baidu.com 网站服务器,或专用CDN服务器(只服务http://baidu.com),即使使用IP访问有何不可呢?



■网友
因为网页服务器配置不一样咯。你的 URL 中的 host 部分是什么,HTTP 请求头部的 host 属性值就是什么。你用 http://baidu.com,浏览器请求时头部带上的就是 host: http://baidu.com。换成 IP,请求头部跟着变。
为什么 HTTP 协议要有 host 属性呢?因为这样做能服用同一个 IP 和端口,使得同一个 IP 和端口能够服务于多个网站。 IP 和端口两者确定一个 TCP 通信对象,这是 TCP 层的限制,不可能在 TCP 层发生改变。HTTP 在 TCP 上面,所以可以通过引入 host 属性来区分同一 IP 和端口的多个网站。
一台网页服务器,在 TCP 层必须绑定一个 IP 和端口,绑定后就可以在上层配置不同 host 对应不同网站。至于当 host 为 IP 时是否对应到某个网站,这纯粹是看配置怎么做。
百度配置到 IP 能访问,因为人家喜欢,很可能还因为人家有能耐这样做。在中国的互联网监管下,理论上域名才能备案,备案了才能开通访问,一个 IP 不能裸着开放访问。如果服务器放在一般数据中心机房,一旦一台服务器敢对未备案的域名作出正常响应,数据中心是要立即调查甚至拔线的。百度当然有自己的机房,没必要如此自己监管自己,所以爱怎样就怎样吧。
别的答案有提到 SNI,这其实是不正确的。因为返回 405 状态吗是 HTTP 这一层负责的,而 SNI 是 HTTPS 的事情。(SNI 是 TLS 的一个扩展。)SNI 解决的问题是,如果同一个 IP 和端口上的多个网站使用不同的 HTTPS 证书,那 HTTPS 加密通讯握手阶段用哪个证书跟你握手。大多数网站都不会为自己的 IP 申请一份证书,所以如果用 HTTPS 加上 IP 访问,你首先看到的是证书错误,浏览器建议你不要访问这个网站。
别的答案还有提到 CDN,这其实也不完全正确,当然 CDN 的定义也非绝对严格,所以没办法说绝对的对错。一般来说,CDN 做的事情只是缓存静态内容,而不提供生成动态内容的计算能力。百度和都是提供动态内容的,都需要网页服务器来提供服务。在这之上,可以做 GeoDNS 优化,意思是同一个域名在不同的地区会被 DNS 指向不同 IP。例如说,很久以前南电信北网通之间的速度很慢,所以百度使用北京机房服务网通用户、深圳机房服务电信用户,这时候百度域名在不同地区会指向不同 IP。


推荐阅读