在如今的互联网环境中,为网站配置 SSL 证书已成为安全的标配。本文将介绍如何使用Let's Encrypt免费获取泛域名 SSL 证书,并实现自动续期,为你的网站保驾护航。
一、 环境准备
在开始之前,确保你具备以下条件:
- 一台可以访问互联网的服务器(Linux 环境,如 Ubuntu/CentOS)。
- Root 权限或 sudo 权限。
- 一个已解析的域名(本文以 example.com 为例)。
二、 什么是 Let's Encrypt?
Let's Encrypt 是一个免费的、自动化的、开放的证书颁发机构(CA),提供免费 SSL 证书。它的目标是让所有网站都能轻松实现 HTTPS 加密,保障用户数据的安全。通过 Let's Encrypt,你可以为你的主域名、子域名,甚至泛域名配置安全证书,而且过程完全自动化,不需要手动申请和管理证书,官方推荐使用 Certbot。
三、 Let’s Encrypt 证书颁发原理
Let’s Encrypt 证书的颁发是通过 自动化的认证流程 完成的,以下是基本流程:
1、 域名验证
在申请证书之前,Let’s Encrypt 必须验证你对所申请域名的控制权。这是通过以下几种方式进行的:
- HTTP-01 验证:Let’s Encrypt 向你请求创建一个特定的文件,并放在你网站的指定路径下。它通过访问该文件来验证你是否控制该域名。
- DNS-01 验证:Let’s Encrypt 提供一条 DNS TXT 记录,要求你将其添加到域名的 DNS 设置中。它通过检查 DNS 记录来验证你对域名的控制权。
对于 泛域名证书,必须使用 DNS-01 验证方式,因为 HTTP 验证不能跨域名层级进行。
2、 证书生成
一旦验证成功,Let's Encrypt 会生成一个 SSL 证书,并将其发放给申请者。这个证书包含了公钥和域名信息,任何人都可以通过该证书与网站进行安全通信。
3、 证书安装
证书的安装你可以选择自己手动安装,我自己是手动安装的,因为我用的是docker版的nginx服务器。你也可以由 Certbot 自动完成,前提是你已经在服务器上安装 Nginx 或 Apache 等服务器。Certbot 会将证书安装到 Web 服务器(如 Nginx 或 Apache)上,并配置好相应的加密设置,自动安装会更方便,动手配置更灵活,比如申请证书和 Web 服务器不在同一台电脑上就需要手动。
4、 自动续期
Let’s Encrypt 的证书有效期为 90 天,因此需要定期续期。Certbot 自动进行续期验证,确保你的网站不会因为证书过期而遭到用户的安全警告。
四、 Certbot 的工作原理
Certbot 是一个命令行工具,用于自动化整个 SSL 证书的管理流程。它可以做以下几件事:
- 申请证书:使用 ACME 协议从 Let’s Encrypt 获取证书。
- 验证域名所有权:通过 HTTP-01 或 DNS-01 验证确保你拥有该域名。
- 安装证书:将证书自动安装到你的 Web 服务器,并配置相关的加密参数。
- 续期证书:定期自动续期证书,避免证书过期。
Certbot 的核心工作是通过 ACME 协议(自动证书管理环境)与 Let's Encrypt 通信。ACME 是一套标准协议,用于自动化证书申请、验证和安装的过程。Certbot 使用 ACME 协议与 Let's Encrypt 进行通信,确保你的网站能够通过安全的 HTTPS 连接。
五、 安装 Certbot
Certbot 是由 Electronic Frontier Foundation (EFF) 提供的一个开源工具,用于自动化从 Let’s Encrypt 获取和管理 SSL 证书。Certbot 会自动为你处理证书申请、安装和续期等过程。
Linux 系统
推荐使用 Linux 的 snap 包管理工具安装Certbot,支持snap后可以使用如下命令安装Certbot
| sudo snap install --classic certbot #安装Certbot |
| sudo ln -s /snap/bin/certbot /usr/bin/certbot #创建一个符号链接,确保可以执行certbot命令(相当于快捷方式) |
其他系统平台
六、 单域名 SSL 证书
1、 申请单域名 SSL 证书
如果你只需要为单个域名(如 example.com 和 www.example.com)申请证书,可以使用以下命令:
| sudo certbot --nginx -d example.com -d www.example.com |
--nginx 需要服务器预先安装nginx,certbot获取到证书后会自动通过修改nginx的配置将证书安装到nginx上。
根据提示输入邮箱地址,并同意服务条款,Certbot 将自动完成证书申请和安装。
2、 单域名自动续期
Let's Encrypt 证书的有效期为 90 天,为了避免证书过期,我们可以使用 Cron Job 设置自动续期。
首先,你可以手动测试续期是否正常:
| sudo certbot renew --dry-run |
如果没有报错,可以继续配置自动续期任务:
| sudo crontab -e |
在打开的编辑器中添加以下行,表示每天凌晨 2 点执行自动续期任务:
| 0 2 * * * /usr/bin/certbot renew --quiet |
--quiet 参数表示静默模式,不会输出非错误信息。
七、 泛域名 SSL 证书
1、 申请泛域名 SSL 证书
泛域名证书(Wildcard Certificate)可以为同一主域名下的所有子域名提供 HTTPS 支持。例如,*.example.com 可以覆盖 blog.example.com、api.example.com 等子域名。
使用 DNS 验证申请泛域名证书
Let’s Encrypt 要求通过 DNS-01 验证来申请泛域名证书。运行以下命令:
| sudo certbot certonly --manual --preferred-challenges dns -d *.example.com -d example.com |
Certbot 会要求你在 DNS 中创建一个特定的 TXT 记录 记录以验证域名的所有权。
| _acme-challenge.example.com IN TXT "certbot给出的随机字符串" |
前往你的域名 DNS 管理页面,添加该记录后,返回命令行按下 Enter。
如图:
大概等几十秒钟,确保 DNS 记录在全网传播开来,Certbot 可以查询到。
Certbot 在执行验证时会发起 DNS 查询,如果能找到所需的 TXT 记录并验证其值,认证就会成功,然后就会颁发证书。证书颁发后,这条 TXT 记录 就可以删除了。
这个是手动添加删除 DNS 对应的 TXT 记录,这里只是演示Certbot颁发证书的过程,实际情况下最好采用自动化脚本添加和删除 DNS 的 TXT 解析记录。
2、 泛域名设置自动续期
Let’s Encrypt 颁发的 SSL 证书有效期为 90 天,为了避免证书过期导致网站 HTTPS 中断,自动续期 是必须要配置的。对于 泛域名证书,由于使用了 DNS-01 验证,因此我们也需要使用相应的自动化脚本来管理 DNS TXT 记录,从而实现自动续期。由于我购买的是腾讯云域名,这里我们以 腾讯云DNSPod 的 API 为例,来配置自动续期。
1. 创建自动化 DNS 脚本
首先,我们需要编写两个脚本用于处理 DNS-01 验证的 DNS 记录添加和删除。假设你已经安装了 腾讯云 CLI 工具 (tccli),,以下是 dnspod.sh 脚本的内容:
tccli安装和使用参考 腾讯云 CLI 工具
| #!/bin/bash RECORD_FILE="/tmp/_acme-challenge.${CERTBOT_DOMAIN}_${CERTBOT_VALIDATION}" if ! command -v tccli >/dev/null; then echo "TCCLI is required: https://cloud.tencent.com/document/product/440" 1>&2 exit 1 fi if [ "$1" = "clean" ]; then # 删除 DNS TXT 记录 RECORD_ID=$(cat ${RECORD_FILE}) if [ -n "${RECORD_ID}" ]; then tccli dnspod DeleteRecord --cli-unfold-argument \ --Domain ${CERTBOT_DOMAIN} \ --RecordId ${RECORD_ID} \ >/dev/null fi rm -f ${RECORD_FILE} else # 创建 DNS TXT 记录 RECORD_ID=$( tccli dnspod CreateRecord --cli-unfold-argument \ --Domain ${CERTBOT_DOMAIN} \ --SubDomain _acme-challenge \ --RecordType TXT \ --RecordLine 默认 \ --Value ${CERTBOT_VALIDATION} \ --TTL 600 \ | grep "RecordId" | grep -Eo "[0-9]+" ) echo ${RECORD_ID} > ${RECORD_FILE} sleep 20 # 等待 DNS 记录传播 fi |
脚本中涉及到一些环境变量比如CERTBOT_DOMAIN、CERTBOT_VALIDATION等等,这是由certbot自动将相关的环境变量传递给这些脚本的。
2. 配置自动续期命令
我们使用 certbot 的 --manual-auth-hook 和 --manual-cleanup-hook 参数,调用 dnspod.sh 脚本来自动添加和清理 DNS 记录:
| certbot renew --manual --preferred-challenges=dns \ --manual-auth-hook "/path/to/dnspod.sh" \ --manual-cleanup-hook "/path/to/dnspod.sh clean" \ --deploy-hook "/path/to/renew_and_reload_nginx.sh" |
- --manual-auth-hook:在验证开始时调用,用于创建 DNS TXT 记录。
- --manual-cleanup-hook:在验证结束后调用,用于清理 DNS TXT 记录。
- --deploy-hook:在证书更新成功后调用,用于重启并加载 Nginx 最新配置。
3. 配置 Crontab 定期续期任务
编辑 Crontab 文件,添加以下行,实现每 10 天凌晨 2 点自动尝试续期证书:
| 0 2 */10 * * root certbot renew --manual --preferred-challenges=dns \ --manual-auth-hook "/path/to/dnspod.sh" \ --manual-cleanup-hook "/path/to/dnspod.sh clean" \ --deploy-hook "/path/to/renew_and_reload_nginx.sh" >> /var/log/certbot-renew.log 2>&1 |
4. 重载 Nginx 配置
以下是 renew_and_reload_nginx.sh 的内容,用于在证书续期后重启 Nginx 服务(假设使用 Docker 运行 Nginx):
| !/bin/bash 停止 nginx 服务 docker compose -f /path/to/compose.yml stop nginx 重新启动 nginx 服务 docker compose -f /path/to/compose.yml up -d nginx |
5. 验证自动续期配置
在完成配置后,可以运行以下命令来测试续期流程,确保一切正常:
| certbot renew --manual --preferred-challenges=dns --manual-auth-hook "/path/to/dnspod.sh" --manual-cleanup-hook "/path/to/dnspod.sh clean" --deploy-hook "/path/to/renew_and_reload_nginx.sh" --dry-run |
如果没有错误提示,说明自动续期配置成功。
加上--dry-run表示使用Let's Encrypt的测试服务器。防止多次使用真实服务器频繁颁发证书达到速率限制
3、 深入解读
DNS 验证和自动化挑战:
- 泛域名证书使用 DNS-01 验证,即要求在 DNS 中添加 _acme-challenge 的 TXT 记录。这种方式可以验证你对整个域名的控制权。
- 使用 API 自动管理 DNS 记录,可以避免手动添加和删除 TXT 记录的繁琐操作,适合生产环境中的自动化需求。
Crontab 定时任务:
- 由于 Let’s Encrypt 证书有效期为 90 天,我们配置 Crontab 每 10 天尝试续期一次,以确保在证书到期前完成续期。
- 任务执行日志会被重定向到 /var/log/certbot-renew.log,便于后续检查和调试。
Nginx 重载:
- 证书续期后,需要重新加载 Nginx 配置,以使新的证书生效。通过 docker compose 管理的 Nginx 服务,可以使用 up -d 命令实现无中断重启。
配置完成后的效果
完成上述配置后,你的服务器将能够自动管理泛域名 SSL 证书,定期续期并自动应用新的证书配置。这将大大降低证书管理的工作量,同时保证网站的 HTTPS 加密连接始终有效。
你可以随时使用以下命令检查现有证书的状态:
| sudo certbot certificates |
如果证书信息显示正确,并且 expiry date 在未来日期,说明配置成功。
通过自动化脚本和 Certbot 工具的结合,你已经为你的泛域名 SSL 证书实现了从申请、安装到续期的全流程自动化,让你的网站可以轻松保持 HTTPS 安全连接。
八、 申请的 SSL 证书文件所在目录
当使用 Certbot 成功申请到 SSL 证书后,证书文件将默认保存在以下目录中:
| /etc/letsencrypt/live/your-domain-name/ |
具体包含以下几个文件:
- cert.pem:这是你的 SSL 证书 文件。
- privkey.pem:这是你的 私钥 文件,务必妥善保管,切勿泄露。
- chain.pem:这是 中间证书链 文件,用于验证证书的完整性。
- fullchain.pem:这是 完整证书链 文件,通常用于 Nginx 或 Apache 的 SSL 配置中。
例如,如果你的域名是 example.com,则目录路径为:
| /etc/letsencrypt/live/example.com/ |
你可以使用以下命令查看证书详细信息:
| sudo certbot certificates |
输出示例:
| Certificate Name: example.com Domains: example.com www.example.com Expiry Date: 2024-02-10 14:30:00+00:00 (VALID: 75 days) Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem |
提示:为了避免证书路径错误,建议在 Nginx 或 Apache 配置中直接使用 fullchain.pem 和 privkey.pem 两个文件。
nginx配置证书示例
| server { listen 80; server_name example.com www.example.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8080; } } |
如果使用docker nginx,可以通过docker挂载卷使用证书,比如我就是这样使用的:
compose.yml:
| services: nginx: image: nginx:latest networks: - spy ports: - "80:80" - "443:443" environment: - TZ=Asia/Shanghai # 设置为上海时区 volumes: # 主配置 - ./nginx/nginx.conf:/etc/nginx/nginx.conf:rw # include配置 - ./nginx/conf.d/:/etc/nginx/conf.d/:rw # 证书 - /etc/letsencrypt/live/spystudy.cn/fullchain.pem:/etc/ssl/certs/spystudy.cn/fullchain.pem:rw - /etc/letsencrypt/live/spystudy.cn/privkey.pem:/etc/ssl/certs/spystudy.cn/private.pem:rw # 日志 - ./nginx/logs/:/var/log/nginx/:rw |
然后nginx配置文件:
| server { listen 443 ssl; server_name spystudy.cn; ssl_certificate /etc/ssl/certs/spystudy.cn/fullchain.pem; ssl_certificate_key /etc/ssl/certs/spystudy.cn/private.pem; return 301 https://www.spystudy.cn$request_uri; } |
九、 验证 HTTPS 配置
证书安装完成后,可以通过访问 https://example.com 检查是否成功启用了 HTTPS。你也可以使用以下命令查看证书状态:
| sudo certbot certificates |
如果证书信息显示正确,并且 expiry date 在未来日期,说明配置成功。
十、 常见问题及解决方法
1. DNS 验证失败
检查 DNS 记录是否添加正确,并确保记录已完全传播,可以使用以下命令查看 DNS 解析状态:
| nslookup -q=txt _acme-challenge.example.com |
2. Nginx 配置冲突
如果 Certbot 无法自动修改 Nginx 配置文件,你可以手动更新 Nginx 配置文件(/etc/nginx/sites-available/default):
| server { listen 80; server_name example.com www.example.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://127.0.0.1:8080; } } |
保存并测试 Nginx 配置:
| sudo nginx -t sudo systemctl reload nginx |
原创文章,作者:cy,如若转载,请注明出处:https://www.cygzs.net/
