SSL 证书颁发机构,我选择 Let’s Encrypt。有以下几个优点:

  • 免费的 SSL 证书
  • 支持 Wildcard Certificates (通配符证书,类似 *.example.com )
  • 支持 ECC(ECDHE 密钥交换、ECDSA 签名、更小、更快)

证书签发工具可使用 acme.sh,支持 ACME v2,shell 实现,没有乱七八糟的依赖,Linux / BSD 基本都可以使用。

安装 acme.sh

建议使用 root 安装。

1
curl https://get.acme.sh | sh

如果系统没有 cron ,安装会中断,根据提示操作即可。比如 Arch Linux,可以使用 cronie, pacman -S cronie

接着设置 cronie 为开启启动,systemctl enable cronie

然后再执行一遍 acme.sh 安装脚本。脚本会做 3 件事情。

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

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

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

Arch Linux 的 cronjob 文件位于 /var/spool/cron/ 目录下,其它发行版可能在 /etc 里。

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

cron 格式一般如下:

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

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

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

为了使环境立即生效,建议退出 shell 后重新打开,或者执行一次 export ~/.bash_profile

配置 acme.sh

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

编辑 ~/.acme.sh/account.conf

设置账户 email,加入 Cloudflare DNS 的 API key 及 email。

1
2
3
ACCOUNT_EMAIL='xxx@example.com'
export CF_Key="xxxxxxxxxxx"
export CF_Email="xxx@example.com"

Cloudflare API key 详见:”Profile - Global API Key - View API Key”。其它 DNS 配置请参考 acme.sh 项目的 wiki 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 。

签发成功后会提示:

1
2
3
4
Your cert is in  /root/.acme.sh/example.com/examplecom.cer
Your cert key is in  /root/.acme.sh/example3.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 /etc/nginx/ssl/example.com.key \
        --fullchain-file /etc/nginx/ssl/fullchain.cer \
        --reloadcmd "systemctl reload nginx"

参数说明:

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

更新证书 Renew Certificate

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

单个域名更新:

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

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

acme.sh 使用说明

  • 命令格式: acme.sh command ...[parameters]....
  • 使用说明:acme.sh -h
  • 更新账户 email: acme.sh --update-account --accountemail 'xxx@example.com'
  • 查看证书: openssl x509 -text -noout -in fullchain.cer

注意事项

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

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

自动续期设置好后,务必细心检查,防止脚本错误,导致证书过期。可使用:

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

这样过两天检查 cron_log 就知道定时脚本有没有生效了。