烧饼博客

使用 acme.sh 配置自动续签 SSL 证书

本文将介绍使用 acme.sh 配置自动续签的 SSL 证书。

之前介绍了 NginxApache 手工配置 SSL 证书的方法,美中不足的是,基本上大多数商业 SSL 证书都需要手工申请和签发,能支持 ACME 自动签发的并不多,有也略贵,比如 ZeroSSL 高级版Digicert 等,那么对于大多数懒人来说,免费的 Let's EncryptBuypassZeroSSL 免费版就是不错的选择。

自动签发和手工签发证书的对比

功能 自动签发 手工签发
有效期 3 个月至 6 个月 30 天到 1 年
难度 不容易 容易
友好度 不友好 友好
适合懒人
系统集成 方便 不方便
后台管理 大多数没有 大多数都有

所以我们建议如果您对服务器有完全控制权,那么自动签发的证书比较适合懒人运维,如果是长期运营的网站和项目,手工签发的证书对新手更友好,请自行选择。

安装 acme.sh

acme.sh 是一个集成了 ACME 客户端协议的 Bash 脚本,作者是 @neilpangxa,按照官方文档说明,我们直接在 Linux 下安装。

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

如果是国内的机器,可以使用拖回源码直接安装:

git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install -m username@example.com

请注意替换 username@example.com 为你自己的邮箱,避免无法收到上游证书的邮件通知,比如 Let's Encrypt 偶尔会错发证书,然后就会邮件通知你,这时候就需要重新签发一次证书了。

安装完成后重新加载 Bash:

source ~/.bashrc

然后也可以开启自动更新:

acme.sh --upgrade --auto-upgrade

选择默认 CA

目前 acme.sh 支持四个正式环境 CA,分别是 Let's Encrypt、Buypass、ZeroSSL 和 SSL.com,默认使用 ZeroSSL,如果需要更换可以使用如下命令:

切换 Let's Encrypt

acme.sh --set-default-ca --server letsencrypt

切换 Buypass

acme.sh --set-default-ca --server buypass

切换 ZeroSSL

acme.sh --set-default-ca --server zerossl

切换 SSL.com

acme.sh --set-default-ca --server ssl.com

切换 Google Public CA

acme.sh --set-default-ca --server google

如果已有 ZeroSSL 帐号,可以在后台控制面板拿到 API Key,然后执行如下命令

apt install jq
curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=你的API_Key" | jq

终端会输出如下内容

{
  "success": true,
  "eab_kid": "kid字符串",
  "eab_hmac_key": "hmac_key字符串",
}

然后手工添加帐号

acme.sh --register-account  --server zerossl \
        --eab-kid kid字符串  \
        --eab-hmac-key hmac_key字符串

Google Public CA 需要按照官方博客申请内测,然后获取 Key。

几个 CA 的简单对比

功能 LE Buypass ZeroSSL SSL.com Google Public CA
有效期 90 天 180 天 90 天 90 天 90 天
多域名 支持 支持,最多 5 个 支持 收费支持 支持
泛域名 支持 不支持 支持 收费支持 支持
Rate Limit 收费无 未知
GUI 管理
ECC 证书链 未知
客户支持 社区 收费 收费 收费 收费

简单来说,如果没有特殊需求,可以选择 Let's Encrypt,如果服务器在国内,可以选择 ZeroSSL 或 Buypass,如果愿意付费得到更好的服务和保障,可以选择 ZeroSSL 和 SSL.com,如果面向欧盟用户,可以选择 Buypass 和 ZeroSSL。

注意:经过测试 Google Public CA 的 ACME 验证域名在国内是无法访问的,只有国外服务器才可以申请,申请完成后的证书并无影响。

使用 HTTP 验证签发证书

首先我们要做一下准备工作,假设你域名是 example.com,解析到你的服务器让其生效后,我们建立一个目录:

mkdir -p /var/www/letsencrypt

我们的目的是绑定 http://example.com/.well-known/acme-challenge 到这个目录。

如果您用的 Nginx,那么新建一个配置文件:

server {
	listen 80;
	listen [::]:80;
	server_name example.com;

	location /.well-known/acme-challenge {
		root /var/www/letsencrypt;
	}

	location / {
		rewrite	^/(.*)$ https://$host/$1 permanent;
	}
}

如果您使用的 Apache,那么新建一个配置文件:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/letsencrypt
    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

我们以 Let's Encrypt 为例,直接在终端运行

acme.sh --issue -d example.com -w /var/www/letsencrypt

如果希望签发 ECC 证书,则运行

acme.sh --issue -d example.com --keylength ec-256 -w /var/www/letsencrypt

如果需要多个域名,则运行

acme.sh --issue -d example.com -d example.org -w /var/www/letsencrypt

然后就等他执行完,直到出现 Cert success 的提示

image.png

然后我们可以安装证书

Nginx

acme.sh --install-cert -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file        /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd     "systemctl restart nginx"

对应的 Nginx 配置指定证书文件

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com.ca.crt;

Apache

acme.sh --install-cert -d example.com \
--key-file       /etc/apache2/ssl/example.com.key  \
--fullchain-file /etc/apache2/ssl/example.com.crt \
--ca-file        /etc/apache2/ssl/example.com.ca.crt \
--reloadcmd     "curl https://ssl-config.mozilla.org/ffdhe2048.txt >> /etc/apache2/ssl/example.com.crt && systemctl restart apache2"

对应的 Apache 配置指定证书文件

SSLCertificateFile      /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile   /etc/apache2/ssl/example.com.key

如果是 ECC 证书,则安装的时候需要带上 --ecc 参数,比如

acme.sh --install-cert --ecc -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file        /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd     "systemctl restart nginx"

注意如果是多个域名,也仅需要在 -d 参数后面指定第一个域名即可。

使用 DNS 验证签发证书

有时候因为不想暴露一些二级域名,或者希望在多台机器上部署同一个域名的证书,这时候就需要用到 DNS 插件了,acme.sh 支持几十种 DNS 插件。

这里以 Cloudflare 为例,登录 Cloudflare Dash 后在 API Token 菜单里添加一个 API Token:

image.png

然后选择 Edit Zone DNS 的模板

image.png

选择你要编辑的域名,也可以加入你服务器的 IP 作为白名单

image.png

完成后会给你一串字符,把他复制下来,需要填入下方的 CF_Token 参数

image.png

然后进入域名的管理页面,在右侧 API 列找到 Account IDZone ID 并复制

image.png

接着在终端运行

export CF_Token="复制下来的 Token"
export CF_Account_ID="复制下来的 Account ID"
export CF_Zone_ID="复制下来的 Zone ID"

然后开启 acme.sh 的 DNS API 模式申请证书

acme.sh --issue --dns dns_cf -d example.com -d *.example.com

安装证书方法同上,另外吐槽下,很多教程会让你用 Cloudflare 的全局 Global API Key,真的是,风险太大了,最后怎么被黑的都不知道 = =

如果不想使用第三方的 DNS 服务完全可以自建 acme-dns 或者 PowerDNS,篇幅有限,我们之后再介绍。

使用 acme.sh 配置自动续签 SSL 证书
无责任编辑
Showfom
发布时间
Feb 3rd, 2022
版权协议
人過留名,雁過留聲,翺翔的飛鳥總會尋到屬於自己的領地
記得,要讓簡樸而純粹的心靜靜地感受,你要相信,美好的世界總會自己尋路向你走來