现在的版本由于支持了泛域名证书验证,Let’s Encrypt的命令和过程机制都和原来不太一样了,想要进入自动认证的,推荐直接使用LNMP提供的全自动脚本,一条命令搞定,会省很多事情!
前言
首先,就在昨天,从StartSSL申请的为期一年的SSL证书到期了,Renew了新的email证书和所有相关DV证书更新进nginx之后,发现所有浏览器(IE/Firefox/Chromium)全都提示证书安全方面的问题,于是花时间仔细调研了一番,突然震惊的发现如下信息:
Firefox浏览器背后的Mozilla基金会正在考虑对沃通(WoSign)及被其秘密收购的StartCom(著名的StartSSL即其旗下产品)这两个CA一年内新签发的所有SSL证书进行封杀。Mozilla的工程师是在对这两个CA签发了一系列可疑的SSL SHA-1证书进行调查之后,宣布了这个禁令。
这两家CA试图规避已经被我大中华山东大学数学教授王小云对撞破解后宣布不再安全的SHA-1算法的停用政策。
沃通秘密收购了StartCom,在2016年采用倒填日期的手段来签发SHA-1证书。
Mozilla说这个临时封杀仅针对这两个公司最新签发的证书,不影响已经分发给他们的客户的证书。如果这两个公司在一年的封杀后没有通过一系列的检查,Mozilla将准备封杀这两个公司的所有证书。
此外,Chrome和其它产品的对它们的封杀也在计划中。
怎么说呢,这年头信仰的缺失总会带来很大问题,也许有一天迪菲-赫尔曼密钥交换算法也变得不再安全了呢……
综合以上原因,也该暂时放弃StartSSL的SHA-1证书,改投目前我认为一定会火起来的Let's Encrypt项目吧。
Let’s Encrypt
Let’s Encrypt是国外一个公共的免费SSL项目,由Linux基金会托管,由Mozilla、思科、Akamai、IdenTrust和EFF等组织发起,目的就是向网站自动签发和管理免费证书。
看这介绍就觉得很牛,一直懒得去尝试,现在终于是出手的机会了。
本文目的
阅读完本文,我希望使你能够达成如下目的:
- 暂时忘了
StartSSL - 了解
Let's Encrypt - 为你的
ubuntu+nginx一路搞定新的SSL证书
废话不多说,我们开始。
具体步骤
本文使用Let's Encrypt推荐的ACME工具Certbot以达到官方指导的证书自动获取、安装、更新、维护的目的,感兴趣的童鞋请访问下面两个网站了解来龙去脉(鸟语版):
性子急的童鞋,请继续往下看,我们正式开始。
环境假设
- Ubuntu 16.04 LTS
- nginx 1.8
sudo太麻烦,以下所有命令假设全在
root权限下执行
配置APT安装Certbot
首先确定你有add-apt-repository命令,如果没有,先装上:
1 | apt install software-properties-common |
执行下面脚本安装Certbot
1 | add-apt-repository ppa:certbot/certbot |
执行certbot -h,如果看到说明信息,就表示安装成功了(一般APT安装不会失败)
注册Certbot
其实这是Certbot提供的一个帮助性服务:certbot register,这个命令,同意几个协议,填写一个邮箱,将来如果不小心丢了证书凭证,可以通过邮箱找回,挺好的,注册吧。
了解Certbot
这里要说明一些关于Certbot的内容,首先这个工具是安装在服务器上的,可以自动搞定SSL证书的工具,它有两种常用的获得证书的途径,HTTP/TLS-SNI,具体技术细节在这里就不啰嗦了,你只需要选择一种:
- HTTP:你需要开着nginx且可以通过HTTP正常访问(不能开HTTPS)
- TLS-SNI:你需要暂时关闭nginx,因为Certbot会临时打开自己的小服务器获取证书,80端口得给它空出来
HTTP方式
因为我之前的证书在更换成Let's Encrypt项目之前就已经过期了,加上Certbot不能通过HTTPS方式验证域名(网站)的有效性,所以我先将nginx虚机配置中所有跟SSL有关的项目全部注释掉,同时保证nginx reload之后还能正常跑起来,这里可以放心,网站内容能不能正常看并不重要,唯一需要注意的一点是,Certbot在执行完下面这条命令后,会在网站根目录新建一个.well-known目录,你需要保证你的nginx能够解析这个目录(最好的办法是丢个文本文件进去,看看能不能通过浏览器读到里面的内容)。
再次注意:执行下面这个命令需要你的nginx运行正常,且要满足上面一段话中的要求,不然证书申请会因为通过域名访问不了你的虚机而卡在反向认证环节。
1 | certbot certonly -w /home/wwwroot/williamyao.com -d williamyao.com -d williamyao.com |
解释一下上面命令的意思:
-w:指定nginx虚机根目录(nginx虚机配置.conf里面的root项),其实就是用来指挥远程服务反向读取这个目录下面的.well-known文件夹看看能不能访问到,以验证域名的真实性。-d:连着两个,表示配合-w指明的虚机目录,总共有这两个域名指向同一个虚机,这两个域名会打包在一个证书里面。
TLS-SNI方式
这里就比较简单了,因为不牵扯反向认证的问题,但是也有一点,nginx(或者80端口)得给Certbot空出来,它需要启动自己的小服务器来认证。
1 | certbot certonly --standalone -d williamyao.com -d williamyao.com |
这一步和HTTP方式的不同总共有两点:一是nginx开关问题,二是以后证书的自动更新(Renew)问题,这个后面紧接着会讨论,得到的证书等文件以及存放路径都是一样的。
得到的东西
不管选择哪种方式,在成功执行完毕后,都会得到下面的东西:
- /etc/letsencrypt/live/williamyao.com/
- privkey.pem : the private key for your certificate.
- fullchain.pem: the certificate file used in most server software.
- chain.pem : used for OCSP stapling in Nginx >=1.3.7.
- cert.pem : will break many server configurations, and should not be used.
对于nginx来说,我们只需要关心前两个文件,一个是秘钥,一个是证书。
配置nginx虚机的conf
以我的配置为例,编辑/usr/local/nginx/conf/vhost/williamyao.com/conf,将原来所有跟SSL有关的配置项删掉(如果有),然后加入下面的配置:
1 | # 启用 SSL 配置 |
将ssl_certificate和ssl_certificate_key替换为得到的东西里面的证书和秘钥,至于其他配置项的意思,请自行度娘。
重启nginx验收
有些人喜欢reload,我就喜欢重启!service nginx restart.如果不出意外,等服务跑起来,打开浏览器看看结构,是不是HTTPS和证书信息都正常?恭喜你!但是!还没完……
配置自动更新
其实我觉得呢,这一步才是Certbot最吸引人的地方,因为Let's Encrypt项目提供的证书有效期只有90天,频繁更新是挺烦人的事情,因此Certbot在手动执行自动更新证书命令的同时,也支持crontab计划表执行。
命令解释
首先看一下命令:certbot renew --dry-run
这个命令的意思是,让certbot模拟更新一下已有证书,测试一下是否都能正常更新,但只是模拟全程,并不改写现有文件。
针对上面提到的需要选择的获得证书的两种方式,这个自动更新命令需要小有调整,对于HTTP方式,需要保证nginx是在运行的,所以我们用上Certbot支持的钩子机制:
1 | certbot renew --pre-hook "service nginx start" --post-hook "service nginx restart" --dry-run |
上面命令的意思很简单,在执行renew动作之前,先执行service nginx start命令,确保nginx服务是起来的,在执行完renew动作之后,再执行service nginx restart来重启nginx确保更新完的证书及时加入nginx服务。
如果是TLS-SNI方式呢,命令稍作修改:
1 | certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start" --dry-run |
也很好理解嘛。
配置crontab
真正配置生产环境的时候,我们不会想没事儿SSH到服务器上手动执行Certbot的,我们需要crontab的自动方式,啥是crontab,请自行度娘 Again.crontab -e
选择一个文本编辑器之后会自动打开crontab的任务文件,新加入一行对应命令,以我为例,每周二四六的凌晨三点检查更新证书,
HTTP方式:
1 | 0 3 * * 2,4,6 certbot renew -q --pre-hook "service nginx start" --post-hook "service nginx restart" |
TLS-SNI方式:
1 | 0 3 * * 2,4,6 certbot renew -q --pre-hook "service nginx stop" --post-hook "service nginx start" |
保存文件,关闭编辑器之后,crontab就自动按照我们的设定开始新的值守任务了。
注意1:因为是自动运行,我们只关心出错时的信息,所以带上
-q开关,忽略所有非错误的信息。
注意2:因为是生产环境,是真的让它更新,所以去掉
--dry-run模拟开关。
注意3:本章节所有renew命令,Certbot都会预先检查证书的有效期,只有临近过期的证书,才真正会被更新,其它“离着作废还早”的证书是会被智能略过的,所以引用官网上的一句说法,“很可能执行完更新命令,什么也没有发生。”
后记
真的不得不说,StartSSL有点让我伤心,之前还写过一片详细的新手教程,现在也不用再看了。
也许有那么一天,任何东西都不再有加密的必要……
那是共产主义吗?!
因为已经到了头昏脑涨的凌晨一点多,所以此文文风略显“彪悍”,望君海涵!
还是那句话,衷心希望此文能够帮到你。