acme.sh 是一个通过 ACME 协议从 Let’s Encrypt 和 ZeroSSL 等 CA 机构申请免费的证书的 Linux 脚本
本文将介绍使用 acme.sh
配置自动续签的 SSL
证书。基本上大多数商业 SSL
证书都需要手工申请和签发,能支持 ACME
自动签发的并不多,有也略贵,比如 ZeroSSL
高级版 和 Digicert
等,那么对于大多数懒人来说,免费的 Let's Encrypt
、 Buypass
和 ZeroSSL
免费版就是不错的选择。
自动签发和手工签发证书的对比
功能 | 自动签发 | 手工签发 |
---|---|---|
有效期 | 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 证书链 | 否 | 否 | 有 | 未知 | 无 |
客户支持 | 社区 | 收费 | 收费 | 收费 | 收费 |
使用 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
的提示
然后我们可以安装证书
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 resta
对应的 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
:
然后选择 Edit Zone DNS
的模板
选择你要编辑的域名,也可以加入你服务器的 IP
作为白名单
完成后会给你一串字符,把他复制下来,需要填入下方的 CF_Token
参数
然后进入域名的管理页面,在右侧 API 列找到 Account ID
和 Zone ID
并复制
接着在终端运行
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
,篇幅有限,我们之后再介绍。