升级 https, Let's Encrypt

升级的原因

去年运营商大面积劫持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个证书。同一个子域名注册或更新都是要计算次数的。《升级 https, Let's Encrypt》

    原文作者:HTTP
    原文地址: https://juejin.im/entry/56ca7dbf99a6ce005a081298
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