如何获取 SSL/TSL 证书并自动续期

警告
本文最后更新于 2024-01-06,文中内容可能已过时。

如何获取 SSL/TSL 证书并自动续期

查看证书有效期

首先我们先来查看证书的有效期,在 Chrome 浏览器中,店家地址栏的左侧的图标,如果当前采用的是 HTTPS 协议,会有连接是安全的这个选项

点击连接是安全的,如果当前证书还未过期,则会显示证书有效

然后点击证书有效,在弹框中就可以看到证书的办法日期和截止日期,从这个有效期我们可以判断,当前使用的证书是一年期的

ACME 协议

维基百科:Automatic Certificate Management Environment - Wikipedia

协议说明:Automatic Certificate Management Environment (ACME)

现在我们一般都是通过各种 ACME 协议的客户端来获取 HTTPS 证书,在学习各种客户端之前,我们需要先了解,什么是 ACME 协议。

ACME 全名 Automatic Certificate Management Environment,是一种通信协议,用于自动化证书颁发机构(CA)与其用户的服务器之间的交互,方便用户获取 CA 颁布的证书和证书过期之后续订证书,CA 也可以通过此协议撤销证书。ACME 协议是Internet Security Research Group (ISRG) 为他们的 Let’s Encrypt服务设计的,非常好用。

ACME 协议主要通过基于 HTTPS 传递 json 格式的消息来实现服务器跟 CA 之间的交互,已作为互联网标准发布,标准规范为 RFC-8555

当前市面上有很多很好用的实现了 ACME 协议的客户端,通过这些客户端我们可以获取 CA 颁布的证书,有的客户端还支持自动续订。

技术方案参考:SSL 证书 是不是互联网新时代的人头税啊。。。。 - V2EX

  • HTML5 网页版 ACME 客户端:无需安装任何软件,纯网页实现,支持快速获取证书,但是不支持续订

  • Let’s Encrypt官方推荐的 ACME 客户端Certbot:需要额外安装snap,但是自动化程度高,支持自动续订

    snap 是在 Linux 设备上安装应用程序的一种安全且可扩展的方式。snap 是一个包含其所有依赖项的应用程序。可以在任何运行 Linux 的设备上使用单个命令安装 snap。有了 snap,软件更新是自动的和有弹性的。应用程序在它们自己的沙箱中完全隔离地运行,从而最大限度地降低了安全风险。

    跟 Docker 有点像,他俩的区别:ubuntu core - what's the main difference between Docker and Snap? - Ask Ubuntu

  • Bash 客户端 acme.sh:方案通用,灵活度高,支持自动续订

市面上用的最多的,也就是这三种客户端。接下来,我们简单实践一下。

HTML5 网页版 ACME 客户端

客户端地址:ACME Web Browser Client | ACME 客户端 H5 网页单文件版,在线免费申请签发 SSL/TLS 通配符泛域名 HTTPS 证书,支持 Let’s Encrypt、ZeroSSL,无需账号免登录注册 | Windows macOS Get Wildcard Certificates Online For Free - Single HTML File

操作方式也很简单,直接按照页面上的步骤一步一步往下走即可,

值得注意的是第三步:验证域名所有权,我们需要在我们的域名解析程序中添加一条记录来证明我们拥有这个域名。

一般我们选择 DNS 验证。然后因为我们使用的是阿里云的服务器,因此,我们需要进入 DNS 控制台,阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台,然后点击添加记录,添加一条指定的记录。

添加成功之后,回到 Web 客户端,然后点击开始验证,验证成功之后,即可下载证书,然后上传到域名对应的服务器上使用即可。非常方便

唯一不方便的是,不支持自动续订。而且证书有效期只有 30 天,需要频繁手动更换。

因此,我们需要自动续订的方案

Certbot

官网:Certbot

现在网上传播比较光的教程是是老版本的 Certbot 即 certbot-auto 的用法,比如Let’s Encrypt 使用教程,免费的 SSL 证书,让你的网站拥抱 HTTPS - Diamond-BlogLet’s Encrypt:使用 Certbot 获取免费 SSL 证书 - Linux 迷,现在 Certbot 的用法简化了很多。教程直接在Certbot官网上:

首先确定你的使用证书的场景

然后是安装 snap,Installing snap on CentOS | Snapcraft documentation

同时要保证本地不包含 certbot-auto 相关的包,然后然后通过 snapd 安装 Certbot,然后就可以获取证书了,Certbot 支持仅获取证书,和获取证书之后自动修改 Nginx 的配置文件然后应用,非常地智能。同时支持证书到期自动续订。

Certbot 虽然是 Let’s Encrypt 官方推荐的客户端,但是平时大家用的最多的,还是 acme.sh

acme.sh - 常用

官方教程:说明 · acmesh-official/acme.sh Wiki · GitHub

参考博客:acme.sh 快速实现 https 证书颁发与自动续期 - 阿里云开发者社区

安装 acme.sh

最好以 root 用户登录服务器,先安装 socat

1
yum install socat -y

然后在服务器上执行以下脚本,记得把lk@163.com换成你自己真实使用的邮箱的地址

其实普通用户和 root 用户都可以安装使用,但是最好使用 root 用户

1
curl https://get.acme.sh | sh -s email=lk@163.com

如果服务器在国内,比如阿里云,可能连不上 Github,只能从 Gitee 中下载脚本,参考教程:Install in China · acmesh-official/acme.sh Wiki · GitHub

执行以下脚本,记得把lk@163.com换成你自己真实使用的邮箱的地址

