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

NGINX不同子路径独立TLS证书配置及代理SSL证书通配问题咨询

我之前在处理多租户NGINX代理场景时碰到过完全一样的问题——NGINX原生的proxy_ssl_certificate、proxy_ssl_certificate_key和proxy_ssl_trusted_certificate确实不支持通配符或者动态变量直接配置,因为这些指令是在配置加载阶段生效的,没法根据每个请求的令牌动态调整。不过结合你已经在使用的access_by_lua_file,我们可以用OpenResty的Lua API完美解决这个问题,具体步骤如下:

解决方案思路

核心是利用OpenResty的请求阶段Lua API,在解析令牌后动态设置SSL客户端证书和信任CA,绕过原生NGINX配置阶段的限制。

1. 在令牌解析Lua脚本中提取证书信息

首先,在你的access_by_lua_file脚本里,解析令牌后把证书/密钥/CA的路径(或者直接证书内容,如果令牌里是二进制内容的话)存储到ngx.ctx(请求上下文)和ngx.var(NGINX变量)中:

-- 示例:从令牌解析出证书相关路径
local token_payload = your_token_parsing_function(ngx.var.http_authorization)

-- 把证书/密钥路径存入请求上下文,供后续SSL设置使用
ngx.ctx.dynamic_cert_path = token_payload.cert_path
ngx.ctx.dynamic_key_path = token_payload.key_path

-- 把CA路径存入NGINX变量,因为proxy_ssl_trusted_certificate支持变量
ngx.var.dynamic_ca_path = token_payload.ca_path

2. 配置NGINX location,动态加载SSL证书

在对应的location块中,使用OpenResty的lua_ssl_certificate_by_lua_block指令,在请求阶段动态加载客户端证书和密钥,同时用变量设置信任CA:

http {
    # 预定义一个变量存储动态CA路径(避免未赋值时出错)
    map "" $dynamic_ca_path {
        default "/etc/nginx/default-ca.pem";
    }

    server {
        listen 443 ssl;
        # 其他基础配置...

        location ~ ^/(analytics|topology) {
            # 先解析令牌,提取证书信息
            access_by_lua_file /path/to/your/token_parser.lua;

            # 动态设置SSL客户端证书和密钥
            lua_ssl_certificate_by_lua_block {
                local cert_path = ngx.ctx.dynamic_cert_path
                local key_path = ngx.ctx.dynamic_key_path

                -- 读取证书文件内容
                local cert_data, err = io.open(cert_path, "r"):read("*a")
                if not cert_data then
                    ngx.log(ngx.ERR, "Failed to read client cert: ", err)
                    return ngx.exit(500)
                end

                local key_data, err = io.open(key_path, "r"):read("*a")
                if not key_data then
                    ngx.log(ngx.ERR, "Failed to read client key: ", err)
                    return ngx.exit(500)
                end

                -- 设置SSL证书和密钥
                local ok, err = ngx.ssl.set_cert(cert_data)
                if not ok then
                    ngx.log(ngx.ERR, "Failed to set client cert: ", err)
                    return ngx.exit(500)
                end

                ok, err = ngx.ssl.set_priv_key(key_data)
                if not ok then
                    ngx.log(ngx.ERR, "Failed to set client key: ", err)
                    return ngx.exit(500)
                end
            }

            -- 动态设置信任的CA证书
            proxy_ssl_trusted_certificate $dynamic_ca_path;
            proxy_ssl_verify on;
            proxy_ssl_verify_depth 3;

            -- 代理到目标后端(后端地址也可以从令牌解析后动态设置)
            proxy_pass https://$dynamic_backend;
        }
    }
}

关键注意事项

  • 权限问题:确保NGINX运行用户(通常是www-data或nginx)有权限读取所有动态证书文件,否则会出现读取失败的错误。
  • 证书内容直接使用:如果你的令牌里携带的是证书的二进制内容(不是文件路径),可以直接把内容传入ngx.ssl.set_cert和ngx.ssl.set_priv_key,省去文件读取步骤,效率更高。
  • 错误处理:一定要在Lua脚本中添加错误日志和异常处理,避免因证书加载失败导致请求静默失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:21:29