Let’s encrypt + HTTP2
DNS劫持 + 权威机构颁发的伪造证书, 足以毁掉整个互联网.
这不是危言耸听, 而是正在发生...
刚使用StartSSL一个月出头, Mozilla基金会 就公布了关于 WoSign CA 不当行为的调查报告. 报告称 WoSign & StartCom 通过故意倒填证书日期, 从而绕过浏览器对SHA-1证书的限制, 并正式提议将停止信任 WoSign & StartCom 一年内新签发的所有证书. 不过正赶上国庆, 闲来无事, 换成 Let’s encrypt 的证书, 顺便支持一下 http2 , 当真是极好的...
在干活之前, 我们先来了解一下这次事件:
事件发展:
- Mozilla基金会 于2015年3月着手调查 WoSign 签发不再安全的SHA-1证书的问题.
- WoSign 于2015年11月秘密收购 StartCom .
- 疑似 StartCom 的前雇员披露 WoSign 秘密收购 StartCom . 以色列企业登记信息表明 StartCom 当前所有人确实为 WoSign CEO王高华.
- WoSign CEO王高华对先前的纰漏表示非常愤怒, 声称这位前雇员违反了NDA保密协议, 将采取法律行动. 并依然拒绝承认收购 StartCom.
- WoSign 的母公司 Qihoo 360 承认 WoSign 收购 StartCom.
- WoSign CEO王高华坚称 StartCom 独立运营, 其原始系统没有发生改变.
- StartCom 在被收购一个半月后, 其官网 StartSSL.com 于2015年12月18日暂停服务并升级系统, 同月22日重新开放, 并开始使用 WoSign 的基础设施签发证书.
- Mozilla基金会 于16年9月20日公布了对 WoSign CA 不当行为的调查报告.
- Qihoo 360 首席安全官 谭晓生 承认 Qihoo 360 是 WoSign 的最大股东, 持有84%股权.
股权关系:
如此看来, "涉事"公司共有这么几个: StartCom / WoSign / Qihoo 360 . 其中, StartCom 被 WoSign 100%收购. 而根据Peter Bowen的调查, WoSign 股权分布如下:
WoSign 股权持有者 | 持有比例 |
---|---|
Qihoo 360 Software (Beijing) Co., Ltd. | 25.61% |
Beijing Qifutong Technology Co., Ltd. | 29.77% |
Beijing Yuan Tu Technology Co., Ltd. | 28.62% |
WoSign CEO Gaohua Wang (an individual) | 12.00% |
Ganfu Zhang (an individual) | 4.00%
值得注意的是: Beijing Qifutong Technology Co., Ltd.(奇付通) & Beijing Yuan Tu Technology Co., Ltd. [属 Qihoo 360 的可变利益实体的附属公司]6. Qihoo 360 分别占股 100% & 70%.
也就是说: 在股权方面, Qihoo 360 直接或间接持有 StartCom 75% 以上的股份. 而实际运作方面, 管理 WoSign & StartCom 中国区所有业务的, 正是 Qihoo 360 (对外称为技术支持).
StartCom / WoSign 做错了什么:
- WoSign 在没有审核域名归属的情况下, 给申请者颁发了一张 GitHub 根域名的SSL证书.
- StartCom & WoSign 伪造证书签发日期, 试图规避 SHA-1 停用政策.
- 即使有充分的技术证据证明 WoSign 已经100%收购 StartCom , WoSign CEO王高华仍然拒绝承认收购 StartCom .
- 即使有充分的技术证据证明 StartCom 使用 WoSign 的基础设施签发证书, WoSign CEO王高华仍坚称 StartCom 独立运营, 其原始系统没有发生改变.
可能会发生什么:
试想: 我要截获你发送给你朋友的快递(数据包), 需要几个步骤?
- 篡改收件地址(DNS劫持), 使包裹发送到错误的地点.
- 拿着你朋友的身份证(权威机构颁发的伪造证书), 假装我是你朋友, 收下邮件.
那么, 反观中国互联网, 第一道防线已经被我大天朝特有的 中国长城防火墙 (DNS劫持 & DNS污染)攻破. 而 StartCom & WoSign (可能还有 CNNIC )这么一搞, 第二道防线(权威机构颁发的证书)也不能保证数据的安全了. 即使这些组织义正言辞地说:"我们不会监控大家的数据"/ "我们不会泄露隐私"/ "我们是为了大家的信息安全着想". 我们也会有些许不自在: 毕竟当某个机构可以监控互联网上的所有讯息和数据, 谁知道他们会拿去做什么? 如果这个组织混有图谋不轨的成员, 后果可想而知...
不容忽略的事实:
- WoSign 不光通过了通过了 微软认证 / Google Chrome认证 / Android 国际认证 , 还通过了 WebTrust 国际认证 , 甚至成为了中国大陆唯一一家加入 国际CA/浏览器产业联盟 的成员单位. 但到目前为止, 除了 Mozilla基金会 , 其余认证机构均没有对这次事件做出回应.
- 此次事件中 Mozilla基金会 站在了道德制高点, 指出 StartCom / WoSign 的种种罪行并加以处罚. 但值得注意的是: 现有的免费SSL证书提供商一共有两家: StartCom & Let's encrypt . 如果 StartCom 已经不被大众信任, 大多数人(包括我)则会投入 Let's encrypt 的怀抱. 而 Mozilla基金会 正是 Let's encrypt 的主要赞助商之一.
Let's encrypt 证书的申请 & 使用
Let's encrypt 的申请证书过程很简便:
- 打开 Let's encrypt 官网
- 点击 Get Started
- 根据实际需求和说明文档, 我选择使用 Certbot 来管理证书.
- 选择Web服务器软件和操作系统, 这里我用 Nginx & Ubuntu 16.04 .
- putty链接服务器, 输入命令: (如果不把lnmp关掉的话是不能正确获取到证书的)
lnmp stop
sudo apt install letsencrypt
letsencrypt certonly --standalone -d 8023.moe -d www.8023.moe
- 根据提示, 证书已经放在了 /etc/letsencrypt/live/8023.moe .
- 修改Nginx配置文件 /usr/local/nginx/conf/vhost/8023.moe.conf , 添加/ 修改代码(注释部分为不再使用的 StartSSL 证书):
ssl on;
ssl_certificate /etc/letsencrypt/live/8023.moe/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/8023.moe/privkey.pem;
#ssl_certificate /usr/local/nginx/certs/8023.moe/1_8023.moe_bundle.crt;
#ssl_certificate_key /usr/local/nginx/certs/8023.moe/8023moe.key;
- 执行第一条命令添加计划任务(软件有Bug, 有几率提示 letsencrypt.client:Registering without email! , 不影响使用.) 但我选择隔三个月手动输入第二条命令续期:
letsencrypt renew --dry-run --agree-tos
letsencrypt renew
- 重启Nginx( lnmp restart )或重启服务器( reboot now ).
Http2
关于 Http2 的相关知识网上已经有很多, 在此不多赘述. 大体就是 安全性更佳 & 性能大幅度的提升. 如果你想知道自己的浏览器是否支持 Http2 , 或想直观的感受 Http2 与 Http1.1 的差距, 可以打开这个网页进行体验.
Http2 配置
注意: 我使用的 LNMPA 1.3 一键安装包已经默认支持 Http2 , 如果您使用其他的一键安装脚本或自行安装运行环境, 请先自行升级 Nginx 到 1.9.5 以上版本 / Apache 到 2.4.17 以上版本. 并自行搜索安装相关组件.
修改Nginx配置文件 /usr/local/nginx/conf/vhost/8023.moe.conf , 将 listen 443; 改为 listen 443 ssl http2 default_server; , 启用 Http2 支持.
打开 Qualys SSL Labs , 输入网址进行测试:
OH, 得分并不理想, 根据提示, 应该是支持弱DH密钥交换参数. 下面也给出了相关的解决方案, 只需要按照它给的步骤做就行了:
- 生成DH参数: openssl dhparam -out /etc/letsencrypt/live/8023.moe/dhparams.pem 2048
- 修改Nginx配置文件 /usr/local/nginx/conf/vhost/8023.moe.conf 添加如下内容:
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/letsencrypt/live/8023.moe/dhparams.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
这段配置文件大意分别是:
- 设置会话超时时间为5分钟
- 设置会话缓存时间为5分钟
- 设置 SSL 协议为 TLSv1 TLSv1.1 TLSv1.2
- 设置 SSL 加密密码类型, 其实写成 ssl_ciphers 'AES128+EECDH:AES128+EDH'; 也可, 但对WinXP和IE6的兼容性不佳.
- 加密密码类型由服务器选择而不是客户端浏览器选择.
改完了之后文件就成了下面这样:
server
{
listen 443 ssl http2 default_server;
#listen [::]:80;
server_name 8023.moe *.8023.moe;
index index.html index.htm index.php;
root /home/wwwroot/8023.moe;
if ( $host != '8023.moe' ) {
rewrite "^/(.*)$" https://8023.moe/$1 permanent;
}
ssl on;
ssl_certificate /etc/letsencrypt/live/8023.moe/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/8023.moe/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/letsencrypt/live/8023.moe/dhparams.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
#ssl_certificate /usr/local/nginx/certs/8023.moe/1_8023.moe_bundle.crt;
#ssl_certificate_key /usr/local/nginx/certs/8023.moe/8023moe.key;
#error_page 404 /404.html;
include proxy-pass-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /\.
{
deny all;
}
access_log off;
}
server
{
listen 80;
#listen [::]:80;
server_name 8023.moe *.8023.moe;
rewrite ^(.*)$ https://8023.moe$1 permanent;
}
再跑个分?
Perfect!~ Http2的配置到此结束~