升级的原因
去年运营商大面积劫持http,我们公司的小网站也未能幸免。当时很多用户投诉,马上升级https还有所顾虑,所以当时简单hack了一下。在html中做多种判断,如果是在div中加广告,就把这个div干掉;如果内嵌到iframe中,就改变url,重新加载。暂时解决了,但是治标不治本,所以最近就进行https的升级。
新证书管理机构–Let’s Encrypt
Let’s Encrypt是去年十二月份开始公测的,可以免费申请证书。其签发的证书已经获得了交叉信任,已经能被所有主流浏览器信任了。交叉签名来自 IdenTrust Root CA。
申请证书工具letsencrypt-auto
官方提供了自动获取证书的工具[letsencrypt-auto],只需一条命令,即可获取证书。第一步是下载工具:
git clone https://github.com/letsencrypt/letsencrypt
执行命令./letsencrypt-auto
即可启动客户端,在执行之前,我们来看看它的用法。letsencrypt-auto
官方集成了几个插件来帮助我们使用:
apache 在Debian相关系统的Apache 2.4上,可以实现自动获取和安装证书
standalone 直接获取证书。这个在申请过程中,会启动一个服务占用80端口,并以此来进行域名所有者验证
webroot 如果自己启动了web服务器,这个命令会在根目录中写文件,以便letsencrypt来验证所有者
manual 完全手动,自己动手,丰衣足食
nginx 测试中,等稳定了再加入
letsencrypt-auto
所以,如果正在运行apache服务器,可以执行 ./letsencrypt-auto --apache -d example.com -d www.example.com -d other.example.net
,这个会获取证书,并安装。
如果没有web服务器,可以执行: ./letsencrypt-auto certonly --standalone -d example.com
。
letsencrypt-auto替代者
用过letsencrypt-auto
就知道里面有很多坑了。
我在用的过程中,发现python2.6不支持,python3.5不支持,后来安装python2.7.11才可以运行。
安装python之前,要安装bz2压缩相关的包,不然执行
letsencrypt-auto
会报错。python的源,我用aliyun的不行,提示有个版本的包找不到,换成豆瓣的才可以
http://pypi.douban.com/
。
所以acme-tiny出现了,建议使用这个来代替letsencrypt-auto
。
利用acme-tiny申请证书步骤
建立Let’s Encrypt账户的私钥
openssl genrsa 4096 > account.key
生成域名的私钥
openssl genrsa 4096 > domain.key
#对于单个域名,执行下面这条语句
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
#对于多域名,可以执行下面这条语句
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat etc="" ssl="" openssl.cnf="" <(printf="" "[san]\nsubjectaltname="DNS:yoursite.com,DNS:www.yoursite.com"))"> domain.csr
新建challenge文件夹
mkdir -p /var/www/challenges/
这个文件夹可以是任意文件夹,记得nginx有权限读即可。配置nginx:
server {
listen 80;
server_name yoursite.com www.yoursite.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
...the rest of your config
}
验证域名所有者,就是通过在/.well-known/acme-challenge/
里写文件,然后通过公网来访问,看能不能访问到来判断的。
正式开始申请
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt
提示成功后,signed.crt就是证书,对应的私钥就是domain.key。如果要申请多个,account.key可以不用变化,其他都要变。
安装证书
对于nginx,还需要额外步骤:
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
server {
listen 443;
server_name yoursite.com, www.yoursite.com;
ssl on;
ssl_certificate /path/to/chained.pem;
ssl_certificate_key /path/to/domain.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
ssl_session_cache shared:SSL:50m;
ssl_dhparam /path/to/server.dhparam;
ssl_prefer_server_ciphers on;
...the rest of your config
}
定时更新证书
可以通过crontab来定时更新证书。脚本renew_cert.sh
示例:
#!/usr/bin/sh
python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat /tmp/signed.crt intermediate.pem > /path/to/chained.pem
service nginx reload
#每月1号执行
0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log
注意事项
更新证书时,要保证步骤3设置不变,即letsencrypt服务器能够访问对应域名下的
/.well-known/acme-challenge/
文件夹同一个ip在3小时内最多申请10个域名的证书
同一个根域名在七天内,只能注册5个证书。同一个子域名注册或更新都是要计算次数的。