用 acme.sh 自动续期 SSL 证书

之前用腾讯云的免费 SSL 证书,每次快到期都得手动续,烦。今天换成了 acme.sh,彻底自动化了。

为什么换

  • 腾讯云免费证书:手动续期,每季度都得操作一次
  • acme.sh:自动申请、自动续期、永久免费、不限次数

方案选择

acme.sh 支持两种验证方式:

  1. DNS 验证:需要 DNS 服务商 API Key,支持通配符证书
  2. HTTP 文件验证:在网站目录放验证文件,不需要 API Key

我选了 HTTP 验证,不想给 API Key。

操作步骤

1. 创建验证目录

mkdir -p /var/www/acme-challenge  

2. 配置 Nginx

在 server block 里加一个优先级最高的 location,让 ACME 验证请求走静态文件:

server {  
    listen 80;
    server_name example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/acme-challenge;
    }

    location / {
        # 你原来的配置
        proxy_pass http://backend;
    }
}

443 端口的 server block 也加同样的 location。

测试配置并 reload:

nginx -t && nginx -s reload  

3. 安装 acme.sh

curl https://get.acme.sh | sh -s email=your@email.com  

如果服务器 CA 证书太旧导致 curl SSL 验证失败,可以先下载到本地再传上去:

# 本地
curl -L https://github.com/acmesh-official/acme.sh/archive/master.tar.gz -o acme.sh.tar.gz  
scp acme.sh.tar.gz root@server:/tmp/

# 服务器
cd /tmp && tar xzf acme.sh.tar.gz  
cd acme.sh-master && ./acme.sh --install -m your@email.com  

4. 申请证书

~/.acme.sh/acme.sh --issue -d example.com -w /var/www/acme-challenge

第一次申请会自动注册账号(默认用 ZeroSSL,也可以指定 Let's Encrypt)。

5. 安装证书到 Nginx

~/.acme.sh/acme.sh --install-cert -d example.com \
    --key-file /etc/nginx/ssl/example.com/key.pem \
    --fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
    --reloadcmd "nginx -s reload"

更新 Nginx 配置里的证书路径:

server {  
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com/key.pem;
    # ...
}

reload 一下:

nginx -s reload  

6. 确认自动续期

acme.sh 安装时会自动加 cron job:

crontab -l | grep acme  
# 输出类似:51 17 * * * "/root/.acme.sh"/acme.sh --cron ...

每天会自动检查证书,到期前 30 天自动续期并 reload Nginx。 须用 ^~ 前缀,否则可能被其他 location 规则覆盖 3. 证书路径:建议统一放 /etc/nginx/ssl/<domain>/,方便管理

总结

整个过程 10 分钟搞定,以后再也不用手动续证书了。acme.sh 支持几十家 DNS 服务商,如果需要通配符证书可以用 DNS 验证方式。

Ruosen

Be a Geek, Do the right thing;