跳过正文

使用 acme.sh 自动化获取网站 SSL 证书

·1360 字·3 分钟
目录

acme.sh 是一个强大且不依赖任何特定语言的 ACME 客户端,非常适合在服务器上直接使用,接下的操作均在 Debian 12 服务器上操作。

前提条件
#

在开始之前,需要准备如下几点:

  • 域名:例如 your_domain.com

  • DNS 配置:域名解析已经正确指向了你的云服务器。

  • Nginx 已安装:服务器已经安装好了 Nginx 且正常运行。

  • 防火墙已放行:服务器防火墙允许 80 (HTTP) 和 443 (HTTPS) 端口的入站流量。

安装 acme.sh
#

通过 SSH 登录服务器,执行acme.sh 的官方安装脚本。

# 安装 curl
sudo apt update
sudo apt install curl

# 执行安装脚本,替换成你自己的邮箱
curl https://get.acme.sh | sh -s email=your_email@example.com

安装完成后,重新加载 .bashrc 或是重新 SSH 登陆服务器来启用 acme.sh 命令:

source ~/.bashrc

生成通配符 SSL 证书
#

确认 DNS 提供商并获取 API 密钥
#

这一步需要登录购买和管理域名解析的平台(例如 Cloudflare, GoDaddy, Namecheap, 阿里云, 腾讯云 DNSPod 等)。acme.sh 支持几乎所有主流的 DNS 提供商。可以在这里查看完整的支持列表和每家提供商所需的 API 密钥名称: acme.sh DNS API WIKI

以阿里云为例:

  1. 登录阿里云创建 RAM 用户,访问控制 RAM 控制台
  2. 进入 RAM 用户界面寻找到创建 AccessKey 按钮。
  3. 点击创建后,获取 AccessKey IDAccessKey Secret

在服务器上配置 API 密钥
#

在服务器上执行 export 命令。后续申请签发证书时,acme.sh 会将 API 密钥储存到当前用户目录下的文件中: ~/.acme.sh/account.conf

以阿里云为例:

export Ali_Key="刚刚获取的AccessKey ID"
export Ali_Secret="刚刚获取的AccessKey Secret"

签发通配符证书
#

  1. 确保你的命令中包含了根域名和通配符域名。

  2. 使用 --dns 参数并指定DNS 提供商(例如 阿里云 是 dns_ali)。

acme.sh --issue --dns dns_ali -d your_domain.com -d *.your_domain.com

acme.sh 会自动调用 DNS API,创建验证所需的 TXT 记录,等待几秒让 DNS 记录生效,然后完成验证并获取证书。成功后,它会自动删除该 TXT 记录。

安装(部署)证书到 Nginx
#

acme.sh 生成的证书默认存放在其内部目录 ~/.acme.sh/ 中,我们需要使用 install-cert 命令将证书“安装”到一个稳定、可公开访问的目录,比如 /etc/nginx/ssl/。这样做还有一个巨大的好处:acme.sh 会记住安装路径和命令。未来当证书自动续期成功后,它会自动把新证书安装到相同的位置,并自动执行你指定的命令来重载 Nginx,实现完全自动化。

创建用于存放证书的目录:

sudo mkdir -p /etc/nginx/ssl

执行命令,安装证书到指定目录:

acme.sh --install-cert -d your_domain.com \
--key-file       /etc/nginx/ssl/your_domain.com/key.pem \
--fullchain-file /etc/nginx/ssl/your_domain.com/cer.pem \
--reloadcmd      "service nginx reload"
  • --install-cert -d your_domain.com: 指定要安装哪个域名的证书。

  • --key-file--fullchain-file: 指定证书私钥和公钥链的目标路径

  • --reloadcmd "service nginx reload": 这是实现自动化的核心acme.sh 会记住这个命令,并在未来每次成功续期后自动执行它,让 Nginx 加载新证书。

配置 Nginx 使用 SSL 证书
#

编辑网站配置文件:

sudo nano /etc/nginx/sites-available/my-hugo-blog.conf

用以下内容完整替换原来的配置。这是一个经过优化的、包含 HTTP 自动跳转到 HTTPS 的配置模板。

# 强制将所有 HTTP 请求重定向到 HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name your_domain.com www.your_domain.com;
    return 301 https://$host$request_uri;
}

# HTTPS 服务配置
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name your_domain.com www.your_domain.com;

    # 证书文件路径 (必须与 acme.sh install-cert 命令中的路径一致)
    ssl_certificate /etc/nginx/ssl/your_domain.com.cer;
    ssl_certificate_key /etc/nginx/ssl/your_domain.com.key;
  
    # 提升安全性的 SSL/TLS 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    # HSTS Header (强制浏览器使用 HTTPS)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # 网站根目录和默认文件
    root /var/www/my-hugo-blog;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

完成并验证
#

保存 Nginx 配置文件后,测试配置语法并重启 Nginx:

sudo nginx -t
sudo systemctl restart nginx

现在,打开浏览器访问 https://your_domain.com,能看到地址栏出现了安全锁标志。这下网站现在不仅启用了 HTTPS,而且其证书将在未来每 60 天自动续期一次,无需再进行任何手动操作。

duan
作者
duan
愿世界和平