最近开始所有语言版本的维基百科都已被屏蔽。 之前,仅限于维基百科的中文版(zh.wikipedia.org),但现在已经扩展到了所有语言 *.wikipedia.org
的版本。
我们将在本文分享 OONI 对于中国封锁维基百科的网络测量数据。 我们发现所有 wikipedia.org 的子域名在中国都被通过 DNS 注入和 SNI 过滤的方式封锁了。
DNS 注入
通过使用 OONI Probe,自 2015 年以来,我们已经在中国的多个地区对维基百科域名进行了 测试。大多数测试数据都是从中国电信(AS4134)收集的。
OONI 的 Web 连通性测试(在 OONI Probe 应用程序中提供)旨在测量基于 TCP/IP,HTTP 和 DNS 的对网站的封锁。 通过此测试收集的网络测量数据显示,在以前,除了中文版之外的大多数维基百科语言版本以前都可在中国访问,中文版据报道自 2015 年 5 月 19 日以来一直被封锁。
OONI 数据显示中国电信(AS4134)至少从 2016 年 11 月 10 日开始封锁 zh.wikipedia.org(之前的 OONI 测试表明 2015 年 3 月 zh.wikipedia.org 是可访问的)。
下图基于 OONI 数据,说明在 2019 年 4 月,多种语言版本的维基百科在中国被封锁。
我们可以在 这里 获得对用于生成上图的 OONI 测量的分析。
OONI 测量结果表明,许多维基百科域名之前都可以访问,但从 2019 年 4 月 25 日开始收集的所有测量数据都显示了所有维基百科子域名的相同 DNS 异常。 前几个月发生的少数 DNS 异常是误报,而 2019 年 4 月以来的 DNS 异常显示维基百科域名被通过 DNS 注入封锁。 大多数测量数据来自中国电信(AS4134)。
由于从中国收集的 OONI 测量结果表明封锁是通过 DNS 注入进行的,我们还可以进一步从中国以外测量基于 DNS 的封锁。 为此,我们从外国进行了 OONI Probe DNS 注入测试,指向中国的 IP 地址。
此测试依赖于中国防火墙将 “注入” 受限域名的 DNS 请求这一事实,即使该请求来自国外并且指向的 IP 地址其实并不提供 DNS 解析服务。 因此,期望是,如果 DNS 查询超时,就说明没有封锁,但如果我们看到响应,那么就说明响应被审查注入了。
OONI Probe DNS 注入测试速度非常快。 它能让我们在不到一分钟的时间内扫描 2,000 多个维基百科域名,并确定哪些域名被封锁。
通过分析 OONI Probe DNS 注入测试的结果,我们发现封锁针对的是 wikipedia.org 的任何子域名 / 语言版本(如 *.wikipedia.org
, zh.wikipedia.org
, en.wikipedia.org
等。)—— 包括 wikipedia.org
—— 但不影响 zh.wikinews.org 之外的任何其他维基媒体(Wikimedia)资源。
封锁针对 wikipedia.org 的子域名而不管它们是否存在(例如,甚至 donotexist.wikipedia.org 都被封锁了!)。 被注入 DNS 响应中返回的 IP 地址似乎也是随机的(先前分析防火墙返回的 IP 地址分布的工作的例子包括 “ 中国的 DNS 长城” 和 “全面了解防火墙 DNS 审查的图景”)。
SNI 过滤
为了检查是否可以通过仅加密 DNS 流量来对维基百科域名的封锁阻止,我们尝试在 Firefox 中启用 DNS over HTTPS。
为此,我们运行:
curl -H 'accept: application/dns-json' https://cloudflare-dns.com/dns-query?name=www.wikipedia.org&type=A
我们能够通过 DNS over HTTPS 成功解析 www.wikipedia.org 域名
这些测试也可以通过在 Firefox 中启用 DNS over HTTPS 来验证。
但是,封锁仍然存在。
从中国只能直接访问 IP 地址,表明可能存在 SNI 过滤。
为了进一步验证封锁是基于 SNI 过滤的假设,我们进行了以下 curl 测试(我们在委内瑞拉进行了类似的测试以确认相同的假设):
$ curl -v --connect-to ::www.kernel.org: https://www.wikipedia.org* Rebuilt URL to: https://www.wikipedia.org/
* Connecting to hostname: www.kernel.org
* Trying 147.75.46.191...
* TCP_NODELAY set
* Trying 2604:1380:4080:c00::1...
* TCP_NODELAY set
* Immediate connect fail for 2604:1380:4080:c00::1: 网络不可达
* Connected to www.wikipedia.org (147.75.46.191) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to www.wikipedia.org:443
* Curl_http_done: called premature == 1
* stopped the pause stream!
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to www.wikipedia.org:443
上面的 curl 测试连接到 www.kernel.org(IP 147.75.46.191),但尝试使用 www.wikipedia.org 的 SNI 进行 TLS 握手。 正如我们从上面的输出中看到的,TLS handshake, Client hello
一发出,连接就中断了。
相反,如下所示,如果我们在与 www.wikipedia.org 进行 TLS 握手时尝试使用 www.kernel.org 的 SNI(我们使用 --resolve
选项跳过 DNS 解析),请求是成功的并且能够完成 TLS 握手。
$ curl -v --resolve 'www.wikipedia.org:443:91.198.174.192' --connect-to ::www.wikipedia.org: https://www.kernel.org* Added www.wikipedia.org:443:91.198.174.192 to DNS cache
* Rebuilt URL to: https://www.kernel.org/
* Connecting to hostname: www.wikipedia.org
* Hostname www.wikipedia.org was found in DNS cache
* Trying 91.198.174.192...
* TCP_NODELAY set
* Connected to www.kernel.org (91.198.174.192) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Wikimedia Foundation, Inc.; CN=*.wikipedia.org
* start date: Nov 8 21:21:04 2018 GMT
* expire date: Nov 22 07:59:59 2019 GMT
* subjectAltName does not match www.kernel.org
* SSL: no alternative certificate subject name matches target host name 'www.kernel.org'
* Curl_http_done: called premature == 1
* stopped the pause stream!
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
curl: (51) SSL: no alternative certificate subject name matches target host name 'www.kernel.org'
基于这些测试,我们得出结论,中国电信确实通过 DNS 注入和 SNI 过滤来封锁维基百科的所有语言版本。
与在埃及实施的审查相似,也许这可以被视为网络封锁的 “纵深防御” 策略。 通过实施基于 DNS 和 SNI 的过滤,中国电信创建了多层审查制度,使翻墙更加困难。
使用加密的 DNS 解析(例如 DNS over HTTPS)以及加密的 SNI(ESNI)可能可以用作翻墙策略。 Wikipedia.org 目前不支持 ESNI,但是已经但有关于启用它的讨论。