acme.sh 简介

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.

安装 Docker

参考:Centos7 安装 Docker

创建 acme.sh 容器

docker run -itd  \
--net=host \
-v /usr/local/ssl/acme.sh:/acme.sh  \
--name=acme.sh \
-v /var/run/docker.sock:/var/run/docker.sock \
neilpang/acme.sh daemon

证书文件会生成到 /usr/local/ssl/acme.sh 中,避免配置信息以及证书的丢失
将 docker.sock 文件映射到 acme.sh 容器中,是为了acme.sh 能够操作 Docker 以便将证书发布到其它容器中,如 Nginx

阿里云自动验证 DNS 生成

  1. 准备一个子账号,用于访问阿里云 DNS 服务
    添加地址

  2. 获取 AccessKey ID 和 AccessKeySecret

  3. 设置 DNS 管理权限
    授权地址

  4. 生成 ssl 证书

docker exec -it \
-e Ali_Key="your key"\
-e Ali_Secret="your secret" \
acme.sh --issue --dns dns_ali -d yourdomain.com \
-d *.yourdomain.com

Cloudflare 自动验证 DNS 生成

  1. 获取 Account ID
    在域名的主页(有折线图的页面),往下找

  2. 创建 Api Token
    My Profile -> Api Tokens

创建完成的页面获取,必须马上记录下来,后面不会再显示,否则只能重置

  1. 生成 ssl 证书
docker exec -it \
-e CF_Token="your token"\
-e CF_Account_ID="your account id" \
acme.sh --issue --dns dns_cf -d yourdomain.com \
-d *.yourdomain.com

将证书发布到 Nginx Docker 容器中

  1. 创建 Nginx 的容器的时候需要设置一个标签
    例如:
docker run  -it -d -p 80:80  --label=yourdomian.com   nginx
  1. 将证书发布到容器中
docker  exec \
-e DEPLOY_DOCKER_CONTAINER_LABEL=yourdomian.com \
-e DEPLOY_DOCKER_CONTAINER_KEY_FILE=/etc/nginx/ssl/yourdomian.com/key.pem \
-e DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/yourdomian.com/cert.pem" \
-e DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/yourdomian.com/ca.pem" \ 
-e DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/yourdomian.com/full.pem" \
-e DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" \
acme.sh --deploy -d example.com  --deploy-hook docker

使用测试服

letsencrypt 正式服是有速录限制的详见,如果第一次用,建议使用测试服

使用方式:
添加 --test 或者 --staging 参数

更新通知

这里使用 iftttWebHooks 来触发邮件发送,更多通知方式参考:acme.sh notify

注意

如果你有域名 yourdomain1.com yourdomain2.com 在两个不同的阿里云账号中,你又需要在一台服务器中生成两个域名的证书,只有最后一个生成的域名会自动续签成功,原因在于 acme.sh 目录下只有一个账号信息配置文件

AUTO_UPGRADE='1'
SAVED_Ali_Key='your key'
SAVED_Ali_Secret='your secret'
USER_PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'

后生成证书的账号就会覆盖之前的账号,如果两个域名在不同的服务商下,一个在阿里云,一个在 Cloudflare 就不会有问题,

解决方案:

  1. 自己手动创建 account.conf 文件,让账号配置到两个文件中,但是默认的定时任务不知道新的 account.conf 文件的存在,必须再添加一个定时任务,并指定 account.conf 文件
24 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --config-home "/acme.sh" --accountconf "/acme.sh/account-new.conf"

虽然最终都能续签成功,每次定时任务都有失败的情况

  1. 也可以创建多个容器来实现,会避免有失败的情况,但是会多消耗资源

以上方案均来自 acme.sh issues 本人未使用或测试

写的不好,仅供参考