李守中
该站已迁往根域名 https://lishouzhong.com
需要注意,迁移后的文章的 url 可能会发生变化。
域名 https://note.lishouzhong.com 下的内容将不再更新,但已有内容会永久保留。

acme.sh 自动管理 ssl 证书

Table of Contents

1. 安装 acme.sh

1.1. Linux

acme.sh 可以以 root 用户身份进行操作,也可以以普通用户身份进行操作。推荐以普通用户身份安装。

切换到 root 用户或者普通用户执行 curl https://get.acme.sh | sh 之后等待。

目录 ~/.acme.sh 内包含程序的所有文件。删除 acme.sh 只需要删除这个文件夹与 crontab 中的 acme.sh 任务即可。

启用日志需要在 ~/.acme.sh/account.conf 文件中加入

LOG_FILE="/home/<username>/.acme.sh/acme.sh.log"

1.2. FreeBSD

执行 pkg install acme.sh 后,系统会自动创建 acme 用户和 acme 用户组,家目录为 /var/db/acme,申请的证书会被放在 /var/db/acme/certs 下。

/var/db/acme/.acme.sh/account.conf 中日志配置为 LOG_FILE='/var/log/acme.sh.log' ,但 acme 用户和用户组没有 /var/log 目录的读写权限,所以在申请证书过程中会报错。

把日志配置修改为 LOG_FILE='/var/db/acme/acme.sh.log' 让日志直接写在 acme 用户的家目录下就正常了。

定期更新证书的 crontab 任务需要用户自行添加,而 Linux 上的在安装 acme.sh 时就已经完成了。

以 root 权限执行 sudo crontab -e -u acme 用编辑器添加 cron 任务:

0 18 * * * /usr/local/sbin/acme.sh --cron --home /var/db/acme/.acme.sh > /dev/null

2. 迁移 acme.sh

2.1. Linux

主要迁移两个部分: ~/.acme.sh 和 crontab 定时任务。下面以用户间迁移为例,主机间迁移步骤相同。

如果开始以 root 安装了 acme.sh 但是想迁移到其他用户下,需要如下操作:

  1. 移动程序目录 sudo mv /root/.acme.sh/ ~
  2. 修改程序目录权限 sudo chown -R <username>:<user_group> ~/.acme.sh
  3. 修改 acme.sh 环境变量,在 ~/.acme.sh/acme.sh.env 文件中:
    • LE_WORKING 对应的路径改成 /home/<username>/.acme.sh
    • alias 对应的路径改成 /home/<username>/.acme.sh/acme.sh
  4. 设置定时任务,执行 crontab -e 输入任务 36 0 * * * "/home/<username>/.acme.sh"/acme.sh --cron --home "/home/<username>/.acme.sh" > /dev/null
  5. /root/.bashrc 文件里面如果还残留有 . "/root/.acme.sh/acme.sh.env" ,删掉即可。
  6. 切换到 root 用户执行 crontab -e 删除该用户下的定时任务。

至此,主体迁移完成。

如果打开了日志也需要更改 ~/.acme.sh/account.conf 文件中的日志路径。

2.2. FreeBSD

tar zcf acme.tar.gz /var/db/acme 打包旧系统上 acme 用户的家目录,然后 crontab -l -u acme 备份 acme 用户的 cron 任务。

然后在新系统上 pkg install acme.sh 安装 acme 后,用 acme.tar.gz 里面的内容覆盖 /var/db/acme 中的内容。

最后在新系统上 sudo crontab -e -u acme 为 acme 用户添加 cron 任务以自动更新证书。

3. 申请证书

从 2021.08.01,也就是 acme.sh 3.0 开始,证书颁发机构被切换到了 ZeroSSL。

申请证书可以用 http 验证或者 DNS 验证。其中 DNS 验证方式需要手动操作,但是,以 DNS Api 的方式进行验证可以实现自动续期。

下面是 DNS Api 的操作方法。

3.1. 内网机器

以阿里云为例。

登陆阿里云控制台 -> 企业 -> 人员权限管理 -> 访问控制 RAM - 人员管理 - 用户 -> 创建用户 -> 勾选 编程访问

保存生成的 AccessKey 信息,这个信息只展示一次。

进入用户页面 -> 权限管理 -> 添加权限 -> 添加 AliyunDNSFullAccess 权限后保存。

根据官方 DNS Api 获取阿里云环境变量格式并填入对应的字符串,然后导入环境变量:

export Ali_Key="LTAI4Fd8J9qs4fxxxxxxxxxx"
export Ali_Secret="Xp3Z7NDOW0CJcPLKoUwqxxxxxxxxxx"

执行 acme.sh --issue --server zerossl --dns dns_ali -d lishouzhong.com -d "*.lishouzhong.com" --dnssleep 600 申请证书。

注意: --dnssleep 600 不能少。acme.sh 在添加 _acme-challenge 之后会用 CloudFlare 或者 google 的公开 DNS 进行验证。但我们的大内网并不能使用这两家的服务。所以需要这个参数让 acme.sh 等待 600s 之后直接使用物理机指定的 DNS 进行验证。这样才能验证成功。

3.2. 外网机器

以 CloudFlare 为例。

登陆 Cloudflare 控制台,点击域名,在 Overview 选项对应页面的右下角找到 Account ID ,它是环境变量 CF_Account_ID 的值。

然后点击 Account ID 下的 Get your API token -> API Token -> Create Token -> 找到 Custom token 点击 Get Started 。值如下:

  1. Token name: acme;
  2. Permissions 选项卡:
    1. Zone - DNS - Edit
    2. Zone - Zone - Read
  3. Zone Resources 选项卡: Include - All zones from an account - 选择自己的账户邮箱。

