You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx使用server_name正则时,如何正确获取请求域名捕获变量?

Nginx动态子域名SSL证书加载问题解决

问题根源

你遇到的核心问题是SSL证书加载时机早于server块正则变量捕获时机:

  • Nginx在SSL握手阶段就需要确定使用的证书,这一步发生在server块匹配之前;
  • 你通过server_name ~^(?<custom_domain>[^.]+)\.捕获的$custom_domain变量,要到server块匹配完成后才会被赋值,所以加载证书时这个变量是空的;
  • 用$host返回正则表达式,是因为Nginx还没完成域名解析就尝试读取证书,此时$host并未指向实际请求的域名。

修复方案

要实现动态加载子域名证书,得用map模块提前从请求域名提取子域名,同时依赖SNI(Nginx 0.9.8+默认支持)来在握手阶段匹配证书:

1. 全局添加map配置

在http块(所有server块外面)添加map,从$host里提取第一个子域名:

http {
    # 其他全局配置...

    map $host $custom_domain {
        ~^(?<sub>[^.]+)\. $sub;
        default "";
    }

    # 下面放你的server块
}

2. 修改server块配置

调整server块的匹配规则和证书路径:

server {
    listen 80;
    listen 443 ssl;

    # 匹配所有带点的域名(覆盖子域名场景)
    server_name ~^[^.]+\..+$;

    # 用map提取的变量加载证书
    ssl_certificate /var/www/faqnation-server/issued_certs/${custom_domain}__issued_cert.pem;
    ssl_certificate_key /var/www/faqnation-server/issued_certs/${custom_domain}__issued_cert.key;

    # 可选:开启OCSP stapling优化SSL性能
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    location / {
        proxy_pass http://127.0.0.1:4178;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3. 验证步骤

  • 检查配置语法:nginx -t
  • 重载Nginx:systemctl reload nginx
  • 确保证书目录权限正确:执行chown -R nginx:nginx /var/www/faqnation-server/issued_certs/让Nginx能读取证书文件

内容的提问来源于stack exchange,提问作者Ashu Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:25:58