互联网上前一百万个网站的 SSL/TLS 分析

jopen 10年前

目前看来评估不同的SSL/TLS配置已经逐渐成为了我的业余爱好。在10月份发表了Server Side TLS之后,我参与一些讨论密码性能、key的长短、椭圆曲线的安全等问题的次数都明显增多了(比较讽刺的是,当初之所以写“Server Side TLS”就是非常天真的希望减少我在这个话题上的讨论次数)

SSL/TLS服务器端的配置教程如今越来越多。其中很快就得到关注的一篇是Better Crypto,我们曾经也在dev-tech-crpto邮件列表中讨论了多次。

人们总是对这些话题非常有热情(我也不例外)。但是有一个问题我们一直念念不忘,就是总想着尽快干掉那些被弃用的密码,即便这意味着切断了与一些用户的连接。我是绝对反对这样做的,并且始终坚信最好的做法是为所有用户都维持向后兼容性,即使是以在我们的TLS服务器上保留RC43DES或是1024DHE key为代价。

最近在dev-tech-crypto上有这样一个问题:“我们是否可以在Firefox上将RC4完全移除?”。有人可能认为,因为Firefox支持所有其他的密码(AES, AES-GCM, 3DES, Camelia…),我们当然可以在不影响用户的前提下移除RC4。但是我们没有实际的数据来证明这一点,所以也不能随便作出这样的决定。

接收挑战:我将带上我的武器cipherscan出来兜兜风,并打算扫描下互联网。

扫描方法

扫描脚本github数据结果在这里未压缩的数据有1.2GB之大,但是XZ难以置信的将其压缩成了一个只有17MB大小的数据存档。

我使用Alexa所列出的前1,000,000个网站作为数据源。使用“testtop1m.sh”脚本并行扫描目标,并通过节流来限制同时扫描的数量(设置为100),然后将结果写入到“results”目录。每个扫描目标的结果被存放在一个json文件中。另一个脚本名为“parse_results.py”,它会扫一遍“results”目录并计算统计数据。非常基础的东东。

我花了大概36个小时来运行整个扫描流程。发现总共有451470个网站开启了TLS,占总数的45%

虽然这不是一个全面的统计,但这一数据足以让我们评价SSL/TLS在现实世界中的状态。

对这451470个网站的SSL/TLS调查

密码

Cipherscan返回了每个目标服务器上所有支持的密码。下表显示了普遍被支持的密码以及仅被一些网站所支持的密码。最后一项最有趣,似乎1.23%的网站仅接受3DES,而1.56%的网站仅接受RC4。这对于那些正考虑放弃支持3DESRC4的开发者来说是非常重要的数据。

值得注意的是:有两个人不知出于什么原因仅仅只在他们的网站上开启了Camellia。好吧先生们,我为你们举杯。

对于那些不寻常的密码,我为其添加了前缀“z”并放在列表底部,非常的显眼。事实上从28%的网站明确支持DES-CBC-SHA这一点上可以看出更好的TLS文档和培训的必要性。

Supported Ciphers         Count     Percent  -------------------------+---------+-------  3DES                      422845    93.6596  3DES Only                 5554      1.2302  AES                       411990    91.2552  AES Only                  404       0.0895  CAMELLIA                  170600    37.7877  CAMELLIA Only             2         0.0004  RC4                       403683    89.4152  RC4 Only                  7042      1.5598  z:ADH-DES-CBC-SHA         918       0.2033  z:ADH-SEED-SHA            633       0.1402  z:AECDH-NULL-SHA          3         0.0007  z:DES-CBC-MD5             55824     12.3649  z:DES-CBC-SHA             125630    27.8269  z:DHE-DSS-SEED-SHA        1         0.0002  z:DHE-RSA-SEED-SHA        77930     17.2614  z:ECDHE-RSA-NULL-SHA      3         0.0007  z:EDH-DSS-DES-CBC-SHA     11        0.0024  z:EDH-RSA-DES-CBC-SHA     118684    26.2883  z:EXP-ADH-DES-CBC-SHA     611       0.1353  z:EXP-DES-CBC-SHA         98680     21.8575  z:EXP-EDH-DSS-DES-CBC-SHA 11        0.0024  z:EXP-EDH-RSA-DES-CBC-SHA 87490     19.3789  z:EXP-RC2-CBC-MD5         105780    23.4301  z:IDEA-CBC-MD5            7300      1.6169  z:IDEA-CBC-SHA            53981     11.9567  z:NULL-MD5                379       0.0839  z:NULL-SHA                377       0.0835  z:NULL-SHA256             9         0.002  z:RC2-CBC-MD5             63510     14.0674  z:SEED-SHA                93993     20.8193

密匙协商

让人惊喜的是部署了ECDHE的比例。21%虽然不算是一场胜利,但是对于其被视为一种非常有希望在不久的将来取代RSA(至少是在密匙协商方面)的算法来说,这却是一个鼓舞人心的数字。

DHE,从SSLv3开始支持到现在已经有接近60%的部署量。我们需要尽快将这个数字提升到100%

Supported Handshakes      Count     Percent  -------------------------+---------+-------  DHE                       267507    59.2524  ECDHE                     97570     21.6116

PFS

完全正向保密(perfect forward secrecy)目前非常流行,所以评估它的部署量最有趣。事实上我重复检查了3次结果才确定下表所示的比例,75%的网站支持PFS,非常准确,因为对我来讲这是非常大的数量。更令人惊讶的是,事实上61%被测试的网站,要么是自己倾向、要么是让客户端倾向于PFS key交换(DESECDHE)而不是其它密码。