1
2
3
4
cd ~
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m lk@163.com

如果控制台提示Install cron job failed,这是因为阿里云的服务器为了保证服务器的安全,限制了所有用户,包括 root 用户对系统关键位置的修改,定时任务 crontab 相关的文件夹/var/spool/cron/就是这样的位置。

类似的问题,我们在《SSH 密钥登录》中修改~/.ssh/authorized_keys的时候也遇到过,主要是为了服务器的安全考虑而增加的限制。

此时,我们以 root 用户登录,执行crontab -e添加定时任务,然后再用crontab -l查看,你会发现都看不到,定时任务没有添加成功。

关于crontab的相关命令,请看《crond 定时任务调度》

此时我们需要执行以下命令,赋予权限

参考博客:linux no crontab for root - using an empty one Permission denied-CSDN 博客

1
chattr -ai /var/spool/cron/

然后再安装一次,记得把lk@163.com换成你自己真实使用的邮箱的地址

1
2
cd ~/acme.sh
./acme.sh --install -m lk@163.com

输出

安装成功,记得把/var/spool/cron/的权限恢复回来

1
chattr +ia /var/spool/cron/

上面安装的脚本主要做了两件事,

  1. 把 acme.sh 安装到当前登录用户的 home 目录~/.acme.sh/下,并创建 一个 shell 的 alias 别名,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

  2. 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书,如果快过期了,需要更新,则会自动更新证书。

申请服务器操作密钥

我们在HTML5网页版ACME客户端曾经手动操作过,在阿里云的 DNS 解析服务那里手动添加一条 DNS 解析结果来证明这个域名是我们的,但是每次都手动操作的话就没法自动续订了,因此,为了实现自动添加这样一条帮助验证的 DNS 记录,我们需要添加一个用户,这个用户可以通过密钥登录,然后添加 DNS 解析记录。

dnsapi · acmesh-official/acme.sh Wiki · GitHub中第 11 条Use Aliyun domain API to automatically issue cert教我们如何创建 RAM 用户,点击阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台,点击创建用户

勾选 OpenAPI,点击确定,然后就会在列表中看到创建的用户对应的一行记录,复制这样记录中的 key 和 secret,以备后用。

然后回到用户列表

点击操作列的添加权限,把 DNS 相关的权限都选上,然后点击确定。

其实这个之前使用阿里云 OSS 的时候也创建过 RAM 用户,具体请看《图床》的直接使用阿里云的 OOS小节

申请证书

将阿里云 RAM 用户的 key 和 secret 设置成环境变量

1
2
export Ali_Key="<key>"
export Ali_Secret="<secret>"

然后开始获取证书

1
2
cd ~/acme.sh
./acme.sh --issue --dns dns_ali -d xiashuo.xyz -d *.xiashuo.xyz

最终输出以下日志,则表示证书生成成功

可以看到证书都生成到了~/.acme.sh/xiashuo.xyz/路径下

copy/安装证书

前面证书生成以后,接下来需要把证书 copy 到真正需要用它的地方。

注意,默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,例如:不要直接让 nginx/apache 的配置文件使用这下面的文件,这里面的文件都是内部使用,而且目录结构可能会变化。

正确的使用方法是使用 --install-cert 命令,并指定目标位置,然后证书文件会被 copy 到相应的位置。

我本地是通过 Nginx 来使用证书,对 Nginx 来说,证书放哪里都可以,配置好位置即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
http {
    ......
    server {

        # 对外以 443 提供 HTTPS 服务
        listen       443 ssl ;
        listen       [::]:443 ssl ;
        server_name  _;

        #  证书地址
        ssl_certificate "/etc/host_ssl/xiashuo.xyz.pem";
        ssl_certificate_key "/etc/host_ssl/xiashuo.xyz.key";
        #  SSL 配置
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;

        location / {
            # 被代理的,原本的 HTTP 服务
            proxy_pass http://localhost:90;
        }
    }

}

证书的安装方式也非常简单。通过--key-file--fullchain-file指定文证书的目标位置,系统会自动选择合适的文件复制过去。比如我本地 Nginx 使用的是/etc/host_ssl/路径下的证书,--reloadcmd的作用是证书更新之后,重启 Nginx,应用新的证书。

我们申请下来的证书的拓展名可能是.cer,但是我们希望的格式是.pem,没关系,本质上是互通的,参考博客:SSL证书、 der、 cer、 pem、x.509区别_cer证书和pem证书-CSDN博客

1
acme.sh --install-cert -d xiashuo.xyz --key-file  /etc/host_ssl/xiashuo.xyz.key   --fullchain-file /etc/host_ssl/xiashuo.xyz.pem  --reloadcmd    "service nginx force-reload"

以下这个脚本除了安装证书外,也添加了一个自动更新的任务,一般来说,60 天以后会自动更新,并会强制重启 nginx 使新的证书生效,可以通过 crontab -l看到对应的定时任务

1
2
# crontab -l
17 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null   

安装完证书之后,访问https://xiashuo.xyz,按照查看证书有效期小节的步骤,看到下图,表示成功了,

查看已安装证书信息

通过以下命令可查看已安装的证书

1
acme.sh --info -d xiashuo.xyz

总结

acme.sh这种方式只会更新证书,而且提供了--reloadcmd参数在更新证书之后重启使用证书的应用,这种设计是非常通用的,非常好用,其实不推荐 Certbot 这种由 Certbot 去修改 Nginx 配置文件这种方式,因为配置文件的写法千变万化,由客户自己去维护是最好的,acme 客户端应该只需要更新证书文件即可。

0%