在 NGINX 反向代理上基于每个主机实施出站 PROXY 协议

在 NGINX 反向代理上基于每个主机实施出站 PROXY 协议

我有一个 NGINX 实例 (nginx/1.17.7),充当 tls 直通反向代理(不终止 TLS,而是根据 SNI 标头转发原始 tcp 连接)。

此配置的主要缺点是上游服务器无法获取真实的客户端 IP 地址,但它们只能将反向代理 IP 视为任何连接的源。

我正在尝试实施代理协议通过能够理解它的上游服务器(例如另一个 NGINX 服务器)来克服这个问题。

如果我们假设所有上游服务器都配置为同时开始接受入站代理协议,那么实现起来就非常容易。

这种配置在这种情况下效果很好:

stream {
    map $ssl_preread_server_name $name {
         www.site1.com site1_https;
         www.site2.com site2_https;
         # ...
    }

    upstream site1_https {
        server <site1 internal ip1>:443;
        # ...
    }
    upstream site2_https {
        server <site2 internal ip1>:443;
        # ...
    }
    # ...

    server {
        listen <public ip address>:443
        ssl_preread on;
        proxy_pass $name;

        # This line enable outbound PROXY Protocol to EVERY upstream server!
        proxy_protocol on;
    }
}

但是,如果您想逐步实现入站代理协议,或者您有一些上游服务器无法解码 PROXY 协议标头,那么最好能够仅将出站代理标头添加到上游服务器的子集。

到目前为止,我为实现此目标所尝试的是添加另一个映射变量来确定是否应设置 proxy_protocol:

stream {
    map $ssl_preread_server_name $name {
        www.site1.com site1_https;
        # ...
    }
    map $name $proxy_protocol_onoff {
        site1_https on;
    }
    # ...
    server {
        # ...
        proxy_pass $name;
        proxy_protocol $proxy_protocol_onoff;
# ...

但我收到以下错误:

invalid value "$proxy_protocol_onoff" in "proxy_protocol" directive, it must be "on" or "off" in /etc/nginx/nginx.conf:147

使用if指令不是一个选项,因为它们不允许在server指令内部。也proxy_protocol on;不允许定义内部上游指令。

NGINX 有可能实现这种行为吗?或者唯一的方法是切换到 HAProxy 或类似的东西?

相关内容