Nginx 开启 Certificate Transparency 保障证书安全

前言

像米饭这样一个域名签过一坨证书的人恐怕不在少数吧(如下图),然而没有好好保管 crt、key 文件也有的吧,如果被坏人拿去干坏事,就算是有 HTTPS 还是依旧会瞎~
举个栗子:
举个栗子

解释

Certificate Transparency 是什么? 贼烦,一看真的是文言文的赶脚,所以我们这里换个思路看看。

首先,我们的证书是从 CA 那里签出来的,不过呢,

CA 也会有坏银(在 XXX 没有申请的情况下,某 CA 内部不当给 XXX 签了证书)
证书下载方式不完善(证书下载链接应该下载一次后就不能下载,或者说只有十分钟的时效性,但是没有做到这点)
CA 被骗了(拿伪造的信息来骗取证书)
拥有高级权限的软件(病毒)自签证书后,然后让系统信任。

为了规避这些问题,IETF 在2013年启动了一个叫做Certificate Transparency的开源项目,把所有已知的合法证书做了一个白名单,浏览器在验证证书的时候同时也会去查看这个证书是不是在白名单里面。 如果不在的话,就会告知用户这个证书找不到记录,于是,有可能是假或者是被盗的证书。

总之呢,CT 就是为了规避上面的几个“不过”,并让你的 HTTPS 更加安全的一个措施。

表现

首先呢,截止发文也就只有基于 Chrome 内核的浏览器支持 Certificate Transparency。所以有没有设置 CT 也就只有哪些浏览器才会有表现。

一、非 EV 证书的 HTTPS,会提供有这么点提示,并不容易察觉,而且这个截图的版本是 Chrome 49 的,到了 50 以上的版本没有设置 CT 的不会有一点提示,就和没有一样:
非 EV 证书的 HTTPS,会提供有这么点提示

二、EV 证书,在 Chrome 浏览器上就会没有高大上的绿色框框了,因为不会有购买了 EV 证书还不开 CT 的网站,所以我举不出栗子。 不过当贵司大价钱买了 EV 证书,结果没出现绿色框框,而你被领导问到的时候,就会尴尬了。 嗯,总之就是会带来一个尴尬加成。

三、非 EV 证书,设置好了 HTTPS 的样子:
因为米饭粑设置了双证书,所以在两个证书也都设置了 CT。

非 ECC 证书效果:

ECC 证书效果:

设置

其实呢,CT 目前有三种设置方法:X.509v3 扩展、TLS 扩展 和通 过OCSP Stapling 目前,TLS 扩展是最好方案了,并且任何 CA 签的证书都适用。

Nginx-CT

Nginx-CT 模块可以让 Nginx 支持通过 TLS 扩展的方式实现 CT。

注: Nginx-CT 只兼容 BoringSSL 和 OpenSSL 1.0.2 +,不支持 LibreSSL。 推荐 OpenSSL。

#下载 Nginx-CT
wget https://github.com/grahamedgecombe/nginx-ct/archive/v1.3.2.tar.gz
tar xzf v1.3.2.tar.gz

#下载 OpenSSL 1.1.0
https://www.openssl.org/source/openssl-1.1.0c.tar.gz
tar xzf openssl-1.1.0c.tar.gz

#编译 Nginx,根据原本的参数修改:

./configure --add-module=/path/to/nginx-ct --with-openssl=/path/to/openssl 

获取 SCT

利用 ct-submit 工具(需要 go 支持),它会讲证书提交给谷歌和几大证书厂商的 CT LOG 服务器,并获得一个受 Nginx-ct 和 mod_ssl_ct 支持的 sct 格式。

#安装 golang
yum install golang -y  // CentOS、RHEL
apt-get install golang -y // Ubuntu、Debian

wget https://github.com/grahamedgecombe/ct-submit/archive/v1.1.2.zip
unzip v1.1.2.zip
cd ct-submit-1.1.2
go build 

编译成功后会获得一个 ct-submit-1.1.2 文件,我们就开始提交:

我这里是 ECC + RSA 双证书,所以我要申请两个,每个证书我都申请了两个:

./ct-submit-1.1.2 ct.googleapis.com/rocketeer <mf8.biz.ecc.crt >rocketeer-1.sct
./ct-submit-1.1.2 ct.googleapis.com/icarus <mf8.biz.ecc.crt >icarus-1.sct
./ct-submit-1.1.2 ct1.digicert-ct.com/log <www.mf8.biz.crt >digicert-2.sct
./ct-submit-1.1.2 ct.googleapis.com/pilot <www.mf8.biz.crt >pilot-2.sct

注1: ct.googleapis.com 国内服务器无法访问,需要到境外服务器提交获取到 sct 文件再传到国内。
注2: 更多 CT LOG 服务器可以在 这里 看到。

配置

然后就只要在虚拟机的 conf 配置文件中加入:

ssl_ct on; #开启 nginx-ct
ssl_ct_static_scts /path/to/scts/; #这里填写 sct 文件的目录路径,而不是文件路径。

如果是双证书的童鞋,可能会遇到:

root@mf8.biz:~# nginx -t
nginx: [emerg] there must be exactly one "ssl_ct_static_scts" directive for each "ssl_certificate" directive
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

其实是,一个证书(ssl_certificate)要对应一个 scts目录(ssl_ct_static_scts)。

例如:

ssl_certificate /usr/local/nginx/conf/ssl/mf8.biz.ecc.crt;
ssl_ct_static_scts /usr/local/nginx/conf/ssl/sct-1/;
ssl_certificate_key /usr/local/nginx/conf/ssl/mf8.biz.ecc.key;
ssl_certificate /usr/local/nginx/conf/ssl/www.mf8.biz.crt;
ssl_ct_static_scts /usr/local/nginx/conf/ssl/sct-2/;
ssl_certificate_key /usr/local/nginx/conf/ssl/www.mf8.biz.key;

然后重启就够了。

8 条评论

发表评论

*

  • 奇怪,ct出来的怎么是0字节的空文件?
    检查过 提交的Log正常,证书正常。

        • 貌似不同的证书也是要对应不同的服务器的

  • 在几个部署LetsEncrypt证书的域名上启用 OCSP Stapling,只有SSLLabs 显示OCSP Stapling: Yes。Chrome 仍然是原来的样子。

    • 浏览器缓存的锅?OCSP Stapling 我服务器端开启后就没看过客户端的反应。。。。

    • 一个域名可以签很多证书,可能是自己去申请的,也可能是不法分子签的。 我们从服务器认定一张仅我们自己签的证书可以加密流量,其他证书就不行