Nginx通配符子域名路由与Certbot证书配置问题排查
Nginx通配符子域名路由与Certbot证书配置问题排查
嘿,我帮你梳理下当前配置里的核心问题,咱们一步步解决路由跳转和SSL证书不匹配的问题:
先说说现有配置的两个关键问题
*.dev.domain.app的SSL错误:你第一个server块用了*.domain.app的证书(domain.app-0001),但这个证书只覆盖一级子域名(比如kubi.domain.app),不包含嵌套的二级子域名(xxx.dev.domain.app),所以浏览器会提示证书不匹配。kubi.domain.app误跳转到dev:现有配置里没有专门处理*.domain.app的HTTPS server块,当访问kubi.domain.app的HTTPS时,Nginx会默认匹配第一个监听443的server(也就是处理*.dev.domain.app的那个),导致被代理到3000端口的dev服务。
解决方案步骤
第一步:申请适配*.dev.domain.app的证书
要让xxx.dev.domain.app的HTTPS正常工作,你需要生成一个覆盖dev.domain.app和*.dev.domain.app的证书,用Certbot执行以下命令:
certbot certonly --nginx -d dev.domain.app -d *.dev.domain.app
执行后会生成包含这两个域名的新证书,路径会在输出里显示,后续配置要用到。
第二步:替换为结构化的Nginx配置
把原来的配置替换成下面的版本,逻辑更清晰,也解决了路由和证书问题:
# 所有HTTP请求强制跳转到HTTPS,统一处理 server { listen 80 default_server; server_name _; return 301 https://$host$request_uri; } # 处理 dev.domain.app 和 *.dev.domain.app → 代理到dev服务(3000) server { listen 443 ssl; server_name dev.domain.app ~^(?<subdomain>.+)\.dev\.domain\.app$; # 这里用新生成的证书路径,如果还没生成,先完成第一步 ssl_certificate /etc/letsencrypt/live/dev.domain.app/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dev.domain.app/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:3000; proxy_set_header Host $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; } } # 处理所有 *.domain.app(除了dev)→ 代理到prod服务(5000) server { listen 443 ssl; server_name ~^(?<subdomain>.+)\.domain\.app$; # 使用你的*.domain.app证书 ssl_certificate /etc/letsencrypt/live/domain.app-0001/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.app-0001/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:5000; proxy_set_header Host $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; } } # 处理主域名 domain.app → 代理到prod服务(5000) server { listen 443 ssl; server_name domain.app; ssl_certificate /etc/letsencrypt/live/domain.app/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.app/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:5000; proxy_set_header Host $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; } }
配置调整说明
- 统一HTTP跳转:用一个默认server把所有80端口请求转HTTPS,避免之前分散的80配置,逻辑更简洁。
- 证书精准匹配:每个server块对应匹配的证书,
*.dev.domain.app用专门的通配符证书,*.domain.app用对应的通配符证书,解决SSL不匹配问题。 - 路由优先级优化:Nginx会优先匹配更具体的
server_name,比如dev.domain.app会被第一个server块捕获,而kubi.domain.app会匹配第二个处理*.domain.app的server块,不会再误跳转到dev。
最后验证
配置修改后,重启Nginx生效:
sudo systemctl restart nginx
然后测试各个域名:
dev.domain.app→ 正常跳转到3000xxx.dev.domain.app→ SSL正常,跳转到3000kubi.domain.app→ 正确跳转到5000domain.app→ 正常跳转到5000
备注:内容来源于stack exchange,提问作者Kubi
相关产品推荐
相关产品推荐

