群晖自带的 Let's Encrypt SSL 证书续签经常抽风?试试这个:ZeroSSL

在当今信息化高速发展的社会,Https 的重要性不言而喻,所以对于我这种自己部署了很多服务并且要暴露在外网的人来说,维持自己的 ssl 证书是一件非常重要的事。

本来一年申请一次 ssl 证书,手动部署一下,我也觉得没什么,直到最近发生了这两件事:

  1. 阿里云调整免费证书的有效期,从一年缩短到了三个月(90天);
  2. 群晖使用 Let‘s Encrypt 进行自动续签服务不稳定,间歇性抽风、校验 80 端口失败等;


是时候折腾一下了

本文介绍通过 Zerossl 平台配合 acme.sh 脚本实现 Linux 服务器证书自动申请续签、自动部署的全过程,因本人在互联网查询教程期间,发现网上大部分文章均已经过时,部分官方新特性未在大部分教程中看到,遂开此文章,望帮到更多人。

如果你有网络条件、设备基础、操作能力,强烈建议你直接参考官方中文指引,毕竟这是实时更新的 wiki ,理论上是不会过期的,也是更加准确的,但如果你命令行操作能力有限,可继续看下去。

请注意文章时效(2023-12-05)。

准备工作

因为我主要是以我自己的亲身经历来讲,所以首先要介绍一下我所使用的服务所走的环境。

  • 我的域名购买自阿里云,现在已将 DNS 解析放到了 Cloudflare ;
  • 我之前的证书也是阿里云的1年免费证书,包含:根证书、中间证书、私钥;
  • 阿里云、腾讯云证书都只能提供主域名和一个子域名的证书(www),不提供免费泛域名证书;

1、一个 DNS 解析托管平台,本文以 Cloudflare 为例

你需要一个支持 Api 修改 DNS 记录的域名解析商,例如我上边提到的 Cloudflare ,创建账号,并讲你的域名迁移到这里之后,你就可以继续往下操作了。

如果你的域名解析服务商是别的平台,比如 GoDaddy、DNSPod 等,也是支持的,不需要迁移到 Cloudflare ,全部支持的列表和操作方法参考 这里(多说一句,其实阿里云也是支持的,但 Cloudflare 有太多好用的特性和功能了)。

2、拿到 Cloudflare 操作 Api 的 Key 和需要修改的域名 ID

一般这种自动化操作脚本都是需要 Key 的,因为接口需要对操作进行身份检查,防止坏人修改你的信息,Key 就是证明你身份的东西。

Global Api Key

Cloudflare 的 Globalkey 的位置可以参考这个操作步骤:【登陆】【右上角】 【Myprofile】 【Api Tokens】 【Global Api Key】 ,输入密码,复制这个Key,暂存到本地后边用。

Zone ID

Zone ID 为你的域名空间ID,加入你有多个域名,那就对应到了多个 Zone ID ,所以需要查询到指定的 Zone ID ,确保修改的是你指定的域名。

Cloudflare 的 Zone ID 可以通过这种方式查询到:【登陆,如果已登陆,就点击左上角的图标回到主页】【登录后的默认主页,点击你的域名】【进入后,查看右侧,下方】

3、使用 ssh 登录到你的主机

请确保你拥有这台主机的 root 账户权限,如果没有,也没关系,证书申请不受影响,证书安装和重启你的服务可能需要你自己想办法了。

4、在 Zerossl 创建账号

如果你由于种种原因,没办法执行下边的所有操作,你还可以回到这一步,因为在 Zerossl 官网也可以通过操作网页界面的方式申请到证书,但在网页只能申请到主域名和 www 子域名。

泛域名要么使用付费方案(付费可以延长至一年有效期),想白嫖?继续往下看。

操作步骤

1、下载 acme.sh 到主机

这一步的脚本无需 root 账号运行,普通用户即可,但使用 root 权限也是更好的。

