Nginx启用Certificate Transparency指南

首先放一张截图

Certificate Transparency 是什么?

在chrome浏览器中,针对启用https的网站,从2015年的某个版本开始,会展示 Certificate Transparency 的说明。

如果没有提供 SCT 信息,最新的 Chrome 只是会在点击地址栏小绿锁时给出说明,内容如下:

The server did not supply any Certificate Transparency information.
服务器未提供任何 Certificate Transparency 信息。

而提供 SCT 信息之后,Chrome 的提示是这样的:

The server supplied valid Certificate Transparency information.
服务器提供了有效的 Certificate Transparency 信息。

HTTPS 网站的身份认证是通过证书信任链完成的,浏览器从站点证书开始递归校验父证书,直至出现信任的根证书(根证书列表一般内置于操作系统,Firefox 则自己维护)。然而,受信任的 CA(证书颁发机构)有好几百个,他们成为整个网站身份认证过程中一个较大的攻击面。实际上,目前由于 CA 失误导致错误签发证书;以及个别 CA 出于某些目的(如监控加密流量)故意向第三方随意签发证书这两种情况时有发生。

无论是 CA 无意或有意签发出来的「非法证书」,都能通过目前的证书链校验机制的验证。这些 CA 签发的「非法证书」相比自签名的「无效证书」,更难被发现,即使被发现依靠现有机制也很难快速消除影响。

另外,域名所有者的管理不善也可能导致域名配置被第三方控制,从而第三方能够向 CA 申请你网站的证书(特别是 DV 类型的证书)。这种情况,发现和处理同样很麻烦。

Certificate Transparency 就是为了解决这些问题诞生的,它可以直译为证书透明度,由 Google 主导,并由 IETF 标准化为 RFC6962。Certificate Transparency 的目标是提供一个开放的审计和监控系统,可以让任何域名所有者或者 CA 确定证书是否被错误签发或者被恶意使用,从而提高 HTTPS 网站的安全性。

Certificate Transparency 整套系统由三部分组成:

  • Certificate Logs;
  • Certificate Monitors;
  • Certificate Auditors。

完整的工作原理可以看官方文档:How Certificate Transparency Works

简单说来,证书所有者或者 CA 都可以主动向 Certificate Logs 服务器提交证书,所有证书记录都会接受审计和监控。支持 CT 的浏览器(目前只有 Chrome)会根据 Certificate Logs 中证书状态,作出不同的反应。CT 不是要替换现有的 CA 设施,而是做为补充,使之更透明、更实时。

Certificate Logs 服务器由 Google 或 CA 部署,这个页面列举了目前已知的服务器。合法的证书提交到 CT Logs 服务器之后,服务器会返回 signed certificate timestamp(SCT),要启用 CT 就必须用到 SCT 信息。

如何在Nginx中启用 Certificate Transparency

目前最简单的启用 Certificate Transparency 的方案是通过 TLS 扩展启用,下面给大家介绍如何在 Nginx 中启用 Certificate Transparency

一、获取SCT文件

通过 ct-submit 这个模块,可以方便地将证书提交给 CT Logs 服务器并得到 SCT 响应。这个模块需要 go 语言的支持:

1
2
3
4
5
6
yum install golang
wget https://github.com/grahamedgecombe/ct-submit/archive/master.zip
unzip master.zip
cd ct-submit-master
go build

编译成功后,当前目录会出现名为 ct-submit-master 的可执行文件。接着就可以提交了:

1
2
./ct-submit-1.0.0 ct.googleapis.com/aviator </usr/local/nginx/conf/server.crt >/use/locan/nginx/conf/scts/aviator.sct
./ct-submit-1.0.0 ct1.digicert-ct.com/log </usr/local/nginx/conf/server.crt >/use/locan/nginx/conf/scts/digicert.sct

以上代码分别向 Google 和 Digicert 的服务器提交了证书,更多可用的服务器可以在这个页面找到。

server.crt 是我的站点证书和中间证书,最开始是站点证书,之后是中间证书。

二、编译 Nginx,加入 CT 模块

要让 Nginx 支持发送 signed_certificate_timestamp 这个 TLS 扩展,需要加入 nginx-ct 这个模块。nginx-ct 需要与 OpenSSL 1.0.2+ 或者 BoringSSL 4fac72e+ 一起编译,不支持 LibreSSL。

1
2
3
4
5
6
7
8
9
10
11
wget http://nginx.org/download/nginx-1.9.11.tar.gz
tar zxvf nginx-1.9.11.tar.gz
wget https://github.com/grahamedgecombe/nginx-ct/archive/master.zip
unzip master.zip
wget https://www.openssl.org/source/openssl-1.0.2f.tar.gz
tar zxvf openssl-1.0.2f.tar.gz
cd nginx-1.9.11/
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6 --with-http_v2_module --with-openssl=/root/openssl-1.0.2f/ --add-module=/root/nginx-ct-master

然后 make 并把 objs 目录下的 nginx 替换掉原先nginx目录sbin目录下的 nginx 即可。

三、修改配置

最后,修改 Nginx 配置,加入以下两行并重启服务即可:

1
2
ssl_ct on;
ssl_ct_static_scts /your/path/to/scts;

需要注意的是,在此处加上Nginx配置后,必须要重启nginx,不能直接nginx -s reload的方式,否则之前仍然不会发送 Certificate Transparency 的信息