一. 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 插件:
-
安装插件:
sudo apt-get install python3-certbot-dns-cloudflare
-
配置 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
-
确保文件权限正确:
chmod 600 cloudflare.ini
-
修改续期命令:
使用 DNS 插件重新获取证书,并设置自动续期:certbot renew --dns-cloudflare --dns-cloudflare-credentials /path/to/cloudflare.ini
验证:
4.2 方法2:提供认证钩子脚本
如果你没有使用支持 API 的 DNS 提供商,或者你更愿意继续使用手动模式,你需要创建一个脚本来自动处理 DNS 记录的验证。以下是一个来自cloudflare DNS提供商简单的示例:
-
创建认证脚本(例如 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 更改已足够传播。
- 脚本使用 Cloudflare 的 API 接口创建一个 TXT 记录,用于 Let’s Encrypt 的 DNS-01 验证。
-
设置脚本权限
给脚本文件设置执行权限:chmod +x auth-hook.sh
-
使用脚本续订证书
在 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
-
如果使用aliyun DNS提供商,这里推荐 @justjavac 大佬写的,https://github.com/justjavac/certbot-dns-aliyun
4.3 使用crontab 进行调度
我这边nginx用的是docker环境,需要把生成的证书同步到容器内。
- 编辑脚本 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
- 设置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
- 对于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
- 对于NGINX服务器:
# 在您的虚拟主机文件中添加以下行: ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Comments | NOTHING