自动签SSL证书

一些互联网安全研究小组领导开发了一种自动签发证书的协议,ACME。所有兼容 ACME 协议的客户端和 CA 服务器都可相互协商签发数字证书,方便了加密流量的普及。acme.sh 是一个兼容该协议的脚本工具,支持 DNS 验证模式、无需根账号权限。

安装脚本

由于 acme.sh 宣称无需的 root/sudo 权限,因此我打算单独给它创建一个低级的系统账号。

创建账号

我创建了一个新的账号,取名 acme。该账号无需密码,不可登录,只能读写特定的账号目录 /home/acme。

创建账号 acme
1
useradd -m acme -s /usr/sbin/nologin

为了方便切换账号,你可以在常用的账号下面新建一个快捷指令 alias acme='sudo su - acme -s /bin/bash' 附加到 ~/.bashrc 配置文件,以后只需要输入 acme 就可以快速切换到 acme.sh 的运行环境。

还是要给点 sudo 权限

刚刚创建的 acme 账号还无法用来重载 Nginx 的数字证书。打开 sudo visudo 编辑配置文件,将这个能力加到配置里。

/etc/sudoers
1
2
acme ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx.service
acme ALL=(ALL) NOPASSWD: /usr/sbin/nginx -t

这样一来 acme.sh 无需密码也能执行 sudo nginx -t && sudo systemctl restart nginx.service,这个到后面更新证书时会有用。

安装 acme.sh

关于 DNS API 和 DNS alias

我的最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 在环境中导入 CloudFalre API Token
export CF_Token="<Your CloudFlare API Token>"
export CF_Account_ID="<Your CloudFlare Account ID>"
export CF_Zone_ID="<Your CloudFlare Zone ID>"

# 使用 DNS API + DNS alias 模式申请泛域名
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com' \
--challenge-alias example.net

mkdir -p /home/acme/ssl

# 将证书安装到指定目录,安装完成后不要忘记重启 Web 服务器
acme.sh --install-cert -d example.com \
--key-file /home/acme/ssl/example.com.key \
--fullchain-file /home/acme/ssl/example.com.crt \
--reloadcmd "sudo nginx -t && sudo systemctl restart nginx.service"

比较 Certbot 和 acme.sh

Certbot 是 EFF 开发的工具,Let's Encrypt 推荐的也是这个,依赖 Python 和 root 权限工作,插件比较少,操作有点复杂。

acme.sh 是第三方工具,现在已被 ZeroSSL 收购,主推他们的数字证书,仍然可以签发 Let's Encrypt 和其他厂家的证书。操作起来简单,支持的 DNS 厂家最多,功能也完整。

参考阅读