ACME 是什么
acme.sh 是一款可以为我们的服务自动申请 SSL 证书的工具。传统方式申请证书的流程一般如下:
- 在网站(比如:freessl.cn/)申请。
- 到域名服务商添加 DNS 解析,或在自己服务器上放校验文件。
- 等待 SSL 签发商(比如:Let's Encrypt 与 TrustAsia)验证,一般半小时内验证完成。
- 下载证书并部署到自己的服务器上。
证书一般是几个月或一年有效期,每次都手动搞一下也挺烦。而且如果有多个子域名操作就更多了,自动工具可以帮你定期做这些事情。
部署
直接安装
可以将工具直接安装在服务器上,个人觉得这样很麻烦,需要装依赖的包还对服务器造成了“污染”。有兴趣的可以了解一下 github.com/acmesh-offi…
Docker 安装
安装并运行neilpang/acme.sh
镜像,这里是以daemon
方式安装,这样,就可以像运行一个命令一样使用 acme.sh 了。
下面的例子是以 Namesilo
为DNS服务商,采用DNS验证的方式:
docker run --rm -itd \
-v "$(pwd)/out":/acme.sh \ # 最终的产物将放在这里
-e Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxxx" \ # 在Namesilo后台创建的api key
--net=host \
--name=acme.sh \
neilpang/acme.sh daemon
-
最重要的是
-e Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxxx"
这一行,不同的服务商对应环境变量的key和数量都不一样,具体支持的列表在这里 -
这个
Namesilo_Key
值从哪里来呢,从各个厂商的管理后来创建,我这里以Namesilo
为例。
运行
申请
先运行下面这个命令,意思是提出申请,具体注释也写上了。
docker exec acme.sh \
--issue \
--dns dns_namesilo \ # 指定DNS服务商
--dnssleep 1800 \ # 1800s 后到域名提供商验证txt_name
-d wanghl.cc \ # 需要申请的域名
-d www.wanghl.cc \ # 需要申请的域名
-d qingdu.wanghl.cc \ # 需要申请的域名
-d lib.wanghl.cc \ # 需要申请的域名
-d media.wanghl.cc \ # 需要申请的域名
--server letsencrypt \ # 从 letsencrypt 申请证书
--yes-I-know-dns-manual-mode-enough-go-ahead-please
dns_namesilo
表示你用的是哪家域名提供商,具体支持列表还是在这里,例如下图:-d
表示需要申请证书的域名,可以一次加入多个。--server
表示从哪个申请证书,letsencrypt
简单一些,如果不加这一行,默认会从ZeroSSL.com CA申请。需要注意的是,如果你从ZeroSSL.com CA申请,需要更多信息,本套教程对你来说就不完整了。
RENEW
上面的命令执行完以后,可以用下面的命令生成证书,你可以理解为轮询结果。
docker exec acme.sh \
--renew \
--dns dns_namesilo \ # 指定DNS服务商
--dnssleep 1800 \
-d wanghl.cc \ # 需要申请的域名
-d www.wanghl.cc \ # 需要申请的域名
-d qingdu.wanghl.cc \ # 需要申请的域名
-d lib.wanghl.cc \ # 需要申请的域名
-d media.wanghl.cc \ # 需要申请的域名
--server letsencrypt \ # 从 letsencrypt 申请证书
--log \ # 输出日志文件
--yes-I-know-dns-manual-mode-enough-go-ahead-please
这个命令看上去跟上面的很像,值得注意的参数有下面几个:
-renew
: 把上面命令中的--issue
换成了这个,表示刷新证书有效期。--dnssleep
:表示多长时间轮询一次,DNS生效需要时间,一般在半小时(1800s)以内,你也可以设小一点。--log
生成日志文件,不管成功/失败,你都可以在日志中看到详细信息。比如脚本做了哪些事、报了什么错,建议加上。
如果DNS验证没有通过,也就是DNS还没有生效,脚本会卡住,在--dnssleep
后再次轮询,直到成功。成功截图如下:
正如上图中显示的,会在out
目录生成几个文件。对我来说有用的文件有两个fullchan.cer
和wanghl.cc.key
KONG 中更新证书
我是用KONG
做的网关,这里顺带也说一下操作方法,其他的比如 Nginx / Apache 操作方法自行google了。
自动部署证书
上面一步更新证书文件也是可以自动化的,具体没有研究了,可以看这里
相当于帮你把证书放到指定的地方,再帮你重启一下Nginx。
自动部署到kong
可以把 fullchan.cer
和wanghl.cc.key
两个文件拷到 kong
的 ssl 目录里。
下面是我kong的一段docker-compose
,KONG_SSL_CERT 和 KONG_SSL_CERT_KEY 两个环境变量指向kong的默认证书。
kong:
image: kong
container_name: kong
volumes:
- "./ssl:/mnt/ssl"
environment:
- LC_CTYPE=en_US.UTF-8
- LC_ALL=en_US.UTF-8
- KONG_DATABASE=postgres
- KONG_PG_HOST=kong-database
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=xxxxxxxxxxxxxxxxxxx
- KONG_CASSANDRA_CONTACT_POINTS=kong-database
- KONG_PROXY_ACCESS_LOG=/dev/stdout
- KONG_ADMIN_ACCESS_LOG=/dev/stdout
- KONG_PROXY_ERROR_LOG=/dev/stderr
- KONG_ADMIN_ERROR_LOG=/dev/stderr
- KONG_SSL_CERT=/mnt/ssl/fullchain.cer
- KONG_SSL_CERT_KEY=/mnt/ssl/wanghl.cc.key
- KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl
我把上面**运行
** 章节中的所有操作写在了一个shell中,现在我在这个shell中加如下操作:
# 复制证书到kong
cp -r ./out/wanghl.cc_ecc/fullchain.cer ./out/wanghl.cc_ecc/wanghl.cc.key ../kong/ssl
# 加可读权限
chmod a+r ../kong/ssl/wanghl.cc.key
# 重启kong
docker compose -f ../kong/docker-compose.yml restart
至此,可以实现自动化更新SSL证书了。当然想要全自动的话,再加一个定时任务就行了,定时任务可以用Cronicle,看我这篇。