免费的 SSL 证书颁发机构,我推荐的有两家 ZeroSSLLet’s Encrypt。有以下几个优点:

  • 支持 Wildcard Certificates (通配符证书,类似 *.example.com )
  • 支持 ECC 证书(同等安全下,ECC 证书比 RSA 体积小)
  • 通过 API 直接签发,不用手工维护。

证书签发工具可使用 acme.sh,支持 ACME v2,纯 shell 实现,Linux / BSD 都可以使用。

安装 acme.sh

1
curl https://get.acme.sh | sh -s email=[email protected]

将 email 替换为自己的,建议使用 root 权限安装,减少不必要的麻烦。

有些 Linux 发行版默认没有安装 cron ,导致安装中断,根据提示操作即可。比如 Arch Linux,可以安装 cronie 后, 再执行一遍安装脚本。

脚本会做 3 件事情:

  • 复制 acme.sh 到 ~/.acme.sh/ 。
  • 创建 alias :acme.sh=~/.acme.sh/acme.sh
  • 创建每日执行的 cronjob 。

脚本创建的 alias 及 env,见 ~/.bash_profile:

1
. "/root/.acme.sh/acme.sh.env"

配置 acme.sh

Wildcard Certificate (通配符证书)要求必须使用域名验证。acme.sh 支持几十个 DNS 服务商的 API。这里以「Cloudflare DNS」举例。

编辑 ~/.acme.sh/account.conf,加入 Cloudflare DNS 的 API key 及 email。

1
2
3
ACCOUNT_EMAIL='[email protected]'
export CF_Key="Paste Your Cloudflare API Key Here"
export CF_Email="[email protected]"

Cloudflare API Key 详见:“Profile - Global API Key - View API Key”。其它 DNS 配置参考 How to use DNS API

签发证书 Issue Certificate

1
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  /root/.acme.sh/example.com/examplecom.cer
Your cert key is in  /root/.acme.sh/example.com/example.com.key
The intermediate CA cert is in  /root/.acme.sh/example.com/ca.cer
And the full chain certs is there:  /root/.acme.sh/example.com/fullchain.cer

安装证书 Install Certificate

1
2
3
4
acme.sh --install-cert -d example.com --ecc \
        --key-file /srv/ssl/example.com.key \
        --fullchain-file /srv/ssl/fullchain.cer \
        --reloadcmd "rc-service caddy reload"

参数说明:

  • --install-cert:安装证书,把证书文件复制到相应的目录。
  • --ecc:安装及更新 ecc 证书使用此参数,签发使用 -k ec-256。
  • --key-file:指定 key 的存储路径。
  • --fullchain-file:指定 合并的证书文件 的存储路径。
  • --reloadcmd:复制完成后执行命令,这里是 重新加载 caddy。

证书的路径按 web server 的配置调整,命令也是。

更新证书 Renew Certificate

手动执行更新:acme.sh --cron。此命令会更新所有的域名证书。

单个域名更新:

1
acme.sh --renew -d example.com [--ecc] [--force]

ECC 证书更新,加参数 --ecc;未到期强制更新,加 --force

定时自动更新证书

cronjob 文件一般位于 /var/spool/cron//etc/crontabs 目录下。

crontab -l 查看计划任务;crontab -e 编辑计划任务。

cronjob 格式一般如下:

1
17 02 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

表示每天凌晨 02:17 检查一下证书是否快到期了。acme.sh 默认设定证书到期前 30 天更新证书。如果没到时间,则不更新。

如果自动添加 cronjob 没有成功,可以使用 acme.sh --install-cronjob 手动添加。

自动续期设置好后,务必细心检查,防止脚本错误,导致证书过期。有个简单的方法:

1
17 02 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" >> /var/log/cron_log

也就是记录 cronjob 的执行后日志,这样第二天检查下 cron_log 文件就知道是否生效了。

注意事项

acme.sh 默认 CA 为 ZeroSSL,如果偏好 Let’s Encrypt,可以执行 acme.sh --set-default-ca --server letsencrypt 切换。

调试时使用 staging 环境测试签发,防止超限 IP 被封。

1
acme.sh --staging --issue -d example.com -d '*.example.com' --dns dns_cf -k ec-256 --dnssleep 60

其它辅助命令

  • 更新账户 email: acme.sh --update-account --accountemail '[email protected]'
  • 查看证书: openssl x509 -text -noout -in fullchain.cer