本文适用场景:通过 Nginx 部署 Hexo 博客,并实现 *.example.com
型泛域名 HTTPS 支持,通过设置泛域名证书,通过Nginx子域名部署其他服务都可以使用。
前置准备
域名要求
- 已注册主域名(如
example.com
) - 完成域名解析(将
*.example.com
A 记录指向服务器 IP)
服务器环境
nginx -v
sudo apt update && sudo apt install certbot python3-certbot-nginx
|
申请泛域名 SSL 证书
通过 Certbot 申请证书
sudo certbot certonly \ --manual \ --preferred-challenges=dns \ --server https://acme-v02.api.letsencrypt.org/directory \ -d "*.example.com" \ -d example.com
|
DNS 验证操作
根据 Certbot 提示,在域名 DNS 中添加 TXT 记录:
_acme-challenge.example.com. 300 IN TXT "gfj9X4...dyt67"
|
等待 DNS 生效(约 2-5 分钟),按回车继续
配置 Nginx 泛域名解析
基础配置示例
创建 /etc/nginx/sites-available/hexo.conf
:
{% raw %} server { listen 80; server_name ~^(?<subdomain>.+)\.example\.com$ example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name ~^(?<subdomain>.+)\.example\.com$ 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; root /var/www/hexo; index index.html; gzip on; gzip_types text/css application/json application/javascript; location / { try_files $uri $uri/ =404; } location ~* \.md$ { deny all; } } {% endraw %}
|
启用配置
sudo ln -s /etc/nginx/sites-available/hexo.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
|
配置 Systemd 定时器自动续期
启用 Certbot 官方定时器
systemctl list-timers | grep certbot
sudo systemctl enable --now certbot.timer
|
验证定时器规则
systemctl cat certbot.timer
[Timer] OnCalendar=*-*-* 00:00:00 RandomizedDelaySec=12h
|
设置续期后自动重载 Nginx
sudo nano /etc/letsencrypt/cli.ini
|
添加内容:
deploy-hook = systemctl reload nginx
|
验证与测试
手动测试续期流程
sudo certbot renew --dry-run
sudo certbot renew --force-renewal
|
查看续期日志
journalctl -u certbot.service --since "1 hour ago"
|
验证证书有效期
openssl x509 -enddate -noout -in /etc/letsencrypt/live/example.com/fullchain.pem
|
最佳实践建议
调整定时器触发时间(可选)
sudo systemctl edit certbot.timer
|
输入:
[Timer] OnCalendar=*-*-* 02:30:00 RandomizedDelaySec=0
|
重启生效:
sudo systemctl restart certbot.timer
|
监控证书状态
systemctl list-timers | grep certbot
|
故障排查
问题:定时器未触发
解决步骤:
- 检查定时器状态:
systemctl status certbot.timer
|
- 查看系统时钟同步:
- 手动触发调试:
sudo systemctl start certbot.service
|
通过以上配置,你的泛域名证书将完全由 Systemd 定时器 自动管理,无需手动干预。访问 SSL Labs 验证 HTTPS 配置完整性。
统一管理SSL配置
创建全局 SSL 配置
新建 /etc/nginx/conf.d/ssl.conf
:
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;
ssl_stapling on; ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN;
|
配置多服务代理示例
Hexo 博客配置
/etc/nginx/sites-available/hexo.conf
:
server { listen 443 ssl http2; server_name blog.example.com; include /etc/nginx/conf.d/ssl.conf; root /var/www/hexo; index index.html; location / { try_files $uri $uri/ =404; } }
|
Nextcloud 服务配置
/etc/nginx/sites-available/nextcloud.conf
:
server { listen 443 ssl http2; server_name cloud.example.com; include /etc/nginx/conf.d/ssl.conf; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
|
主域名重定向
/etc/nginx/sites-available/redirect.conf
:
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name example.com www.example.com; include /etc/nginx/conf.d/ssl.conf; # 主域名跳转到博客 return 301 https://blog.example.com; }
|
操作验证
检查语法并重载
sudo nginx -t && sudo systemctl reload nginx
|
测试所有子域名
curl -I https://blog.example.com
curl -I https://cloud.example.com
openssl s_client -connect blog.example.com:443 -status
|
维护与更新
证书续期后统一生效
所有服务共用同一证书,续期后只需一次重载:
sudo certbot renew --post-hook "systemctl reload nginx"
|
更新 SSL 配置
修改 /etc/nginx/conf.d/ssl.conf
后,所有服务自动继承新配置。
注意事项
- 避免重复包含
- 每个
server
块只能包含一次 include /etc/letsencrypt/options-ssl-nginx.conf;
- 公共配置中的参数会被 最后一个包含的文件覆盖
- 多证书混合场景
若部分服务使用独立证书,可在对应 server
块中覆盖路径:
server { listen 443 ssl http2; server_name special.example.com; ssl_certificate /path/to/special/fullchain.pem; ssl_certificate_key /path/to/special/privkey.pem; include /etc/nginx/conf.d/ssl.conf; }
|
通过这种配置,你可以实现 一处修改,全局生效,极大简化多服务的 SSL 管理。完整配置示例可参考 GitHub Gist。