给网站添加Let's Encrypt的免费ssl证书

概要

目前很多浏览器默认都会标记http访问的网站为不安全,https部署已经称为大趋势,我之前利用业余时间搭建了一个网站,本文就以这个域名为基础说明如何给网站加上证书。本文使用的操作系统centos、软件使用nginx、域名是bingimg.cn

什么是 Let's Encrypt

当我们要为网站加上https的访问时,我们必须申请https证书,证书的申请一般是要去有证书颁发资质的机构(CA)去申请,并且在CA申请的证书一般需要按年缴一定的维护费用,作为个人搭建的学习型网站,我们找到了一个免费的证书颁发组织,Let's Encrypt 就是一个由非营利性组织 互联网安全研究小组(ISRG)提供的免费、自动化和开放的证书颁发机构(CA)。

简单的说,借助 Let's Encrypt 颁发的证书可以为我们的网站免费启用 HTTPS(SSL/TLS) 。Let's Encrypt免费证书的签发/续签都是脚本自动化的,官方提供了几种证书的申请方式方法,点击此处 快速浏览。官方推荐使用 Certbot 客户端来签发证书,这种方式可参考文档自行尝试,不做评价。我这里直接使用第三方客户端 acme.sh 申请,据了解这种方式可能是目前 Let's Encrypt 免费证书客户端最简单、最智能的 shell 脚本,可以自动发布和续订 Let's Encrypt 中的免费证书。

为了实现自动化证书管理Let's Encryp制订了ACME 协议,这个协议是 Let's Encrypt 实现证书签发流程自动化的根本。目前ACME 协议已正式成为 IETF 标准(RFC 8555)。而acme.sh是一个第三方的脚本工具,其实现了ACME协议的内容。本文我们将使用这个工具来下载,安装,部署证书。

安装 acme.sh

首先我们需要将acme.sh工具安装在在系统上,安装很简单,一条命令:

curl https://get.acme.sh | sh

整个安装过程进行了以下几步(这是安装命令自动完成的),了解一下即可:

1. 把 acme.sh 安装到当前用户的主目录$HOME下的.acme.sh文件夹中,即~/.acme.sh/之后所有生成的证书也会放在这个目录下;

2. 创建了一个指令别名alias acme.sh=~/.acme.sh/acme.sh这样我们可以通过acme.sh命令方便快速地使用 acme.sh 脚本;

3. 自动创建cronjob定时任务, 每天 0:00 点自动检测所有的证书,如果快过期了,则会自动更新证书。

安装命令执行完毕后,执行acme.sh --version确认是否能正常使用acme.sh命令。

https://github.com/Neilpang/acme.sh
v2.7.9

如有版本信息输出则表示环境正常;如果提示命令未找到,执行source ~/.bashrc命令重载一下环境配置文件。

整个安装过程不会污染已有的系统任何功能和文件,所有的修改都限制在安装目录~/.acme.sh/中,这个脚本被安装之后,会自动往crontab中添加一条定时任务,我的机器上看到的是下面这条:

48 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

生成证书

据 acme.sh 官方文档介绍,其实现了 acme 协议支持的所有验证协议,一般有两种方式验证:http 和 dns 验证。

也就是我们有两种选择签发证书,这里我直接选择 http 验证方式,另外一种方式本篇不做介绍,可参考文档自行尝试。

签发证书也很简单,一条命令:

acme.sh --issue -d bingimg.cn -d www.bingimg.cn -w /data/bingimg/static

简单解释下这条命令涉及的几个参数:

  • --issue是 acme.sh 脚本用来颁发证书的指令;
  • -d是--domain的简称,其后面须填写已备案的域名;
  • -w是--webroot的简称,其后面须填写网站的根目录

最后一个 -w 参数其实不一定非要是网站的根目录,只不过指定的这个目录,随后acme.sh会将一个文件放到这个目录下,并且尝试去访问这个目录的这个文件,只要我们配置nginx让他能够访问到就可以,不一定非要是根目录。不过我经过上面的设置之后,报错了:

按照提示我们添加一个  --debug 选项之后继续运行这个命令,以便能看到详细的报错信息:

acme.sh --issue -d bingimg.cn -d www.bingimg.cn -w /data/bingimg/static --debug

其提示从网站根目录访问他生成的文件路径访问不到,因为我们指定的目录是 /data/bingimg/static 这个并不是网站根目录,我们只需配置一下nginx让他能够访问到这个文件即可,重新配置nginx之后再次运行上面的acme.sh命令,输出没有任何报错,知道最后成功,最后的输出如下:

生成好之后如果发现少了一个域名,需要另外在生成一个域名,因为之前已经生成过两个域名,在生成会报错,我们可以加上参数 --force 强制重新生成:

acme.sh --issue -d bingimg.cn -d www.bingimg.cn -d pc.bingimg.cn -w /data/bingimg/static --debug --force

