使用 acme.sh 签发免费的通配符 SSL 证书
网站启用 HTTPS 可以应对运营商的「HTTP 劫持」,避免被插入广告。大多数情况,使用免费的「SSL 证书」就足够了。
推荐的 CA 及签发工具
ZeroSSL、Let’s Encrypt 是两个常见的 CA(证书授权机构)。最大的特点是,提供免费的 SSL 证书,有效期为 90 天。有以下优点:
- 支持 Wildcard Certificates (通配符证书,类似 *.example.com )
- 支持 ECC 证书(同等安全下,ECC 证书比 RSA 体积小)
- 可以通过 API 直接签发,不用手动申请。
推荐使用 acme.sh 作为证书签发工具。它支持 ACME v2,纯 shell 实现,无其它依赖,Linux / BSD 都可以使用。
安装 acme.sh
curl https://get.acme.sh | sh -s email=[email protected]
有些 Linux 发行版默认没有安装 cron,导致安装无法完成。像 Alpine Linux、Arch Linux 之类的,可以安装 cronie, 再执行一次上方的脚本。
脚本会做 3 件事情:
- 复制 acme.sh 到
~/.acme.sh/
。 - 创建 alias :
acme.sh=~/.acme.sh/acme.sh
。 - 创建每日执行的 cronjob 。
配置 acme.sh
Wildcard Certificate(通配符证书)要求必须使用域名验证。acme.sh 支持几十个 DNS 服务商的 API。这里以「Cloudflare DNS」举例。
编辑 ~/.acme.sh/account.conf
,加入 Cloudflare DNS 的 API Key 及 email。
ACCOUNT_EMAIL="[email protected]"
export CF_Key="My Cloudflare API Key"
export CF_Email="[email protected]"
Cloudflare API Key 详见:“Profile - Global API Key - View API Key”。其它 DNS 配置参考 How to use DNS API。
签发证书
acme.sh --issue -d example.com -d '*.example.com' -k ec-256 --dns dns_cf --dnssleep 60
参数说明:
--issue
:签发证书。-d
:后面跟域名,通配符域名需要加单引号。example.com
: 要签发证书的域名,替换成你自己的。-k ec-256
:签发 ECC 证书(-k
等于--keylength
)。--dns dns_cf
:表示使用 Cloudflare DNS API。--dnssleep 60
:dns 更新后,等待 60 秒。
因为签发的是 ecc 证书,生成的证书文件夹是 example.com_ecc 。
签发成功后会有以下类似提示:
Your cert is in /PATH/.acme.sh/example.com_ecc/examplecom.cer
Your cert key is in /PATH/.acme.sh/example.com_ecc/example.com.key
The intermediate CA cert is in /PATH/.acme.sh/example.com_ecc/ca.cer
And the full chain certs is there: /PATH/.acme.sh/example.com_ecc/fullchain.cer
安装证书
修改服务器的配置,指定证书路径。
# Caddy Server
tls /srv/ssl/example.com_fullchain.cer /srv/ssl/example.com.key
# nginx
ssl_certificate /srv/ssl/example.com_fullchain.cer;
ssl_certificate_key /srv/ssl/example.com.key;
acme.sh --install-cert \
-d example.com --ecc \
--key-file /srv/ssl/example.com.key \
--fullchain-file /srv/ssl/example.com_fullchain.cer \
--reloadcmd "rc-service caddy reload"
参数说明:
--install-cert
:安装证书,把证书文件复制到相应的目录。-d
:指定域名。--ecc
:ecc 证书使用此参数,对应签发时使用的-k ec-256
。--key-file
:指定 key 的存储路径。--fullchain-file
:指定 合并的证书文件 的存储路径。--reloadcmd
:复制完成后执行命令。这里是「重新加载 caddy」,如果用的是 nginx 可以使用systemctl restart nginx
或nginx -s reload
。
证书路径及重新加载的命令,请根据需要调整功能。
自动更新证书
acme.sh 可以使用 crontab 定时检查证书是否过期,并重新签发。crontab 文件一般位于 /var/spool/cron/
或 /etc/crontabs
目录下。
crontab -l
查看计划任务;crontab -e
编辑计划任务。
cronjob 格式一般如下:
# 分钟 小时 日期 月份 星期 命令
17 02 * * * "/PATH/.acme.sh"/acme.sh --cron --home "/PATH/.acme.sh" > /dev/null
表示每天凌晨 02:17 检查证书是否到期。默认设定证书到期前 30 天更新证书。
如果安装时 cronjob 没有添加成功,可以使用 acme.sh --install-cronjob
手动添加。
手动更新证书
# 更新一个证书
acme.sh --renew -d example.com --ecc
# 更新所有证书
acme.sh --renew-all
# 运行 cronjob 来更新证书(可用于检查 cronjob 命令是否正确)
acme.sh --cron
更新证书时,会自动跳过未到期的。可以使用 --force
参数进行强制更新。
其它说明
# 默认 CA 为 zerossl,可以切换为 letsencrypt
acme.sh --set-default-ca --server letsencrypt
# 使用 staging 环境测试签发,防止超限导致 IP 被封。
acme.sh --staging --issue -d example.com -d '*.example.com' -k ec-256 --dns dns_cf --dnssleep 60
# 更新账户 email
acme.sh --update-account --accountemail '[email protected]'
# 如果需要同时使用多个 DNS API Key,可以使用 --config-home 指定配置的目录,issue、install-cert、cronjob都需要
acme.sh --config-home '/PATH/TO/CONFIG_DIR' --issue -d example.com -d '*.example.com' -k ec-256 --dns dns_cf --dnssleep 60
# 查看证书
openssl x509 -text -noout -in fullchain.cer