跳转至

sniproxy: 基于 stream-lua-nginx-module 的 SNI 代理

安装

如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。

CentOS/RHEL 7 或 Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-sniproxy

CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-sniproxy

要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua

本文档描述了 lua-resty-sniproxy v0.22,发布于 2020 年 8 月 31 日。


该库是用 Lua 编写的 SNI 代理。TLS 解析部分是从 dlundquist/sniproxy 重写的。

请注意,nginx stream modulengx_stream_lua_module 是必需的。

在 Openresty >= 1.9.15.1 上进行了测试。

概述

stream {
    init_by_lua_block {
        local sni = require("resty.sniproxy")
        sni.rules = {
            {"www.google.com", "www.google.com", 443},
            {"www.facebook.com", "9.8.7.6", 443},
            {"api.twitter.com", "1.2.3.4"},
            {".+.twitter.com", nil, 443},
            -- 要激活此规则,您必须使用 Lua 代理
            -- {"some.service.svc", "unix:/var/run/nginx-proxy-proto.sock", nil, sni.SNI_PROXY_PROTOCOL_UPSTREAM},
            -- {"some2.service.svc", "unix:/var/run/nginx-proxy-proto.sock", nil,
            --                            sni.SNI_PROXY_PROTOCOL_UPSTREAM + sni.SNI_PROXY_PROTOCOL},
            {".", "unix:/var/run/nginx-default.sock"}
        }
    }

    # 对于 OpenResty >= 1.13.6.1,使用原生 Nginx 代理
    lua_add_variable $sniproxy_upstream;
    server {
            error_log /var/log/nginx/sniproxy-error.log error;
            listen 443;

            resolver 8.8.8.8;

            prepread_by_lua_block {
                    local sni = require("resty.sniproxy")
                    local sp = sni:new()
                    sp:preread_by()
            }
            proxy_pass $sniproxy_upstream;
    }

    # 对于 OpenResty < 1.13.6.1 或配置了 `flags`,使用 Lua 代理
    server {
            error_log /var/log/nginx/sniproxy-error.log error;
            listen 443;

            resolver 8.8.8.8;

            content_by_lua_block {
                    local sni = require("resty.sniproxy")
                    local sp = sni:new()
                    sp:content_by()
            }
    }
}

init_worker_by_lua_block 指令中应定义一个 Lua 数组表 sni_rules

第一个值可以是整个主机名或正则表达式。使用 . 作为默认主机名。如果没有匹配的条目,连接将被关闭。

第二个和第三个值是目标主机名和端口。主机可以是 DNS 名称、IP 地址或 UNIX 域套接字路径。如果主机未定义或设置为 nil,将使用 SNI 中的 server_name。如果端口未定义或设置为 nil,将使用 443

第四个值是要使用的标志。可用的标志有:

sni.SNI_PROXY_PROTOCOL -- 使用从代理协议接收到的客户端地址发送到上游
sni.SNI_PROXY_PROTOCOL_UPSTREAM -- 向上游发送代理协议 v1 握手

要使用标志,服务器必须配置为进行 Lua 代理(请参见上述示例)。

规则的应用优先级按其在表中的出现顺序进行。在上述示例中,api.twitter.com 将匹配第三条规则 api.twitter.com 而不是第四条 .+.twitter.com

如果协议版本低于 TLSv1(例如 SSLv3、SSLv2),连接将被关闭,因为这些版本不支持 SNI 扩展。

另见

GitHub

您可以在 nginx-module-sniproxy 的 GitHub 仓库 中找到此模块的其他配置提示和文档。