请把下方的 my@example.com 替换为你申请域名时所填写的邮箱,不要直接复制运行!

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


群晖在这里会报错

所以群晖用户需要增加 –force 参数运行

1
curl https://get.acme.sh | sh -s email=my@example.com --force

还可以使用 wget 来运行,上边如果已经运行成功了,那就没必要再使用 wget 运行了

1
wget -O -  https://get.acme.sh | sh -s email=my@example.com --force


运行成功后截图

脚本会将 acme.sh 下载到当前用户目录下,也就是 ~/.acme.sh 目录, 可使用以下方式切换到该目录:

1
cd ~/.acme.sh

2、为域名申请一个证书

证书申请需要验证你对当前域名的所有权,通常有三种方式:80 端口、www 根目录验证、增加 DNS 记录验证

acme.sh 非常强大,还拥有 standalone 模式,即使你本地啥网络服务也没部署,他也可以自己启动 80 端口,然后临时充当你的网络服务来辅助验证,甚至还可以不使用 80 端口(当你的网络服务有反向代理端口转发的话)!

考虑到个人家庭公网 IP 会被屏蔽80端口,强烈建议此类跟我类似情况的用户使用 增加 DNS 记录验证 的方式来验证,因为这是最简单的方式!

使用增加 DNS 记录的方式申请证书
此方式需要用到上边我们预先申请好的 Cloudflare Key 和 Zone ID。

请确保当前的命令行位置是 ~/.acme.sh

为了方便,建议像我这样操作:

新建一个执行文件

1
touch fetch.sh

编辑 fetch.sh,将以下内容放到该文件中,记得修改相应的地方为你自己的内容

1
2
3
4
5
6
cd /path/to/.acme.sh
export CF_Key="替换成上边你保存的 KEY"
export CF_Email=" 替换成你申请域名的时候所填写的邮箱"
export CF_Zone_ID="替换成你的域名所在的 Zone ID"
./acme.sh --issue --dns dns_cf -d 你的域名地址 -d '*.你的域名地址'
./acme.sh --issue --dns dns_cf -d 你的域名地址 -d '*.你的域名地址'

在这行命令中:

–dns dns_cf,就是以 cloudflare dns生成的方式,通过向我们的 DNS 解析中添加一个 txt 记录来验证你对该域名的所有权,这个过程是程序自动的,你无须做任何操作,等就可以了;
-d 你的域名地址 -d ‘.你的域名地址’,这里看起来有两个【 -d 你的域名地址】,但他们作用不一样,前一个是你申请的主域名,后一个是你申请你域名的所有子域名(也可称之为泛域名),比如www.子域名,所以在替换的时候,一定记得:你只能替换 【你的域名地址】内容,其它地方都不要动,尤其是前边的 【.】 ,不要自作聪明删掉它。
编辑好之后,再给这个脚本添加执行权限

1
chmod a+x ./acme.sh

执行

1
./fetch.sh


执行结果截图

如果你跟我一样看到这个结果(主要是绿色的 Cert success),恭喜!你应该已经拿到了证书了。

开心一下,继续下一步。

3、安装证书

由于接下来这一步对服务器影响较大,而且部分操作需要 root 权限,对以下操作较为陌生的人,不要轻易运行!!!在线生产环境,不要轻易运行!!!当然,如果是在非生产环境,或者你本身就对这个操作比较熟悉,那没什么问题。

Apache 部署证书的方法

1
2
3
4
5
./acme.sh --install-cert -d 你的域名地址 \
--cert-file /path/to/certfile/in/apache/cert.pem \
--key-file /path/to/keyfile/in/apache/key.pem \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd "service apache2 force-reload"

Nginx 部署证书的方法

1
2
3
4
./acme.sh --install-cert -d 你的域名地址 \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"

群晖部署证书的方法

