如何在Nginx配置中为多SPA站点通过Certbot配置HTTPS
解决Nginx动态server_name下Certbot无法识别子域名的问题
从Apache2迁移至Nginx环境,使用Certbot(Let's Encrypt)为多个子域名的SPA站点配置HTTPS。为简化新增SPA流程,将所有配置集中在单个文件并通过变量管理,但动态设置的
server_name导致Certbot无法识别所有子域名,无法生成对应证书。当前配置使用map提取子域名,动态指定静态路径和WebSocket端口,需要让Certbot检测到所有subdomain.domain.fr及www.subdomain.domain.fr子域名。
方案一:使用通配符证书(推荐,适合多子域名场景)
Certbot无法识别Nginx配置中的变量式server_name,而通配符证书*.domain.fr可覆盖所有二级子域名(包括www.前缀的三级子域名),完美适配动态配置场景。
操作步骤
- 确认DNS服务商支持ACME DNS-01挑战:通配符证书必须通过DNS验证域名所有权,需确保你的DNS服务商支持Certbot对应DNS插件(如Cloudflare、Route53等主流服务商均支持)。
- 安装DNS插件:根据DNS服务商安装对应插件,例如Cloudflare用户执行:
sudo apt install certbot-dns-cloudflare - 配置DNS插件凭证:创建凭证文件(如
/etc/letsencrypt/cloudflare.ini),填入服务商API密钥/令牌:
赋予文件只读权限保证安全:dns_cloudflare_email = your-cloudflare-email@example.com dns_cloudflare_api_key = your-cloudflare-api-keysudo chmod 600 /etc/letsencrypt/cloudflare.ini - 生成通配符证书:执行命令生成覆盖所有子域名的证书:
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d *.domain.fr -d domain.fr - 修改Nginx配置启用HTTPS:
拆分HTTP和HTTPS的server块(遵循Nginx最佳实践,避免if语句):# 处理HTTP请求,统一重定向到HTTPS server { listen 80; server_name *.domain.fr domain.fr www.*.domain.fr; return 301 https://$host$request_uri; } # 处理HTTPS请求的主server块 server { listen 443 ssl http2; server_name $subdomain.domain.fr www.$subdomain.domain.fr; # SSL证书配置 ssl_certificate /etc/letsencrypt/live/domain.fr/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.fr/privkey.pem; # 可选:添加SSL优化配置(如协议、加密套件) # 静态文件服务(保留原配置) root $static_path; index index.html; location / { try_files $uri $uri/ /index.html; } # WebSocket代理配置(保留原配置) location ~* \.io { proxy_pass http://localhost:$websocket_port; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_set_header X-NginX-Proxy false; proxy_redirect off; } # 日志配置(保留原配置) error_log /var/log/nginx/${subdomain}_error.log warn; access_log /var/log/nginx/${subdomain}_access.log combined; } - 验证配置并重启Nginx:
sudo nginx -t sudo systemctl reload nginx
方案二:显式列出所有子域名生成多域名证书
若不想使用通配符证书,可通过临时显式列出所有子域名完成Certbot验证,之后恢复动态配置。
操作步骤
- 创建临时Certbot验证配置:新建
/etc/nginx/snippets/certbot-temp.conf,列出所有需要证书的子域名:server { listen 80; server_name subdomain1.domain.fr www.subdomain1.domain.fr subdomain2.domain.fr www.subdomain2.domain.fr subdomain3.domain.fr www.subdomain3.domain.fr subdomain4.domain.fr www.subdomain4.domain.fr subdomain5.domain.fr www.subdomain5.domain.fr subdomain6.domain.fr www.subdomain6.domain.fr subdomain7.domain.fr www.subdomain7.domain.fr subdomain8.domain.fr www.subdomain8.domain.fr subdomain9.domain.fr www.subdomain9.domain.fr subdomain10.domain.fr www.subdomain10.domain.fr; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } - 加载临时配置并重启Nginx:在主Nginx配置文件中添加
include /etc/nginx/snippets/certbot-temp.conf;,执行:sudo nginx -t sudo systemctl reload nginx - 生成多域名证书:执行Certbot命令,列出所有子域名:
sudo certbot certonly --nginx -d subdomain1.domain.fr -d www.subdomain1.domain.fr -d subdomain2.domain.fr -d www.subdomain2.domain.fr -d subdomain3.domain.fr -d www.subdomain3.domain.fr -d subdomain4.domain.fr -d www.subdomain4.domain.fr -d subdomain5.domain.fr -d www.subdomain5.domain.fr -d subdomain6.domain.fr -d www.subdomain6.domain.fr -d subdomain7.domain.fr -d www.subdomain7.domain.fr -d subdomain8.domain.fr -d www.subdomain8.domain.fr -d subdomain9.domain.fr -d www.subdomain9.domain.fr -d subdomain10.domain.fr -d www.subdomain10.domain.fr - 恢复动态配置:删除临时配置的
include语句,修改原server块启用HTTPS(参考方案一的HTTPS server块配置),重启Nginx。
注意事项
- 通配符证书有效期为90天,可通过
sudo certbot renew --dry-run测试自动续期是否正常。 - 新增子域名时,方案一无需修改证书,直接更新
map配置即可;方案二则需重新执行Certbot命令添加新子域名。 - WebSocket配置在HTTPS环境下无需额外修改,原有的
Upgrade和Connection头配置已适配WSS协议。
内容的提问来源于stack exchange,提问作者Seba99
相关产品推荐
相关产品推荐

