用Let's encrypt 免费给自己的博客加上https之小白版

最近公司任务不是很重,适配iOS 10 ATS 已经成为了项目这一个月的任务,杨老大负责任的把这个重担一个人扛下了,因此我等小民就只能自己去研究了,于是就寻思着给自己的博客加上ssl验证,有个小绿锁🔒 看起来确实是舒坦很多。在这里就记录下全过程。

前言

HTTPS目前已经成为各大主流网站的标配,未来必将成为一种趋势,很多个人博客现在也都加入了HTTPS的阵营。HTTPS好处多多,可以防止各种攻击劫持,运营商广告植入,客户传输信息泄露等问题。为了让HTTPS能够全面普及,Let’s Encrypt项目应运而生,它由互联网安全研究小组ISRG(Internet Security Research Group)提供服务,ISRG是来自美国加利福尼亚州的一个公益组织。Let’s Encrypt 得到了 Mozilla、Cisco和 Chrome 等众多公司和机构的支持。

关于Let’s Encryot

Let’s Encrypt 是一个新的 CA,他能够提供一种非常容易的方式来获取和安装免费的 TLS/SSL 证书,从而在 web 服务器上启用 HTTPS 加密。他通过提供软件客户端 letsencrypt 来简化这个过程,它企图自动完成大部分所需的必要步骤。当前,Let’s Encrypt 仍然处在公开测试阶段,他整个获取和安装证书的流程只在 Apache 服务器上实现了全部自动化。然而 Let’s Encrypt 也可以很容易的在其他不同的服务器上获取和安装免费的 SSL 证书。
验证流程

申请 Let’s Encrypt 证书不仅免费、代码开源,而且配置简单,不过每次申请只有90天的有效期,但可以通过脚本定期更新,配置好之后一劳永逸。

下面就开始来一起看看吧~

第一步:创建 LET’S ENCRYPT 账号(如何你没有的话),并生成CSR文件

为了区分其他,我们现创建一个文件夹,用来单独存放账号、证书和key

1
2
mkdir ssl
cd ssl

Let’s Encrypt使用一个私钥来进行账号的创建与登陆,因此我们需要使用openssl创建一个account.key。首先我们需要看下我们的openssl的安装目录,并记录下openssl.cnf 文件的地址。

1
openssl versiona

从这里我们可以看到当出openssl的安装路径

1
2
3
4
5
6
OpenSSL 1.0.2g 1 Mar 2016
built on: reproducible build, date unspecified
platform: debian-amd64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fdebug-prefix-map=/build/openssl-wIGtVG/openssl-1.0.2g=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/lib/ssl" //这个就是我们需要的openssl的路径了

这一步完成后,我们开始我们的第一步

创建Let’s Encrypt私钥

首先进入我们刚刚的ssl 文件夹,然后生成私钥

1
2
cd ssl
openssl genrsa 4096 > account.key

创建CSR(Certificate Signing Request,证书签名请求) 文件

ACME协议 (Let’s Encrypt所使用的) 需要一个csr文件,用来进行证书签名和证书更新。

将需要加密的域名加到下面的代码中,目前一张证书最多可以加密 100 个域名,注意命令行中的域名换成你自己的域名:

1
2
3
openssl genrsa 4096 > domain.key
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /usr/lib/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

注意:openssl.cnf 文件的位置可能会因为linux版本的不同而有变,我们只需要在上一步中的openssl 路径后面加上/openssl.cnf

现在我们已经生成了csr和私钥,接下来就到了比较纠结的一步了,需要证明你拥有该域名

配置域名验证

CA 在签发 DV(Domain Validation)证书时,需要验证域名所有权。传统 CA 的验证方式一般是往 admin@youmail.com 发验证邮件,而 Let’s Encrypt 是在你的服务器上生成一个随机验证文件,再通过创建 CSR 时指定的域名访问,如果可以访问则表明你对这个域名有控制权。 首先创建用于存放验证文件的目录,然后通过 “.well-known/acme-challenge/“ 这个URL来访问到验证文件. 注意: Let’s Encrypt 会对你的服务器做一次http请求来进行验证,因此你需要保证80端口能够访问:

1
mkdir -p /var/www/challenges

然后配置一个 HTTP 服务,以 Nginx 为例:(注意:这里的端口是80,不是443)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//这个是新增加的一个servr
server {
listen 80;
server_name yoursite.com www.yoursite.com;
if ( $request_uri !~ "/.well-known/acme-challenge/*" ) { # 让 Let's Encrypt 成功访问到验证文件不受 301 影响
return 301 https://yoursite.com$request_uri; # 注意进行301重定向到https,否则通过http仍能访问你的站点
}
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
#...你的其他配置
}

这个验证服务以后更新证书还要用到,需要一直保留。

获取网站证书

先回到我们的ssl目录,然后把 acme-tiny 脚本保存到 ssl 目录

1
2
3
4
5
cd
cd ssl
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
sudo chmod +x acme_tiny.py
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt

如果一切正常,当前目录下就会生成一个 signed.crt,这就是申请好的证书文件。

安装证书

证书生成后,就可以把它配置在web 服务器上了,需要注意的是,Nginx需要追加一个Let’s Encrypt的中间证书,在 Nginx 配置中,需要把中间证书和网站证书合在一起:
``
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem

1
2
3
最终,修改 Nginx 中有关证书的配置并 reload 服务即可:
## 修改 Nginx 中有关证书的配置并 reload 服务

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_prefer_server_ciphers on;

#…你的其他配置
}

server {

listen 80;
server_name yoursite.com www.yoursite.com;

if ( $request_uri !~ “/.well-known/acme-challenge/*” ) { # 让 Let’s Encrypt 成功访问到验证文件不受 301 影响
return 301 https://yoursite.com$request_uri; # 注意进行
301重定向到https,否则通过http仍能访问你的站点
}

location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}

#…你的其他配置
}

大功告成

好了,现在就能重启你的nginx

1
nginx -s reload

后续

恭喜!你的网站已经使用上了HTTPS。 但Let’s Encrypt 证书有效期只有90天, 所以需要定期更新。现在只需要写一个更新脚本并把它放到定时任务中即可。

在ssl的文件夹内进行如下操作

1
2
3
4
cd
cd ssl
touch renew_cert.sh
vi renew_cert.sh

然后在renew_cert.sh中输入

1
2
3
4
5
#!/usr/bin/sh
python /root/ssl/acme_tiny.py --account-key /root/ssl/account.key --csr /root/ssl/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat /tmp/signed.crt intermediate.pem > /root/ssl/chained.pem
service nginx reload

定时任务可以设置为每个月执行一次:

1
0 0 1 * * /root/ssl/acme-tiny/renew_cert.sh 2>> /var/log/acme_tine.log

以上就是整个的全过程了。欢迎享受HTTPS之旅~


您是本博客的第个小伙伴