在 Nginx 中,四层的数据被称为 stream,和四层代理有关的模块主要有:
ngx_stream_core_module:四层代理的基本功能模块
ngx_stream_upstream_module:四层代理转发到上游的模块
ngx_stream_proxy_module:四层代理相关配置
其他 stream 相关模块用于如 SSL 支持、geoip 支持、简单访问控制支持等,本次测试并没有使用到。
使用的注意事项
Nginx 的四层反代功能较为简单,其访问控制模块因为源站 IP 可以进行伪造,基本不可用于 UDP Flood 的防护。
使用健康检测功能的前提是他们在一个共享内存的 zone 里,注意各个区块的层次关系即可,zone 是配置上游服务器组共享内存的功能,因此 zone 要放在 upstream 区块。status 命令即监控dashboard 是 ngx_http_status_module 的内容,严格来说不是四层代理的部分。
我使用的 UDP 反代配置:
stream {
upstream dns_server {
zone stream_dns 10m;
server 127.0.0.1:53;
}
match dns {
send \x00\x2a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06\x73\x65\x72\x76\x65\x72\x0a\x73\x74\x61\x72\x64\x75\x73\x74\x65\x72\x02\x6d\x65\x00\x00\x01\x00\x01;
expect ~* \x6a;
}
server {
listen 10086 udp;
proxy_pass dns_server;
error_log /home/nginx/dns-error.log debug;
health_check udp match=dns interval=1s;
status_zone stream_dns;
}
}
健康检测页面配置:
server {
listen 8080;
root /usr/share/nginx/html;
location /status {
status;
}
location = /status.html {
}
}
ngx_stream_core_module
ngx_stream_core_module 模块从1.9.0版本开始提供,默认编译不包含此模块,需要在编译参数中加上--with-stream。
语法:listen address:port [ssl] [udp] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
环境:server
设置接受连接的端口和地址,可以只有端口号,也可以包含IP或主机名。
listen 127.0.0.1:12345;
listen *:12345;
listen 12345; # same as *:12345
listen localhost:12345;
IPV6 地址需要使用中括号标注:
Shell
listen [::1]:12345;
listen [::]:12345;
1
2
listen [::1]:12345;
listen [::]:12345;
Unix socket 需要使用前缀“Unix:”
listen unix:/var/run/nginx.sock;
ssl 参数所有连接都需要使用 SSL 加密;
udp 参数指定监听 UDP 端口(从1.9.13版本开始支持);
其他相关参数:
backlog=number 参数设置 listen() 调用的最大等待连接队列数,默认情况下,backlog 在 BSD 上被设置为-1,在其他平台被设置为511;
bind 参数使用所给的 address:port 产生一个独立的 bind() 调用,用于使用多个 listen 命令监听不同地址上的相同端口号;
ipv6only=on|off 参数,配置 [::] 监听地址是否接受 IPV4 请求,此选项默认为 on;
reuseport 参数(从1.9.1开始支持)为每个 worker 进程独立地创建一个监听的 socket(使用 SO_REUSEPORT),允许内核将入站连接分发到不同 worker 进程,仅支持 Linux3.9+ 和 DragonFly BSD;
so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt] 参数配置 TCP keepalive 特性;
不同的 Server 区块必须 listen 不同的地址+端口组合。
语法:resolver address … [valid=time] [ipv6=on|off];
环境:server
配置解析 upstream 域名所使用的 DNS 服务器:
resolver 127.0.0.1 [::1]:5353;
地址可以以 IP 或者域名的形式给出,也可以附带端口号。默认情况下,nginx 会解析 V4 和 V6 地址,并会在 TTL 时间内缓存解析结果。
语法:resolver_timeout time;
默认:30秒
环境:stream,server
(从1.11.3版本开始提供)
设置 DNS 解析超时时间。
语法:server {…}
环境:stream
设置一个独立的 Server。
语法:stream {…}
环境:main
提供四层代理的 Server 的配置环境,和 http {…} 类似。
语法:tcp_nodelay on | off;
默认:on
环境:stream,server
(从1.9.4版本开始提供)
开启或关闭 TCP_NODELAY 选项,这个选项将会同时应用于到客户端和到上游服务器的连接。
语法:variables_hash_bucket_size size;
默认:64
环境:stream
(从1.11.2版本开始提供)
设置变量 hash 表的桶大小,详细设置参见独立文档
语法:variables_hash_max_size size;
默认:1024
环境:stream
(从1.11.2版本开始提供)
设置 hash 表的最大大小,详细设置参见独立文档
内置变量,(ngx_stream_core_module 模块从1.11.2开始支持变量):