acme.sh 申请 ssl 域名证书

单独以 docker 守护进程运行 acme.sh 程序

/localhost/out 生成的原始证书的目录

/localhost/ssl 通过 acme.sh --install-cert 复制和转换证书格式后存放的目录(nginx 配置文件引用的 ssl 证书目录) 比如:/localhost/ssl/abc.com

/localhost/web 存放网站页面的目录,比如:/localhost/web/abc.com 存放的是网站 abc.com 的页面文件, 申请证书时会在容器中生成 /container/web/abc.com/.well-known/acme-challenge/xxxxxx 文件,所以宿主机与容器web目录要映射

1
2
3
4
5
6
7
docker run --rm -itd \
 -v /localhost/out:/acme.sh \
-v /localhost/ssl:/container/ssl \
-v /localhost/web:/container/web \
--net=host \
--name=tacme \
neilpang/acme.sh daemon

测试 acme.sh 是否正常运行

1
2
3
4
docker exec tacme acme.sh -v
#返回如下内容
#https://github.com/acmesh-official/acme.sh
#v3.0.8

绑定一个邮箱,不然会提示无法生成证书

acme.sh 默认是使用 zerossl 颁布证书,需要绑定邮箱。

如果切换成使用 letsencrypt 颁布证书就不需要绑定邮箱。

绑定邮箱后,申请的证书记录可以在web页面 https://app.zerossl.com/certificates/issued 查看

1
docker exec tacme acme.sh --register-account -m abc@qq.com

申请ssl证书

方式1 --standalone 模式

如果80端口被占用,在 --standalone 模式下要指定另外的端口 --httpport 81

这里申请的是 顶级域名 abc.com 和 二级域名 www.abc.com 的多域名证书

适用于nginx中配置 https://abc.com 顶级域名跳转到 https://www.abc.com 二级域名

1
2
3
4
5
docker exec tacme acme.sh --issue \
-d abc.com \
-d www.abc.com \
--standalone \
--httpport 81

方式2 -w /container/web/abc.com 指定容器web页路径

如果出现超时Timeout或者404找不到https://www.abc.com/.well-known/acme-challenge/xxxxxx 文件,很有可能就是宿主机web根目录没有映射到容器中, 比如:/localhost/web:/container/web

需要你指定 -w /container/web/abc.com 容器web路径

1
2
3
4
5
docker exec tacme acme.sh --issue \
-d abc.com \
-d www.abc.com \
-w /container/web/abc.com \
--keylength ec-256

--keylength ec-256 #缺省项,指定证书使用的ECC算法,可选值还有 ec-384, ECC 比 RSA 更好。

运行成功之后会生成一个以域名开头的文件夹 /acme.sh/abc.com_ecc 其中放置着ssl各种证书。

方式3 生成泛域名证书

先申请ak,推荐aliyun(最安全的做法是创建ram子用户,给此用户仅添加“管理阿里云解析dns权限”)
https://ak-console.aliyun.com/#/accesskey
https://ram.console.aliyun.com/manage/ak

配置环境变量,供后续执行的程序使用

1
2
3
#export 可新增,修改或删除环境变量
export Ali_Key="LTdxxxKvtP"
export Ali_Secret="gabUA2xxxxxXT0ehIb9j"

执行生成通配符域名证书

1
2
3
4
docker exec tacme acme.sh --issue \
--dns dns_ali \
-d abc.com \
-d '*.abc.com'

证书生成成功之后,Ali_Key/Ali_Secret 会自动保存在 /acme.sh/account.conf 文件中

复制和转换证书格式并保存到指定目录

/container/ssl/abc.com/此目录必须已经存在

1
2
3
4
5
6
docker exec tacme acme.sh --install-cert \
-d abc.com \
--key-file /container/ssl/abc.com/key.pem \
--fullchain-file /container/ssl/abc.com/fullchain.pem \
--cert-file /container/ssl/abc.com/cert.pem \
--ca-file /container/ssl/abc.com/ca.pem

-d abc.com 表示转换 abc.com 域名的证书,会在/acme.sh/目录下匹配存放此域名证书的文件夹,比如:abc.com_ecc

切换默认证书申请服务器 zerossl 或 letsencrypt

1
2
docker exec tacme acme.sh --set-default-ca --server letsencrypt
docker exec tacme acme.sh --set-default-ca --server zerossl

在容器中设置定时任务 crontab -e

--cron 运行 cron 作业来更新所有证书

--home "/root/.acme.sh" acme.sh 程序文件所在的目录

--config-home "/acme.sh" 存放acme.sh生成的证书及配置文件目录

> /dev/null 2>&1 表示程序执行过程中不打印信息(抛弃正常信息和错误信息)

1
0 2 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --config-home "/acme.sh" > /dev/null 2>&1

表求在每天的2点,检查证书,如果快过期了,一般是3个月,会在第2个月进行证书更新。

执行以下命令行,查看证书下次更新时间

1
2
#在宿主机执行
docker exec tacme acme.sh --info -d abc.com

返回如下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Wed May 29 19:20:40 UTC 2024] The domain 'abc.com' seems to have a ECC cert already, lets use ecc cert.
DOMAIN_CONF=/acme.sh/abc.com_ecc/abc.com.conf
Le_Domain='abc.com'
Le_Alt='www.abc.com'
Le_Webroot='/container/web/abc.com'
Le_PreHook=''
Le_PostHook=''
Le_RenewHook=''
Le_API='https://acme-v02.api.letsencrypt.org/directory'
Le_HTTPPort='88'
Le_Keylength='ec-256'
Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1635883427/273571115052'
Le_LinkOrder='https://acme-v02.api.letsencrypt.org/acme/order/1635883427/273571115052'
Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/04602e68b39b9fa0f98b4c6f8f7cf41462f0'
Le_CertCreateTime='1716969431'
Le_CertCreateTimeStr='2024-05-29T07:57:11Z'
Le_NextRenewTimeStr='2024-07-27T07:57:11Z'
Le_NextRenewTime='1722067031'
Le_RealCertPath='/container/ssl/abc.com/cert.pem'
Le_RealCACertPath='/container/ssl/abc.com/ca.pem'
Le_RealKeyPath='/container/ssl/abc.com/key.pem'
Le_ReloadCmd=''
Le_RealFullChainPath='/container/ssl/abc.com/fullchain.pem'

acme.sh 其它命令

详见:https://github.com/acmesh-official/acme.sh
查看帮助

1
acme.sh -h

查看所有证书生成列表

1
acme.sh --list

强制重新生成指定证书

1
acme.sh --renew --force -d abc.com -d www.abc.com

强制重新生成所有证书

1
acme.sh --renew-all --force

删除域名更新

1
acme.sh --remove -d www.abc.com

查看域名配置

1
acme.sh --info -d abc.com