如何在ssllabs获得A+

2020年07月13日 97点热度 0人点赞 0条评论

过年前在阅读v2射线(不知道那是什么,没听说过)的文档时认识到了ssllabs,简而言之ssllabs是一个测试网站ssl的站点,输入网址后会对网站的ssl进行评分。如今ssl证书可以说是网站的标配,尤其对于防某些流氓来说更是如此。加之一位前端大叔叔给我普及nginx优化,提到了HSTS,所以索性水一篇,介绍一下怎么完善ssl,让你的网站在ssllabs里测试为A+。

如何在ssllabs获得A+

自豪ing

以下内容基于宝塔面板自带nginx配置

选择特定的TLS协议

虽然Nginx默认的协议支持是完整的,但是我们需要排除一些不太安全的协议类型,尽管这样会不得不忽视一小部分用户,例如WindowsXP用户。他们需要通过已经不再安全的老旧协议进行连接。如果要求安全程度比较高则可以只允许TLS1.3协议。建议选用tls 1.2和tls 1.3。

ssl_protocols TLSv1.2 TLSv1.3;

选择密码类型

这里也同样面临着兼容/安全的选择。在这里用了CloudFlare's Internet facing SSL cipher configuration。值得注意的是,如果要加入更多密匙类型支持,那么就需要小心这些类型的排列,应当从最佳加密到最好的兼容排列。

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

前向安全性的配置(Forward Secrecy)

前向安全性(Forward Secrecy)的概念:客户端和服务器协商一个永不重用的密钥,并在会话结束时销毁它。服务器上的 RSA 私钥用于客户端和服务器之间的 Diffie-Hellman 密钥交换签名。从 Diffie-Hellman 握手中获取的预主密钥会用于之后的编码。因为预主密钥是特定于客户端和服务器之间建立的某个连接,并且只用在一个限定的时间内,所以称作短暂模式(Ephemeral)。

如果使用前向安全机制,攻击者取得了一个服务器的私钥,他是不能解码之前的通讯信息的。这个私钥仅用于 Diffie Hellman 握手签名,并不会泄露预主密钥。Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。

因为 PFS(Perfect Forward Secrecy,PFS) 使用了『迪菲-赫尔曼加密法』,所以需要一些额外的配置。

  1. 需要生成一个 dhparam.pem 文件。
  2. 告诉 Nginx 使用不要使用默认的加密算法。

dhparam.pem 生成 法一:很慢

openssl dhparam -out dhparam.pem 2048

dhparam.pem 生成 法二:较快

openssl dhparam -dsaparam -out dhparam.pem 4096

在nginx配置中加入

ssl_dhparam /your path/dhparam.pem;

在哪里执行生成代码就在哪里产生pem文件,例如在root用户下生成就在/root/目录下,生成之后可以移动到自己想要移动的位置。  

其它

add_header X-Frame-Options DENY;

#禁止被嵌入框架

add_header X-Content-Type-Options nosniff; 

#防止在IE9、Chrome和Safari中的MIME类型混淆攻击  

开启HSTS

什么是HSTS

在网站全站HTTPS后,如果用户手动敲入网站的HTTP地址,或者从其它地方点击了网站的HTTP链接,通常依赖于服务端301/302跳转才能使用HTTPS服务。而第一次的HTTP请求就有可能被劫持,导致请求无法到达服务器,从而构成HTTPS降级劫持。这个问题目前可以通过HSTS(HTTP Strict Transport Security,RFC)来解决。

HSTS(HTTP Strict Transport Security)是国际互联网工程组织IETF发布的一种互联网安全策略机制。采用HSTS策略的网站将保证浏览器始终连接到该网站的HTTPS加密版本,不需要用户手动在URL地址栏中输入加密地址,以减少会话劫持风险。

HSTS并不是HTTP会话劫持的完美解决方案。用户首次访问某网站是不受HSTS保护的。这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问。如果用户通过HTTP访问HSTS保护的网站时,以下几种情况存在降级劫持可能:

  1. 以前从未访问过该网站
  2. 最近重新安装了其操作系统
  3. 最近重新安装了其浏览器
  4. 切换到新的浏览器
  5. 切换到一个新的设备,如:移动电话
  6. 删除浏览器的缓存
  7. 最近没访问过该站并且max-age过期了

解决这个不足目前有两种方案

  1. 是浏览器预置HSTS域名列表,Google Chrome、Firefox、Internet Explorer和Spartan实现了这一方案。google坚持维护了一个“HSTS preload list”的站点域名和子域名,并通过HSTS提交其域名。该域名列表被分发和硬编码到主流的web浏览器。客户端访问此列表中的域名将主动的使用HTTPS,并拒绝使用HTTP访问该站点。一旦设置了STS头部或者提交了你的域名到HSTS预加载列表,这是不可能将其删除的。这是一个单向的决定使你的域名通过HTTPS可用的。
  2. 将HSTS信息加入到域名系统记录中。但这需要保证DNS的安全性,也就是需要部署域名系统安全扩展。截至目前这一方案没有大规模部署。

 

