一. Let's Encrypt 介绍

Let's Encrypt 是当前最常用的免费 HTTPS 证书生成工具之一。该服务由非营利组织提供,致力于为全球范围内的网站提供便捷的自动化证书颁发服务。虽然 Let's Encrypt 证书的有效期只有90天,但是可以自动续期,这使得 Let's Encrypt 更加易于使用和部署。

在使用 Let's Encrypt 生成证书时,可以使用 Certbot 工具来执行此任务。下面是一个示例命令,用于生成证书:

sudo certbot certonly \
    --email example@qq.com \
    --server https://acme-v02.api.letsencrypt.org/directory \
    --agree-tos \
    --manual \
    --preferred-challenges=dns  \
    -d example.com \
    -d www.example.com
  • certbot: Certbot 工具名称。
    certonly: Certbot 工具的插件,用于生成 SSL/TLS 证书。
  • --email example@qq.com: Let's Encrypt 要求在生成 SSL 证书时提供有效的联系电子邮件地址。
  • --server https://acme-v02.api.letsencrypt.org/directory:指定 Certbot 生成证书的 ACME 服务器。这里使用 Let's Encrypt v2 API 端点。
  • --agree-tos:同意 Let's Encrypt 的服务条款。
  • --manual:指定使用手动模式生成证书。这意味着您需要在命令提示符下手动操作来验证您拥有该域名。
  • --preferred-challenges=dns:指定 Certbot 使用 DNS 验证方式进行证书颁发。这表示您需要将一个特定的 TXT 记录添加到 DNS 进行验证。
  • -d 'example.com':指定您想要为其生成 SSL 证书的域名。你可以通过添加多个 -d 选项来同时为多个域名生成证书。

请注意,由于 --manual 选项需要手动操作,因此它可能比其他选项耗费更多时间。另外,使用 DNS 验证时需要在 DNS 服务商处添加 TXT 记录以实现验证,这在某些情况下可能会比较困难,也需要等待 DNS 缓存刷新。在选择选项时,请根据您的需求和特定情况来作出最合适的选择。

我们可以把 --manual --preferred-challenges=dns 替换成--preferred-challenges http-01并配置 Nginx 服务器的相应设置,使用 HTTP 验证方式生成证书。

二. 生成证书的详细流程

在 Linux 上使用 Certbot 来获取并自动续期 Let's Encrypt 的 SSL 证书是一个很好的选择,因为 Certbot 是由 Electronic Frontier Foundation (EFF) 支持的官方客户端。下面是详细的步骤:

1. 安装 Certbot

首先,你需要在你的 Linux 系统上安装 Certbot。安装方法取决于你使用的 Linux 发行版。以下是一些常见的 Linux 发行版的安装指令:

对于 Ubuntu/Debian 系统:

sudo apt update
sudo apt install certbot

对于 CentOS/RHEL 系统:

sudo yum install epel-release
sudo yum install certbot

对于 Fedora 系统:

sudo dnf install certbot

2. 使用以下命令生成证书:

sudo certbot certonly \
    --email example@qq.com \
    --server https://acme-v02.api.letsencrypt.org/directory \
    --agree-tos \
    --manual \
    --preferred-challenges=dns  \
    -d example.com \
    -d *.example.com

请将 example@qq.com 替换为您自己的电子邮件地址,并使用您要生成证书的域名替换 example.com 和 www.example.com。
运行此命令后,Certbot将提示您为该域名添加DNS TXT记录。请使用您的DNS提供商或托管服务提供商的管理面板或API添加记录。
输入它并等待几分钟以允许记录传播并进行验证。一旦您添加了DNS记录,该命令将在 /etc/letsencrypt 目录中生成通配符证书。



如果成功的话,它会生成两个文件:
/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem

3. 手动续期

Certbot 是申请的Let’s Encrypt的免费证书,有效期 3 个月,到期之后我们可以再次续期,达到永久免费的效果。

你只需要在到期前,再手动执行生成证书的命令,也就是以上步骤2,就ok啦。

4. 自动续期

4.1 方法1:使用DNS插件

