HTTPS 检测平台

之前的文章「开启全站 HTTPS(附百度分享本地化)」,写的是 HTTPS 的启用方法和一点其他细节,整体还是比较基础。

这样的配置在 SSLLABS.COM 并不能取得很好的评级。

通过这个强大的在线平台,我们能检测出 HTTPS 站点的 SSL 证书信息、安全缺陷、以及常见操作系统下的加密套件适用情况。

我保留了早前第一次开启 HTTPS 后的评级截图:

把 HTTPS 安全评级提升到 A+-极客飞船

F,最低水平(尴尬),而造成评级只有 F 的首要原因也给出了说明:

把 HTTPS 安全评级提升到 A+-极客飞船

OpenSSL Padding Oracle vuln.(CVE-2016-2107) ,“密文填塞”漏洞,该漏洞存在于 OpenSSL 1.0.2 < 1.0.2h 和 1.0.1 < 1.0.1t 的版本中。

除了 CVE-2016-2107 ,更近期的还有 CVE-2016-2108 漏洞,OpenSSL 官方有关于它们的安全公告:传送门

OpenSSL 的版本可以使用命令 # openssl version 自查,如果版本存在漏洞就要赶紧升级了。

升级 OpenSSL

很多 IDC 主机操作系统自带的 OpenSSL 版本都是低于 1.0.2h 的,加上 OpenSSL 的安全公告是英文 ,SSLLABS 的检测报告也是英文,翻译过来翻阅过去劳神费力。

所以最简单解决 OpenSSL 已知漏洞的办法,就是将 OpenSSL 升级到 1.0.2K,也就是截至本文发布的最新版本。

下面是我的升级流程:

#获取资源&安装
wget https://www.openssl.org/source/openssl-1.0.2k.tar.gz
tar xvf openssl-1.0.2k.tar.gz
cd openssl-1.0.2k
./config shared zlib-dynamic
make
make install

#重命名旧文件
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak

#链接新文件
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
echo “/usr/local/ssl/lib” >> /etc/ld.so.conf
ldconfig -v

详尽定义与 SSL 有关的参数

解决 OpenSSL 安全漏洞是第一步,对于 webserver 的配置还要做细致的定义。

极客飞船是用的 Nginx,下面是本站关于 SSL ,也就是 443 端口下的配置。

server
{
listen 443 ssl;
server_name geekufo.com www.geekufo.com;
root /网站目录;

#配置证书路径
ssl_certificate /公钥路径;
ssl_certificate_key /私钥路径;

#加入2048位的迪菲、赫尔曼算法秘钥
#要先手动生成
#下面是生成命令,路径可以自定义
#openssl dhparam -out /www/ssl/dhparam.pem 2048
ssl_dhparam /www/ssl/dhparam.pem;

#允许的协议,针对降级攻击,禁用SSLv2 SSLv3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

#优先使用服务端设定的加密套件,而不是浏览器的
ssl_prefer_server_ciphers on;

#禁用不安全的加密套件
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4';

#优化TLS握手,缓存链接凭据
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;

#OCSP封套
ssl_stapling on;
ssl_stapling_verify on;
resolver 114.114.114.114 valid=300s;
resolver_timeout 10s;

#后面省略了关系不大的配置
......
}

做到这一步,再去 ssllabs.com 检测,已经是 A 了。

把 HTTPS 安全评级提升到 A+-极客飞船

这样一套下来,基本在现代的操作环境下都会采用 TLSv1.2 加密方式,次一点也是 TLSv1.0 。

同时,也放弃了 IE 6 ,一方面 IE 6 仅支持安全性欠佳的 SSLv2、SSLv3,另一方面根据百度流量研究院的统计报告:

2016 年 3 月 至 2017 年 2 月这一年,IE 6 的市场占有率仅有 1.92% 了,并且一直呈逐步下降的态势。

把 HTTPS 安全评级提升到 A+-极客飞船

我本来想取最近的样本,但涵盖今年 3 月的话,IE 6 在统计里已经就没有踪影了 _(:зゝ∠)_

其实也能看到,整个配置涉及了很多专业的概念,例如 OCSP 、dhparam 。

这里感谢那些无私分享的博主们,通过不同的博文,我获取到了有关这些概念的释义。

我把这些分散、碎片化的信息归集到了一个 txt 文本,并附上了出处,我相信学习,还是要“知其然并知其所以然”,赞同的朋友不妨看一看 —— 传送门

启用 HSTS

A 是个不错的优化结果,但我们还能再做点事,让它达到顶级的 A+,这项工作是「HSTS」。

HSTS 全称 Header Strict Transport Security(严格 HTTPS 传输模式),简单地说:让客户端在本地强制采用 HTTPS 访问。

这个跟我们常用的 301 跳转有什么区别呢?

回想下我们平时上网的习惯,输域名是不是通常没有加 http:// 或 https:// ?

以本站的 301 跳转举例,提交 geekufo.com ,此时客户端实际发出的是 HTTP 请求,然后由服务器来决定是否采用 HTTPS。

那么在服务器验证和决定跳转 HTTPS 前,都是采用的明文传输。

HSTS 的作用,更一步地说,是强制让浏览器,在限定的时间内,对站点使用 HTTPS 访问。

和 301 跳转不同之处在于,它是由客户端来决策,而不是服务器。

Nginx 启动这个功能,需要在配置中加入:

# 开启 HSTS
add_header Strict-Transport-Security "max-age=15552000; includeSubdomains; preload";

但启用 HSTS 需要慎重!

如果网站中途放弃了使用 HTTPS ,用户又没有清除缓存,致网站无限重定向

同时 HSTS 也存在需要填补的安全漏洞。

为了使 HSTS 生效,客户端必须先访问一次站点以获取响应头,所以首次连接依然给 HTTP 明文传输留下了机会。

解决办法是申请加入「HSTS Preload List」。

这是一份由 Google Chrome 维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 同在使用,包含了支持 HSTS 的站点域名,并定期更新的名单。

申请地址(需翻墙)

申请条件:

拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);

将所有 HTTP 流量重定向到 HTTPS;

确保所有子域名都启用了 HTTPS;

HSTS 响应头要求:max-age 不能低于 18 周(10886400 秒),必须指定 includeSubdomains 参数,必须指定 preload 参数。

查询方式:

申请一段时间后,使用谷歌浏览器输入 chrome://net-internals/#hsts ,在 Query domain 项中查询。

把 HTTPS 安全评级提升到 A+-极客飞船

总之,HSTS 适合已经确定会一直使用全站 HTTPS 的站点。

最后,如果网站用了 CDN ,那么 SSLLABS 可能检测到的是 CDN 的节点,一番折腾后测出个 F 也不必沮丧,比如我接入 VeryCloud 后检测,就只有 F ,解析回源站再测才能得到 A+ ,这才是真实的安全水平。

把 HTTPS 安全评级提升到 A+-极客飞船