使用acme.sh申请SSL证书


部署教程

安装并配置acme.sh

  1. 安装
    这里使用 Docker 安装,方便环境隔离。/opt/acme.sh 为挂载目录

    docker run -d --name acme.sh \
    -e AUTO_UPGRADE=0 \
    -e TZ=Asia/Shanghai \
    -v /opt/acme.sh:/acme.sh \
    neilpang/acme.sh daemon
  2. 配置
    acme.sh 默认使用的是 ZeroSSL,我这里修改为 Let's Encrypt

    docker exec acme.sh --set-default-ca --server letsencrypt
    docker exec acme.sh --set-default-chain --preferred-chain "ISRG" --server letsencrypt

    注:--preferred-chain "ISRG" 表示设置根证书为 ISRG Root X1, 它与 DST Root CA X3 的区别主要是

    • ISRG Root X1 会更新一些,DST Root CA X3 已于2021年9月30日到期

    • 一些旧的设备(例如,iPhone 4 或 HTC Dream)不会信任 ISRG Root X1,因为它们没有获得软件更新

    • 虽说 DST Root CA X3 已到期,但Android设备仍能够继续正常访问使用 Let’s Encrypt 证书加密的网站,其它旧设备将会得到证书过期警告

  3. 注册账号(记得修改为自己的邮箱)

    docker exec acme.sh --register-account --server letsencrypt -m [email protected]
    [Sun Sep 24 15:49:59 CST 2023] Create account key ok.
    [Sun Sep 24 15:49:59 CST 2023] Registering account: https://acme-v02.api.letsencrypt.org/directory
    [Sun Sep 24 15:50:05 CST 2023] Registered
    [Sun Sep 24 15:50:05 CST 2023] ACCOUNT_THUMBPRINT='xxx'

    这时会在 /acme.sh 目录下生成一个 http.header 文件,申请证书时会使用该文件

固定域名(webroot)

如果只有少数几个固定的域名,这时可以使用 webroot 方式申请SSL证书。webroot 方式会在本地生成一个验证文件,申请证书时通过验证该文件验证域名所有权

申请证书

docker exec acme.sh --issue -d example.com -d www.example.com,nas.example.com -w /acme.sh/example.com

执行后会在挂载目录 /opt/acme.sh 下生成SSL证书相关的 cert 文件和 key 文件

$ ls example.com
ca.cer  fullchain.cer  example.com.cer  example.com.conf  example.com.csr  example.com.csr.conf  example.com.key

配置SSL证书

ssl_certificate /opt/acme.sh/example.com/fullchain.cer;
ssl_certificate_key /opt/acme.sh/example.com/example.com.key;
ssl_dhparam /opt/acme.sh/example.com/dhparam.pem;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;

如何生成 dhparam 的证书?

openssl dhparam -out /opt/acme.sh/example.com/dhparam.pem 2048

配置NGINX

Let's Encrypt 只会在 80 端口验证域名所有权,所以只需要在 80 端口添加一个 location

server {
    listen       80;
    listen  [::]:80;
    server_name  www.example.com nas.example.com;

    location / {
        return 301 https://example.com$request_uri;
    }
    location ^~ /.well-known/acme-challenge {
        alias /opt/acme.sh/example.com/.well-known/acme-challenge;
    }
}

server {
    listen       443 ssl;
    listen       [::]:443 ssl;
    server_name  nas.example.com;
    include      /etc/nginx/conf.d/ssl/example.com.conf;

    ......
}

重启NGINX

nginx -t
nginx -s reload

泛域名(DNS)

webroot 无法申请泛域名证书,泛域名证书的申请需要利用DNS服务提供商的API,动态添加一个TEXT记录,这里以 Cloudflare 为例

令牌获取

右上角点击我的个人资料, 然后点击创建令牌

然后选择DNS模版

  • 令牌名称可以随意

  • 权限设置为 区域 -> DNS -> 编辑

  • 区域资源设置为 包括 -> 特定区域 -> 域名(example.com)

继续以显示摘要, 然后创建令牌

最后记得保存令牌到本地

账户ID获取

选择对应的域名,在概况的右下角会有账户ID显示

编辑配置

编辑 /opt/acme.sh 目录下的 account.conf

+ CF_Token='xxx'
+ CF_Account_ID='xxx'

申请证书

docker exec acme.sh --issue --dns dns_cf -d "nas.example.com" -d "*.nas.example.com"

安装证书

如果想要修改默认安装的目录,则可以使用 --install-cert 命令

docker exec acme.sh --install-cert -d nas.example.com \
--key-file /nginx/data/custom_ssl/npm-1/privkey.pem \
--fullchain-file /nginx/data/custom_ssl/npm-1/fullchain.pem

如果想要更新证书后同步重启NGINX,可以继续添加命令参数

--reloadcmd "nginx -s reload"

搭配NginxProxyManager

首先打开 NginxProxyManager, 选择 SSL Cetificates

然后选择 Add SSL Cetificates -> Custom

最后添加相关文件:

  • Certificate: nas.example.com.cer

  • Certificate Key: nas.example.com.key

  • Intermediate Certificate: ca.cer

为了避免证书过期后重新添加,需要把NginxProxyManager挂载目录也挂载到 acme.sh 容器

docker stop acme.sh
docker rm acme.sh
docker run -d --name acme.sh \
-e AUTO_UPGRADE=0 \
-e TZ=Asia/Shanghai \
-v /opt/acme.sh:/acme.sh \
-v /opt/nginx:/nginx \
neilpang/acme.sh daemon

然后修改申请证书的命令

docker exec acme.sh --issue --dns dns_cf -d "nas.example.com" -d "*.nas.example.com" \
--renew-hook "acme.sh --install-cert -d nas.example.com \
--key-file /nginx/data/custom_ssl/npm-1/privkey.pem \
--fullchain-file /nginx/data/custom_ssl/npm-1/fullchain.pem"

如果提示 Domains not changed, 则需要使用 --force 重新申请

更新证书(手动)

Let's Encrypt 申请到的证书有效期是90天,acme.sh 每60天会对证书进行更新,你也可以手动强制更新:

# 查询证书申请信息
acme.sh --list

# 手动强制更新证书
acme.sh --renew -d nas.example.com -d *.nas.example.com --force

参考资料

作者: honmaple
链接: https://honmaple.me/articles/2023/09/shi-yong-acme-shshen-qing-sslzheng-shu.html
版权: CC BY-NC-SA 4.0 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat
alipay

加载评论