如果你的 DNS 提供商支持 API 访问,最好的解决方案是使用 Certbot 的 DNS 插件,这些插件可以自动处理 DNS 记录的更改。例如,如果你使用的是 Cloudflare,你可以安装和使用 Certbot 的 Cloudflare 插件:

  1. 安装插件:

    sudo apt-get install python3-certbot-dns-cloudflare
  2. 配置 DNS API:
    创建一个 API 令牌并保存到一个安全的配置文件中,比如 cloudflare.ini,并设置适当的权限:
    如果使用全局 API 密钥:

    dns_cloudflare_email = your-email@example.com
    dns_cloudflare_api_key = your-api-key

    如果使用 API 令牌:

    dns_cloudflare_api_token = your-api-token
  3. 确保文件权限正确:

    chmod 600 cloudflare.ini
  4. 修改续期命令:
    使用 DNS 插件重新获取证书,并设置自动续期:

    certbot renew --dns-cloudflare --dns-cloudflare-credentials /path/to/cloudflare.ini

    验证:

4.2 方法2:提供认证钩子脚本

如果你没有使用支持 API 的 DNS 提供商,或者你更愿意继续使用手动模式,你需要创建一个脚本来自动处理 DNS 记录的验证。以下是一个来自cloudflare DNS提供商简单的示例:

  1. 创建认证脚本(例如 auth-hook.sh):

    #!/bin/bash
    # Cloudflare API 设置
    API_TOKEN="your_cloudflare_api_token"
    ZONE_ID="your_zone_id"  # Cloudflare Zone ID
    DNS_RECORD_NAME="_acme-challenge.$CERTBOT_DOMAIN."
    # 创建或更新 DNS TXT 记录
    RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
     -H "Authorization: Bearer $API_TOKEN" \
     -H "Content-Type: application/json" \
     --data '{"type":"TXT","name":"'"$DNS_RECORD_NAME"'","content":"'"$CERTBOT_VALIDATION"'","ttl":120}')
    # 检查 Cloudflare API 是否成功响应
    SUCCESS=$(echo $RESPONSE | jq .success)
    if [[ $SUCCESS != "true" ]]; then
    echo "Failed to update DNS records."
    echo "API Response: $RESPONSE"
    exit 1
    fi
    # 休眠以等待 DNS 更改传播
    sleep 30

    脚本说明

    • 脚本使用 Cloudflare 的 API 接口创建一个 TXT 记录,用于 Let’s Encrypt 的 DNS-01 验证。
      -使用 curl 发送 HTTP POST 请求到 Cloudflare 的 API 端点,以添加 DNS 记录。
      -使用 jq 解析 JSON 响应以检查操作是否成功。
      -在验证之前等待 30 秒,以确保 DNS 更改已足够传播。
  2. 设置脚本权限
    给脚本文件设置执行权限:

    chmod +x auth-hook.sh
  3. 使用脚本续订证书
    在 Certbot 命令中指定这个脚本作为认证钩子:

    certbot certonly --manual --preferred-challenges=dns --manual-auth-hook /path/to/auth-hook.sh -d "example.com" -d "*.example.com"

    以上都可以在命令后加上 --dry-run 后缀进行测试,测试完成后删除 --dry-run

  4. 如果使用aliyun DNS提供商,这里推荐 @justjavac 大佬写的,https://github.com/justjavac/certbot-dns-aliyun

4.3 使用crontab 进行调度

我这边nginx用的是docker环境,需要把生成的证书同步到容器内。

  1. 编辑脚本 automatic_certificate_renewal.sh
    #!/bin/bash
    # 更新证书
    # 方法1
    /usr/bin/certbot renew --dns-cloudflare --dns-cloudflare-credentials /opt/cmd/cloudflare/cloudflare.ini
    # 方法2
    # /usr/bin/certbot certonly --manual --preferred-challenges=dns --manual-auth-hook /opt/cmd/cloudflare/auth-hook.sh -d "byteromance.com" -d "*.byteromance.com"
    # 覆盖证书文件
    cp /etc/letsencrypt/live/byteromance.com/privkey.pem /data/wordpress/wp_nginx/certs
    cp /etc/letsencrypt/live/byteromance.com/fullchain.pem /data/wordpress/wp_nginx/certs
    docker restart wp_nginx
  2. 设置crontab调度
    0 0 1 * * bash /opt/cmd/automatic_certificate_renewal.sh > /opt/cmd/log/cert/logfile_$(date "+\%Y\%m\%d").log 2>&1

三. 配置HTTPS

在生成证书后,使用以下方法之一来配置您的HTTPS,这里不作详细的介绍。
nginx参考: Docker部署WordPress:用Nginx为站点加速上SSL/HTTPS

  1. 对于Apache服务器:
    # 在您的虚拟主机文件中添加以下行:
    SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem 
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem 
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
  2. 对于NGINX服务器:
    # 在您的虚拟主机文件中添加以下行:
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;