首先需要介绍一些 SSL/TLS 的知识。当你以 https 的方式访问某个域名时,客户端(浏览器、App 等)会向服务器请求证书,这时服务器会返回与域名一样的证书验证连接 比如你访问 www.google.com,则返回 www.google.com 的证书来进行验证,验证通过之后才客户端才会继续建立加密连接

如果你访问 www.google.com ,而服务器给你返回 *.googleusercontent.com 的证书,那么只要是个客户端都不会继续建立连接了(360 这种无视证书错误的奇葩除外)。

一般来说,一个 IP 的一个端口只能使用一个证书,而网站却可以有无限多个,如果是这样的话 IP 枯竭会提前到来的(其实主要还是一般 vps 加 ip 要加钱)。聪明的人们想到了一个方法来改变现状:服务器名称指示(SNI)——在建立 SSL 握手请求时的加一个 Host 信息来标记要访问的主机名,以便服务器解析 Host 信息后返回了正确的证书,这让一个 IP 地址一个端口 得以使用 多个证书 。这也正是为什么可以在 hosts 里大量使用同一 IP 的原因。

当然,这需要服务端和客户端同时支持 SNI.如果服务器支持了 SNI 而客户端不支持 SNI,那么 以上技术均是白瞎 ,依旧只能获取到默认的证书,当证书错误时就不会继续建立 SSL 握手连接了。

以下是支持SNI的浏览器

Internet Explorer 8 及以上 (XP SP2 及以下均不支持,SP3 需安装补丁

Internet Explorer 7 及以上 (Vista或更高级的系统)

Mozilla Firefox 2.0 及以上

Opera 8.0 及以上 (the TLS 1.1 protocol must be enabled)

Google Chrome 6.0 及以上

Safari 3.0 及以上 (Mac OS X 10.5.6 以上)

Mobile Safari(iOS 4.0以上)

Android 自带的浏览器 (Android 3.0 以上)


咱们举个例子吧

原本你使用 VPN 可以在 Google Play 上下载 App,但修改 hosts 之后不但不能下 App,连预览图都无法加载了,就算再用 VPN 也无法正常工作

这是因为 Google Play 这个 App 不支持 SNI,应用预览图的地址是

lh*.googleusercontent.com

因为封锁太紧的原因,无法找到默认证书为 *.googleusercontent.com (泛域名) 的 IP,在修改 hosts 后因为证书错误的原因,应用便无法正常加载图片。

嗯,这就是 hosts 的局限性所在了,如果你只是使用 Web 服务的话,可以无视这个 Wiki,如果你需要使用各种 Google 服务的话,那么不推荐使用hosts 这种方法。

如有错误,欢迎指正。