创建完成之后保存生成的 API Token ,这串字符只展示一次。它是环境变量 CF_Token 的值。

导入环境变量:

export CF_Token="PfCA6tyLxxxxxxxx-sS6ANgqzuVexxxxxxx"
export CF_Account_ID="1fs48ec7e2063cb70hacc3xxxxxxxxxx"

执行 acme.sh --issue --server zerossl --dns dns_cf -d lishouzhong.com -d "/.lishouzhong.com" 开始申请证书。

4. 安装证书

执行 ~/.acme.sh/acme.sh --list 列出全部证书。

根据官方说法: 不要直接用 ~/.acme.sh/ 目录内的证书文件,因为目录结构可能会因为脚本自动更新而变动。

正确的使用方法是使用 --install-cert 参数,并指定目标位置,然后证书文件会被 copy 到相应的位置,例如:

比如 Apache:

acme.sh --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

比如 Nginx:

acme.sh --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

安装到其他地方也可以:

acme.sh --install-cert -d lishouzhong.com -d "*.lishouzhong.com" \
    --key-file          /home/<username>/dockerData/ssl/lishouzhong.com/privkey.pem  \
    --fullchain-file    /home/<username>/dockerData/ssl/lishouzhong.com/fullchain.pem \
    --reloadcmd         "docker exec nginx nginx -s reload"

--install-cert 的详细参数参考: https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc

这里指定的所有参数都会被记录,将来证书自动更新以后,自动调用。

要修改安装配置,可修改 vim ~/.acme.sh/<domain>/<domain>.conf 文件或直接运行新的安装命令,即可覆盖上一次的配置。

要删除安装配置,可直接运行无参数的安装命令 acme.sh --install-cert -d <domain> -d "*.<domain>"

5. 证书操作

5.1. 更新证书

acme.sh 安装时就已经配置好了自动更新,但如果有需要也可以手动更新:

acme.sh --renew -d lishouzhong.com -d "*.lishouzhong.com" --force

5.2. 吊销证书

如果不再使用申请到的证书,可以选择吊销该证书:

acme.sh --revoke -d lishouzhong.com -d "*.lishouzhong.com"

5.3. 删除证书

从 acme.sh 中移除该证书,但并不吊销该证书:

acme.sh --remove -d lishouzhong.com -d "*.lishouzhong.com"

执行证书移除命令后 acme.sh 仅不再执行有关该证书的任务,但证书文件仍然在 ~/.acme.sh/ 路径下,需要用户手动删除。

5.4. ECC证书

目前最常用的密钥交换算法有 RSAECDHE:

  • RSA 历史悠久,兼容性好,但计算较慢;
  • ECDHE 使用 ECC 算法,计算速度快,但兼容性较差;

内置 ECDSA 公钥的证书一般被称之为 ECC 证书 ,内置 RSA 公钥的证书称为 RSA 证书 。ECC 算法的计算复杂度远小于 RSA,但却能用更小的密钥长度得到与 RSA 相同的安全等级,一般认为 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key。

所以 ECC 证书不仅体积小,运算速度也更快。但是由于历史原因,它在旧系统的兼容性上存在不少问题,比如 XP 及之前的 Windows 系统都不能原生支持 ( FireFox 除外 )。

acme.sh 也可以申请 ECC 证书,仅需再申请命令中加上 --keylength 参数,操作上并无太大变化。

目前 --keylength 支持以下三类可选长度:

  • ec-256 ( 推荐使用 )
  • ec-384
  • ec-521 ( 不完善 )

执行 acme.sh --issue --server zerossl --dns dns_ali -d lishouzhong.com -d "*.lishouzhong.com" --dnssleep 600 --keylength ec-256 开始申请证书。在 ~/.acme.sh/ 下的生成的存放 ecc 证书文件夹带 _ecc 后缀。

创建证书安装目录 mkdir -p /home/<username>/dockerData/ssl/lishouzhong.com_ecc/

安装命令要加 --ecc 参数:

acme.sh --install-cert -d lishouzhong.com -d "*.lishouzhong.com" --ecc \
--key-file       /home/mgz/dockerData/ssl/lishouzhong.com_ecc/privkey.pem \
--fullchain-file /home/mgz/dockerData/ssl/lishouzhong.com_ecc/fullchain.pem \
--reloadcmd      "systemctl force-reload nginx"

更新证书加 --ecc 参数: acme.sh --renew -d lishouzhong.com -d "*.lishouzhong.com" --force --ecc

吊销证书加 --ecc 参数: acme.sh --revoke -d lishouzhong.com -d "*.lishouzhong.com" --ecc

移除证书加 --ecc 参数: acme.sh --remove -d lishouzhong.com -d "*.lishouzhong.com" --ecc

6. 踩坑

6.1. Error add txt for domain:_acme-challenge.*

到阿里云的 DNS 解析配置页,或者 CloudFlare 控制台查 DNS 解析记录。

如果以前申请过,有 CNAME 记录没删,手动删掉 _acme-challenge 的 CNAME 再次运行就正常了。

6.2. 卡在 Checking lishouzhong.com for _acme-challenge.*

这个问题一般出在大内网的机器上。

申请证书过程中,acme.sh 在添加 _acme-challenge 之后会用 CloudFlare 或者 google 的公开 DNS 进行验证。但大内网不让用这两家的服务。所以需要加 --dnssleep 这个参数让 acme.sh 等待 600s 之后 ( 600s 在多数时候足以让国外的 DNS 服务器上的信息传导到国内服务器上 ) 直接使用物理机指定的 DNS 进行验证。这样才能验证成功。



Last Update: 2023-05-18 Thu 08:56

Generated by: Emacs 28.2 (Org mode 9.5.5)   Contact: lsz.sino@outlook.com

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议