1. 从零开始为Nginx配置Let's Encrypt泛域名证书
作为一枚长期与服务器打交道的运维老兵,我深知SSL证书配置这个看似简单的环节,实际暗藏着无数新手容易踩坑的细节。今天就用我在华为云、阿里云等平台实操过上百次的经验,手把手带你在Ubuntu 22.04上完成Let's Encrypt证书的全套配置流程。
先明确几个关键点:Let's Encrypt作为非盈利性CA机构,提供的免费证书有三个核心优势——90天有效期(需定期续期)、支持通配符证书、完全自动化部署。而Certbot则是官方推荐的自动化工具链,能帮我们完成从申请到配置的全流程。下面进入正题:
1.1 环境准备与依赖安装
在开始前,请确保:
- 已拥有域名解析权限(以example.com为例)
- 服务器已安装Nginx并开放80/443端口
- 系统时间为北京时间(证书验证对时间敏感)
安装Certbot核心组件:
bash复制sudo apt update
sudo apt install -y certbot python3-certbot-nginx
这里选择python3-certbot-nginx插件而非默认版本,是因为它提供了Nginx配置自动修改功能。实测在Ubuntu 22.04上,该版本对Jinja2模板的解析更稳定。
重要提示:如果之前安装过旧版certbot,务必先执行
sudo apt remove certbot清除残留配置,避免出现依赖冲突。
2. 泛域名证书申请全流程解析
2.1 DNS验证原理剖析
与单域名证书的HTTP验证不同,泛域名证书必须通过DNS TXT记录验证域名所有权。其核心机制是:
- Certbot向Let's Encrypt发起申请时,会生成随机字符串作为验证令牌
- 需要在域名解析中添加_acme-challenge子域的TXT记录
- CA服务器通过DNS查询验证记录是否存在
这种验证方式的优势在于:
- 可验证主域及其所有子域的控制权
- 不影响现有网站服务
- 适合没有公网IP的内网环境
2.2 分步申请指南
执行申请命令(请替换实际域名):
bash复制sudo certbot certonly --manual --preferred-challenges dns \
--server https://acme-v02.api.letsencrypt.org/directory \
-d example.com -d *.example.com
关键参数说明:
--manual:启用交互式模式--preferred-challenges dns:强制使用DNS验证-d参数列表:主域+通配符子域
接下来会进入交互流程:
2.2.1 邮箱与协议确认
code复制Enter email address (used for urgent renewal and security notices):
这里建议填写真实邮箱,证书到期前会收到提醒。但注意不要使用企业邮箱,某些邮件服务器会拦截自动邮件。
2.2.2 DNS记录添加
系统会提示类似信息:
code复制Please deploy a DNS TXT record under:
_acme-challenge.example.com
With value:
XrF5bWZvQ3JkZ1A5qW0wS3VpLmNvbQ==
以华为云DNS控制台为例:
- 登录控制台进入域名解析
- 添加记录类型为TXT
- 主机记录填写
_acme-challenge - 记录值粘贴生成的字符串
- TTL建议设为300秒
验证记录是否生效:
bash复制dig TXT _acme-challenge.example.com +short
若返回包含验证值,按Enter继续。注意:某些DNS服务商生效较慢(如Cloudflare),可能需要等待2-5分钟。
2.2.3 二次验证问题
泛域名证书需要两轮验证!完成第一次后,会立即要求添加第二条不同值的TXT记录。这是ACME协议的安全要求,务必完整执行。
典型报错处理:
- "DNS problem: NXDOMAIN" → 记录未生效或拼写错误
- "Invalid TXT record" → 值包含多余引号或空格
- "Too many certificates" → 同一域名每周限制5次申请
2.3 证书文件说明
成功后会显示证书存储路径:
code复制/etc/letsencrypt/live/example.com/
├── cert.pem # 证书本体
├── chain.pem # 中间证书
├── fullchain.pem # 证书链(推荐使用)
└── privkey.pem # 私钥(务必保密)
安全建议:
- 私钥文件权限应设为600
- 定期备份整个live目录
- 不要直接修改这些文件(续期时会自动更新)
3. Nginx高级SSL配置实战
3.1 最小化安全配置
编辑站点配置文件(示例路径):
bash复制sudo nano /etc/nginx/sites-available/default
基础SSL配置模板:
nginx复制server {
listen 443 ssl http2;
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;
# 加密套件配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# HSTS增强安全
add_header Strict-Transport-Security "max-age=63072000" always;
# 其他业务配置...
}
3.2 性能优化关键参数
- OCSP装订(减少客户端验证延迟):
nginx复制ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
- 会话复用配置:
nginx复制ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
- DH参数强化(需提前生成):
bash复制sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
然后在nginx配置中添加:
nginx复制ssl_dhparam /etc/nginx/dhparam.pem;
3.3 HTTP强制跳转
在80端口server块中添加:
nginx复制server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
测试并重载配置:
bash复制sudo nginx -t && sudo systemctl reload nginx
4. 证书维护与自动化
4.1 续期机制解析
Let's Encrypt证书有效期90天,但官方建议每60天续期一次。Certbot的renew命令会检查到期时间,仅对30天内到期的证书执行更新。
手动续期测试:
bash复制sudo certbot renew --dry-run
成功输出应包含:"Congratulations, all renewals succeeded"
4.2 自动化部署方案
方案一:Systemd定时器(推荐)
创建服务文件:
bash复制sudo nano /etc/systemd/system/certbot-renew.service
内容:
code复制[Unit]
Description=Let's Encrypt Renewal
[Service]
ExecStart=/usr/bin/certbot renew --quiet
创建定时器:
bash复制sudo nano /etc/systemd/system/certbot-renew.timer
内容:
code复制[Unit]
Description=Daily renewal for Let's Encrypt
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
启用:
bash复制sudo systemctl enable --now certbot-renew.timer
方案二:Crontab传统方式
bash复制(sudo crontab -l 2>/dev/null; echo "0 3 * * * /usr/bin/certbot renew --quiet") | sudo crontab -
4.3 常见故障排查
- 续期失败:DNS记录未清除
bash复制sudo certbot renew --force-renewal
- Nginx配置冲突
bash复制sudo certbot --nginx --expand -d example.com -d www.example.com
- 证书文件损坏
bash复制sudo ls -l /etc/letsencrypt/archive/example.com/
5. 高阶技巧与安全加固
5.1 多域名合并管理
对多个主域申请统一证书:
bash复制sudo certbot certonly --manual --preferred-challenges dns \
-d example.com -d *.example.com \
-d example.org -d *.example.org
5.2 密钥轮换策略
生成新密钥并更新证书:
bash复制sudo certbot renew --key-type ecdsa --elliptic-curve secp384r1 --force-renewal
5.3 证书透明度日志
检查证书是否被记录:
bash复制sudo apt install ct-submit
ct-submit ct.googleapis.com/logs/argon2021 </etc/letsencrypt/live/example.com/cert.pem
经过这些年的运维实践,我发现90%的SSL相关问题都源于三个原因:DNS解析延迟、文件权限错误、Nginx配置语法错误。建议每次修改后使用nginx -t测试,并通过journalctl -u nginx -f实时查看日志。