如何加入到HSTS Preload List

  1. 具备一个有效的证书
  2. 在同一台主机上提供重定向响应,以及接收重定向过来的HTTPS请求
  3. 所有子域名均使用HTTPS
  4. 在根域名的HTTP响应头中,加入HSTS Header,并满足下列条件:
    • 必须包含includeSubDomains参数
    • 必须包含preload参数
    • 过期时间最短不得少于18周(10886400秒)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

加always需要nginx1.7.5以上,以下不用加。

当你准好这些之后,可以在HSTS Preload List的官网上提交申请。

从提交申请到完成审核,成功加入到内置列表 ,中间可能需要等待几天到几周不等的时间。可通过官网或在Chrome地址栏里输入chrome://net-internals/#hsts查询状态。

如果申请报Warning: Unnecessary HSTS header over HTTP

在网站配置文件中server块上方添加如下内容

map $scheme $hsts_header {
    https   "max-age=31536000; includeSubDomains; preload";
    }

接着在配置文件中server块内添加如下内容

add_header Strict-Transport-Security $hsts_header;

保存配置,生效后Preload List中检测即正常。

 

说完了怎么在ssllab得到A+,接着水一下关于证书安全的CAA验证。

什么是 DNS CAA

譬如说,你的站点已经启用了 HSTS,甚至已经被固化到了浏览器内部。但是一个中间人仍然劫持了你的连接。你走了 HTTPS 协议?没问题,我也搞到了一个你所访问域名的 SSL 证书。要知道 SSL 连接使用的证书是服务端决定的,但是这个证书未必就是真正的域名所有人申请的。虽然普通人未必能搞到不属于你的域名的证书,但是证书颁发机构就不一样——虽然基于信誉的原因他们不太可能会这样做,但是没有任何外在的保护防止他们颁发并非由域名所有人申请的证书。

简而言之,一个有效的证书未必就是域名所有人申请的证书。就好比普通人造不出能过验钞机的假钞,但是再强大的验钞机也不能阻止造币厂监守自盗。这时就需要一个更上层的服务去验证这个“有效的证书”的合法性,这就是 DNS CAA 的作用。

DNS Certification Authority Authorization(DNS证书颁发机构授权,简称 CAA)是一项借助互联网的域名系统(DNS),使域持有人可以指定允许为其域签发证书的数字证书认证机构(CA)的技术。它会在 DNS 下发 IP 的同时,同时下发一条资源记录,标记该域名下使用的证书必须由某证书颁发机构颁发。比如笔者的破站使用了 Let's Encrypt 颁发的免费证书,我可以同时使用 CAA 技术标记我的破站 www.mjish.com使用的 SSL 证书由 Let's Encrypt 颁发,这样就可以(在一定程度上)解决上面所述的问题。

 

启用 DNS CAA

CAA 是 DNS 服务器下发的记录,所以首先要 DNS 服务器支持才行。支持 CAA 记录的DNS服务器包括Cloudflare,同时也建议大家可以把域名转到CF名下,因为把域名转到CF后续费每年是按照出厂价,而如果是在购买域名处续费,一般都会长许多,同时CF有免费的cdn,网站被打可以迅速使用。不是用宝塔建站,申请ssl证书的话使用CF的API可以一键申请,详见Freessl。购买域名可以采用namesilo,不尽价格便宜而且提供免费的隐私保护。

这里以Cloudflare为例,添加 CAA 记录。

  • Name 可以直接填写顶级域名,会自动应用到多级域名。
  • CAA data 填写 0 issue "证书颁发机构域名"
    如果如果你用 Let's Encrypt 颁发的免费证书,CAA data 部分直接填写 0 issue "letsencrypt.org" 即可。
  • 你还可以添加一条为 0 iodef "mailto:你的邮箱" 的 CAA 记录,表示如果发现违背 CAA 记录的情况给这个邮箱发邮件通知。

如果你仍然不太清楚如何填写 CAA 记录,可以用工具直接生成:sslmate.com/caa/。填写域名后点 Auto-Generate Policy,这个工具会自动查询你的网站使用了什么证书,从而生成对应的 CAA 记录数据。

如何在ssllabs获得A+

检验 DNS CAA 是否生效

使用 ssllabs 可以很方便的检验你的域名是否启用了DNS CAA,在检测结果中会出现CAA的起效情况。

mjys

喵酱

一只喜好各类影视,不折腾会挂掉的喵~~