在网上搜索到的大部分教程,在这里都跟我讲,如果要自动部署证书到群晖,需要先这样,再那样,然后如果你 Admin 账号开了两步验证,还需要怎样怎样。听得我头皮发麻,但实际上官方的部署脚本已经升级了,所以看到这里,你们可以不用像我之前那样疑惑了。

跟上边一样,新建一个 install.sh 脚本(touch install.sh),把以下内容放到脚本里,并给脚本授予执行权限(chmod a+x ./install.sh)

1
2
3
4
5
6
7
cd /path/to/.acme.sh
export SYNO_Username='群晖管理员用户名'
export SYNO_Password='群晖管理员密码'
export SYNO_Certificate="证书名称"
export SYNO_DID='设备ID'
export SYNO_Create=1
./acme.sh --deploy --deploy-hook synology_dsm -d 你的域名地址 -d '*.你的域名地址'

关于上边的脚本,主要是设备 ID 那里,如果你没开管理员的两步验证,就无需填写,直接删除这一行即可。

用户名跟密码自不用多说,直接填;

export SYNO_Certificate=”证书名称”,【证书名称】这里替换成英文,给你新申请的证书起一个名称,比如:zerossl;

export SYNO_DID=’群晖设备ID’,【设备ID】这里,如果你开了两步验证,这里就需要一点点操作,【打开浏览器,使用管理员账号登陆你的群晖,登录的时候选择:记住这台设备】【按 F12 开启调试模式,这个时候会弹出来一个新的界面】【上方一横排菜单里,找到 Application,如果找不到,就把这个窗口拉宽一点儿】【在左侧的 Cookies 菜单点击下方的地址,右侧就会出现很多项内容,找到 ID,把右边的值复制出来,放到上方的”群晖设备ID“处替换即可】

获取设备 ID 的地方

export SYNO_Create=1,脚本会自动处理,所以不管你的证书是不是新建,都可以这么写

1
./acme.sh --deploy --deploy-hook synology_dsm -d 你的域名地址 -d '*.你的域名地址',--deploy-hook synology_dsm

这是专门针对群晖部署的方式,如果你不是群晖设备,请参考其它部署方式。

官方脚本已经提供了输入两步验证(OTP code)的输入口了

等你输入好两步验证码之后,命令行会跳出新的输入,设备名称那里可以留空,你直接回车即可,脚本会自己默认一个名称的。

官方提供了超级多的其它的自动化部署方式,本文不再一一赘述,请参考官方提供的部署方式WIKI。

4、自动化更新证书

在操作步骤第一步的时候,可以看到我的截图里有报错,其实 acme.sh 有检查自动化任务,同时也会在安装时自动部署更新脚本,60天后(证书过期前30天),自动申请延长证书。

使用其它不具备运行 crontab 系统的小伙伴(比如群晖),就需要自己到定时任务管理系统去设置一下了,但其实在上方的准备一切正常的情况下,你也只需要运行两个脚本:fetch.sh 获取下新的证书,install.sh 把证书安装到服务器即可。


群晖的任务管理设置入口

群晖系统自身带有任务管理,在任务管理里设置好脚本,我也就摆脱了手动之苦,享受全自动化带来的乐趣了~

SSL 证书的意义

老手自不用多说,SSL 是初入编程世界的新人必须要了解的一个知识,本文也是面向较为初级的编程新手,希望大家通过 SSL 证书保护好自己的隐私和数据。

其实在各个开发平台,厂商也都半强制要求了开发者所开发的 App 在调用后端接口时,必须要使用 Https 协议而非 Http 进行通信,这也是依赖于 SSL 证书的。

所以你还在等什么 ~

哦,对了,本来写这篇文章我是有点儿拖延症的,两天了一直没动,直到我打开了 testv 的官网,发现他们 https 证书居然过期了。

哈!哈!哈!

作为老粉丝,我突然就来了兴趣,干脆就通过这种方式来催 testv 更新证书好了。

希望他们看到。