首页 IT正文

申请免费的https证书-Let's Encrypt详细教程

admin IT 2017-07-27 1030 0

f03dd00c39a8c71.jpg

背景

近来,互联网由httphttps推进的步伐越来越快,除了各大浏览器之外,搜索引擎也特别的优待https,因此想着跟上步伐把自己的网站也弄成https

想要弄成httpsssl证书是个绕不过去的坎,各大CA机构的证书都价格不菲,要找个免费又受各大浏览器信任的证书着实不易。

本来考虑StartSSL是个不错的选择,但是最近StartSSL因为自身的不规范操作遭到了各大浏览器的封杀,只能抛弃。

通过筛选之后,发现Let's Encrypt是最好的选择,唯一的缺点是证书的有效期只有3个月,不过这可以通过自动更新来解决。以下摘自网上关于Let's Encrypt的介绍:

Let's Encrypt 是免费、自动化、开放的证书签发服务。它由 ISRG(Internet Security Research Group,互联网安全研究小组)提供服务,而 ISRG 是来自于美国加利福尼亚州的一个公益组织。Let's Encrypt 得到了 Mozilla、Cisco、Akamai、Electronic Frontier Foundation 和 Chrome 等众多公司和机构的支持,发展十分迅猛。

本人对于ssl证书Let's Encrypt并没有什么研究,试用了不少号称自动化申请的脚本,但都失败,本文是在踩过坑后最终成功的步骤记录。

基本照搬于此文:https://imququ.com/post/letsencrypt-certificate.html

前提及准备工作

以下的所有操作最好都是在实际绑定域名指向的服务器上进行,因为这期间会通过域名指向进行域名的所有权验证,以及以后的证书自动更新也都会进行验证,因此这是最直接方便的选择。

操作系统

操作系统Linux,网上给的方案和脚本也都是针对linux,本人用的CentOS

配置验证的http服务

本人使用nginx,以nginx为例,其它的原理都一样。

CA 在签发 DV(Domain Validation)证书时,需要验证域名所有权。Let's Encrypt 的验证方式是在你的服务器上生成一个随机的验证文件,在创建 CSR 时通过指定的域名进行访问,如果访问成功则表明你对这个域名有控制权。

具体访问的路径为:http://www.dexcoder.com/.well-known/acme-challenge/xxxxxxxxxx

最后的部分为随机生成的验证文件,因此需要把生成随机文件的目录映射成该路径:

server{    listen       80;    server_name  www.dexcoder.com;    location ^~ /.well-known/acme-challenge/ {            alias /opt/www/dexcoder/challenges/;    }    location / {            return 301 https://$server_name$request_uri;    }}

创建帐号

新建一个ssl目录,之后所有的操作及生成的证书文件等都在该目录。

进入这个目录,创建一个 RSA 私钥用于 Let's Encrypt 识别你的身份:

openssl genrsa 4096 > account.key

创建 CSR 文件

接着就可以生成 CSR(Certificate Signing Request,证书签名请求)文件了。在这之前,还需要创建域名私钥(一定不要使用上面的账户私钥),根据证书不同类型,域名私钥也可以选择 RSA 和 ECC 两种不同类型。以下两种方式请根据实际情况二选一。

1)创建 RSA 私钥(兼容性好):

openssl genrsa 4096 > domain.key

2)创建 ECC 私钥(部分老旧操作系统、浏览器不支持。优点是证书体积小):

#secp256r1openssl ecparam -genkey -name secp256r1 | openssl ec -out domain.key#secp384r1openssl ecparam -genkey -name secp384r1 | openssl ec -out domain.key

有了私钥文件,就可以生成 CSR 文件了。在 CSR 中推荐至少把域名带 www 和不带 www 的两种情况都加进去,其它子域可以根据需要添加(目前一张证书最多可以包含 100 个域名):

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:dexcoder.com,DNS:www.dexcoder.com")) > domain.csr

执行这一步时,如果提示找不到 /etc/ssl/openssl.cnf 文件,请看看 /usr/local/openssl/ssl/openssl.cnf 是否存在。

我在执行这一步时以上两处都没有该文件,但已经安装了openssl照理说应该存在才对,使用find命令搜索:

[root@iZ28siayqz6Z ~]# find / -name openssl.cnf/etc/pki/tls/openssl.cnf

终于发现 /etc/pki/tls/openssl.cnf ,如果还是不行,也可以使用交互方式创建 CSR(需要注意 Common Name 必须为你的域名):

openssl req -new -sha256 -key domain.key -out domain.csr

获取网站证书

下载acme-tiny脚本:

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

执行脚本,指定账户私钥、CSR 以及验证目录(前面nginx配置的验证目录):

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /opt/www/dexcoder/challenges/ > ./signed.crt

报出如下错误:

Traceback (most recent call last):  File "acme_tiny.py", line 2, in <module>    import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, loggingImportError: No module named argparse

这是因为centOS本身的包都比较老旧,Python还是2.6.x版本,acme-tiny脚本需要2.7以上版本才行。

下载2.7.8,解压并编译安装:

# wget http://python.org/ftp/python/2.7.8/Python-2.7.8.tgz# tar xvf Python-2.7.8.tgz# cd Python-2.7.8# ./configure --prefix=/usr/local/python27# make && make install

这里安装到了/usr/local/python27目录,我并没有也不想改变系统默认的python版本,因此显示指定python版本执行:

/usr/local/python27/python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /opt/www/dexcoder/challenges/ > ./signed.crt

又报出:

Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "/usr/local/python27/lib/python2.7/urllib.py", line 86, in urlopen    return opener.open(url)  File "/usr/local/python27/lib/python2.7/urllib.py", line 204, in open    return self.open_unknown(fullurl, data)  File "/usr/local/python27/lib/python2.7/urllib.py", line 216, in open_unknown    raise IOError, ('url error', 'unknown url type', type)IOError: [Errno url error] unknown url type: 'https'

这是因为在编译安装python时系统中没有openssl库,安装:

sudo yum install openssl-devel

重新编译安装python:

./configure --prefix=/usr/local/python27# make && make install

再次执行脚本,成功。当前目录下生成一个 signed.crt,这就是申请好的证书文件。

如果你的域名在国外,DNS解析放在国内,这一步很可能会遇到类似这样的错误:

> ValueError: Wrote file to /home/xxx/www/challenges/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg, but couldn't download http://www.yoursite.com/.well-known/acme-challenge/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg

这是因为你的域名很可能在国外无法解析,可以找台国外 VPS 验证下。

搞定网站证书后,还要下载 Let's Encrypt 的中间证书。

在 Nginx 配置中,需要把中间证书和网站证书合在一起:

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pemcat signed.crt intermediate.pem > chained.pem

为了后续能顺利启用 OCSP Stapling,我们再把根证书和中间证书合在一起:

wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root.pemcat intermediate.pem root.pem > full_chained.pem

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

ssl_certificate     /opt/www/dexcoder/ssl/chained.pem;ssl_certificate_key /opt/www/dexcoder/ssl/domain.key;

配置nginx http 301跳转到https

其实前面验证服务中已经给出配置了:

location / {        return 301 https://$server_name$request_uri;}

证书自动更新脚本

Let's Encrypt 签发的证书只有 90 天有效期,推荐使用脚本定期更新。例如我就创建了一个 renew_cert.sh 并通过 chmod a+x renew_cert.sh 赋予执行权限。文件内容如下:

#!/bin/bashcd /home/xxx/www/ssl/python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir /home/xxx/www/challenges/ > signed.crt || exitwget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pemcat signed.crt intermediate.pem > chained.pemservice nginx reload

crontab 中使用绝对路径比较保险,crontab -e 加入以下内容:

0 0 1 * * /home/xxx/shell/renew_cert.sh >/dev/null 2>&1

这样以后证书每个月都会自动更新,一劳永逸。实际上,Let's Encrypt 官方将证书有效期定为 90 天一方面是为了更安全,更重要的是鼓励用户采用自动化部署方案。

最后

实测 Let's Encrypt 的证书在各大系统及浏览器中都没发现任何问题,兼容性还是很不错的。


本文标题:申请免费的https证书-Let's Encrypt详细教程
本文链接:https://xl.cndyun.com/post/123.html
作者授权:除特别说明外,本文由 admin 原创编译并授权 小龙的博客 刊载发布。
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031

分享:

支付宝

微信