可以看出我们加了一个域名  pc.bingimg.cn 但是报错,看报错的意思是,没有找到这个域名的dns记录,所以我们只需要在域名解析服务那里为这个域名添加一条dns记录,在重新运行上面的命令就可以了。到此证书下载成功,我们生成的证书可以给 bingimg.cn、www.bingimg.cn、pc.bingimg.cn 这3个域名使用,证书被放在  /root/.acme.sh/bingimg.cn/ 目录下。另外我们可以通过下面的命令查看和删除已经生成的证书:

# 查看证书列表
acme.sh --list 

# 删除证书
acme.sh remove <SAN_Domains>

安装证书

下面我们就将下载下来的证书安装到网站上,这里主要说明如何将证书安装到nginx上,其他 webserver 请参考 acme.sh 文档自行实践。废话不多说,进入本节正题。

 上一小节,生成的证书放在了 /root/.acme.sh/bingimg.cn 目录,因为这是 acme.sh 脚本的内部使用目录,而且目录结构可能会变化,所以我们不能让 Nginx 的配置文件直接读取该目录下的证书文件。

正确的做法就是使用 --installcert 命令,指定目标位置,然后证书文件会被 copy 到相应的位置。一条命令即可解决:

acme.sh  --installcert -d bingimg.cn  \
         --key-file /etc/nginx/certinfo/bingimg.cn.key \
         --fullchain-file /etc/nginx/certinfo/fullchain.cer \
         --reloadcmd "service nginx force-reload"

我们之前生成的证书是在目录/root/.acme.sh/bingimg.cn 下面,从上面的截图可以看到,这个目录下有4个文件,我们在生成证书的时候指定了3个域名,生成的这个证书可以被用在这3个域名上,并且生成证书的时候第一个 -d bingimg.cn 表示的是主域名,后面的是 SAN 域名。如果需要用一个证书保护多个域名的情况,有2种办法,第一种办法就是使用SAN证书,就像我们这里生成的证书一样,可以在生成证书的时候指定多个域名,其中第一个是主域名,后面的是需要被保护的SAN域名,一个SAN证书最多可以保护500个域名,这这些域名之间可以没有关系,例如 abc.com    222.com 这两个域名可以被放在一个 SAN 证书中。另一种是使用泛域名证书例如 *.abc.com 的证书可以被用来保护主域名和无数个 abc.com 的二级子域名。安装之后成功输出下面内容:

 

这里我将证书放到了/etc/nginx/certinfo/目录,这个目录本身没有,我们需要手工创建,当然也可以自行指定。

 最后一步就是,修改 Nginx 配置文件启用 ssl,修改完成后需要重启下 Nginx,这一块不再详述。Nginx 配置请参考: 

# 监听80端口,对所有 http://bingimg.cn 和 http://www.bingimg.cn 的请求都301转向到 https://www.bingimg.cn 上
server { listen 80; server_name bingimg.cn,www.bingimg.cn; return 301 https://www.bingimg.cn$request_uri; } # 监听443端口,对所有 https://bingimg.cn 的请求301转向到 https://www.bingimg.cn 上,这个不用配置ssl证书 server { listen 443 ; server_name bingimg.cn; # 这个跳转的https的server块里面不需要配置证书,不知道为什么,当请求上来之后第一步不是建立ssl连接吗,那就应该需要证书才对吧,然而确实不需要 return 301 https://www.bingimg.cn$request_uri; } # 监听443端口,接受所有 https://www.bingimg.cn 的请求 server { listen 443 default_server ssl; # 这里必须要加上 default_server server_name www.bingimg.cn; ssl on; ssl_certificate /etc/nginx/certinfo/fullchain.cer; # 这里配置上证书的路径 ssl_certificate_key /etc/nginx/certinfo/bingimg.cn.key; ..... other config ..... }

我们上面不仅仅对http的请求配置了跳转到https上,并且对bingimg.cn的https请求也跳转到www.bingimg.cn的https上,最后所有的请求都会落到www.bingimg.cn域名的https服务上,这样做首先将所有http请求跳转成https,其次讲所有bingimg.cn的请求跳转到www.bingimg.cn域名上,因为本质上这是两个不同的域名,都落到www.bingigm.cn域名上有利于SEO,另外要注意的是,上面的配置中最后一个 server 块中的listern命令需要添加  default_server 参数,否则跳转不正常,在nginx的error log 中会找到如下错误:

完成证书部署后可以通过如下站点检测网站的安全级别:

更新证书

目前 Let's Encrypt 的证书有效期是90天,时间到了会自动更新,您无需任何操作。 今后有可能会缩短这个时间, 不过都是自动的,不需要您关心。但是,您也可以手工运行命令强制续签证书:

acme.sh --renew -d example.com --force

更新 acme.sh 脚本

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步。升级 acme.sh 到最新版:

acme.sh --upgrade

如果您不想手动升级,,可以开启自动升级:

acme.sh  --upgrade  --auto-upgrade

您也可以随时关闭自动更新:

acme.sh --upgrade  --auto-upgrade  0

以下关于acme.sh的资料参考:

到此关于部署免费ssl证书到网站的记录就说完了,可以点击连接查看效果  必应壁纸|必应美图

posted @ 2021-04-16 23:30  薰衣草的旋律  阅读(1020)  评论(0编辑  收藏  举报