不出所料,绝大多数——98%DHE key1024位。导致这个情况的原因如下:

  1. Apache2.4.6及其以前的版本中,DH参数总是设置为1024位并且不是用户所能配置的。未来Apache的版本会为DH参数自动选择一个更好的值。

  2. java6,或许还有一些其它的库,并不支持大于1024位的DHE key

所以,虽然大家都同意需要一个2048位的RSA算法模型,但使用1024位的DHE key,即便其有效的降低了TLS的安全性,可目前还没有任何的解决办法——不同于打破旧客户端的向后兼容性。

ECDHE这方面,总是使用P-256曲线来完成握手。同样的,这也很容易理解,因为IECHromeFirefox目前仅仅持P256。但是根据最近由DJBLange发表的研究显示,这可能不是最安全的选择。

下表中的曲线统计存在一些瑕疵:Cipherscan在底层使用OpenSSL,而我并不确定OpenSSL是如何在握手阶段选择曲线的。这是Cipherscan需要改进的一块,所以希望大家不要受这些数字的影响。

Supported PFS             Count     Percent  PFS Percent  -------------------------+---------+--------+-----------  Support PFS               342725    75.9131  Prefer PFS                279430    61.8934    DH,1024bits               262561    58.1569  98.1511  DH,1539bits               1         0.0002   0.0004  DH,2048bits               3899      0.8636   1.4575  DH,3072bits               2         0.0004   0.0007  DH,3248bits               2         0.0004   0.0007  DH,4096bits               144       0.0319   0.0538  DH,512bits                76        0.0168   0.0284  DH,768bits                825       0.1827   0.3084    ECDH,P-256,256bits        96738     21.4273  99.1473  ECDH,B-163,163bits        37        0.0082   0.0379  ECDH,B-233,233bits        295       0.0653   0.3023  ECDH,B-283,282bits        1         0.0002   0.001  ECDH,B-571,570bits        329       0.0729   0.3372  ECDH,P-224,224bits        4         0.0009   0.0041  ECDH,P-384,384bits        108       0.0239   0.1107  ECDH,P-521,521bits        118       0.0261   0.1209

协议

在协议扫描的结果中有些地方让我很吃惊:仍然有18.7%的网站支持SSLv2!拜托,各位,我们已经重复了这个问题有很多年了:SSLv2漏洞太多了,不要使用它!

我非常欣赏这38个仅仅接受SSLv2的网站。干的好。

同样有趣的是,2.6%的网站支持TLSv1.2,而不是TLS1.1。合理的情况下,TLSv1.2网站的数量应该大于2.6%才对,但事实并非如此(只有0.001%).所以我只能想象,出于某些原因,网站都使用TLSv1TLSv1.2,而不是1.1

更新:HN上的“harshreality找出了一条OpenSSL中的更新日志可以来解释这种行为:

Changes between 1.0.1a and 1.0.1b <a title="26 Apr 2012" href="https://jve.linuxwall.info/blog/26%20Apr%202012">26 Apr 2012</a>  - OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately mean any application compiled against OpenSSL 1.0.0 headers setting SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to 0x10000000L Any application which was previously compiled against OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 will need to be recompiled as a result.

不出所料,绝大多数网站都支持SSLv3TLSv1,分别为99.6%98.7%。有少量的网站支持TLS1.11.2,这令人担忧,但一点也不奇怪。

考虑到近期的商业产品对TLS版本的可怜的支持,所以这也不能怪系统管理员。供应商可以肯定会推动这一进程,所以在你更新下一个合同前,确保将TLSv1.2加入你的心愿单。

Supported Protocols       Count     Percent  -------------------------+---------+-------  SSL2                      85447     18.9264  SSL2 Only                 38        0.0084  SSL3                      449864    99.6443  SSL3 Only                 4443      0.9841  TLS1                      446575    98.9158  TLS1 Only                 736       0.163  TLS1.1                    145266    32.1762  TLS1.1 Only               1         0.0002  TLS1.2                    149921    33.2073  TLS1.2 Only               5         0.0011  TLS1.2 but not 1.1        11888     2.6332

哪些没有被测试?

这不是一个全面的测试。还有RSA key的大小没有被评估。同时还有TLS扩展,OCSP Stapling支持,以及一些值得反复观察的有趣的特征。下次再说吧。

培训,以及向后兼容

如果要说这个小实验说明了些什么问题,那就是旧的密码和协议还远远没有被抛弃。当然,如今你可以决定在客户端上干掉RC43DES,但是要注意有一小部分的因特网将是你和你的用户连接不到的。

对这个情况我们可以做什么?培训是关键:TLS是一个复杂的专题,而大多数的管理员和网站所有者没有时间和知识去找遍几十个邮件列表和博客来得到最好的配置选择。

这也是编写Server Side TLSBetter Crypto等文档的首要动机。我们中的一些人是致力于改进这些文档的。但是我们需要一个团队来传播这些信息,在会议、邮件列表和用户群中指导管理员们,同时推动网站所有者为他们的网站添加更多的安全配置。我们需要一些帮助:去那里!教TLS吧!

原文链接: Julien Vehent   翻译: 伯乐在线 - deathmonkey
译文链接: http://blog.jobbole.com/55550/