相关链接
ngx_stream_pass_module:流传递模块,允许将TCP/UDP连接直接传递给指定的后端服务器。类似于HTTP中的 proxy_pass
,但用于处理TCP和UDP流量。通过 pass
指令指定后端服务器地址和端口。
ngx_stream_proxy_module:流代理模块,提供TCP和UDP流量的反向代理功能。它可以将客户端请求转发到一个或多个后端服务器,并将响应返回给客户端。常用的指令包括 proxy_pass
用于指定后端服务器地址和端口,以及各种超时和缓冲区设置。
ngx_stream_proxy_protocol_vendor_module:这是一个商业订阅模块,允许从云平台的应用特定TLV(Type-Length-Value)字段中获取连接的额外信息。它支持通过PROXY协议头获取更多关于连接的详细信息,适用于AWS、Google Cloud Platform 和 Microsoft Azure 等云平台。例如,可以提取AWS VPC端点ID、Azure私有端点LinkID和Google Cloud PSC连接ID。
ngx_stream_realip_module:真实IP模块,用于恢复客户端的真实IP地址。当Nginx位于反向代理或负载均衡器之后时,客户端的真实IP地址可能会被代理服务器的IP地址覆盖。通过配置 set_real_ip_from
和 real_ip_header
指令,可以将代理服务器传递的真实IP信息提取出来并应用到日志记录和其他逻辑中。
ngx_stream_return_module:返回模块,允许在处理过程中立即返回一个预定义的响应。这对于简单的状态码返回或错误处理非常有用。使用 return
指令可以直接返回指定的状态码和消息。
ngx_stream_set_module:变量设置模块,允许在处理过程中动态设置变量。这对于实现复杂的条件判断和逻辑控制非常有用。使用 set
指令可以在不同的处理阶段设置或修改变量值。
ngx_stream_split_clients_module:客户端拆分模块,用于根据一定的规则(如IP地址范围或哈希值)将客户端分配到不同的组别。这在A/B测试或灰度发布中非常有用,可以按比例分配流量到不同的版本或服务。常用的指令是 split_clients
,用于定义拆分规则。
ngx_stream_ssl_module:SSL/TLS支持模块,为Nginx的TCP/UDP流处理提供加密连接的能力。它允许配置SSL/TLS服务,确保数据在客户端和服务器之间的传输是安全的。常用的配置指令包括 ssl_certificate
和 ssl_certificate_key
来指定证书和私钥文件。
ngx_stream_ssl_preread_module:SSL预读模块,允许在不终止连接的情况下读取SSL/TLS握手信息。这对于需要在建立完整SSL连接之前进行某些操作(如基于SNI选择后端服务器)非常有用。使用 ssl_preread on;
指令启用此功能。
ngx_stream_pass_module 模块允许你将 TCP 或 UDP 连接直接传递给指定的后端服务器或 Unix 域套接字。这对于需要在不同的协议层之间进行流量转发的应用场景非常有用。
主要功能
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_pass_module
来实现连接传递。
将连接传递到 HTTP 服务
假设你想在一个流模块中终止 SSL/TLS 连接,并将解密后的连接传递给一个 HTTP 服务:
http {
server {
listen 8000;
location / {
root html;
}
}
}
stream {
server {
listen 12345 ssl;
ssl_certificate domain.crt;
ssl_certificate_key domain.key;
# 将解密后的连接传递给 HTTP 服务
pass 127.0.0.1:8000;
}
}
在这个例子中:
listen 12345 ssl;
监听在 12345
端口上的 SSL/TLS 流量。ssl_certificate
和 ssl_certificate_key
配置了 SSL/TLS 证书和私钥。pass 127.0.0.1:8000;
将解密后的连接传递给本地的 HTTP 服务,监听在 8000
端口。使用 Unix 域套接字
如果你想将连接传递给一个通过 Unix 域套接字监听的服务:
stream {
server {
listen 12345;
# 将连接传递给 Unix 域套接字
pass unix:/tmp/stream.socket;
}
}
在这个例子中:
listen 12345;
监听在 12345
端口上的流量。pass unix:/tmp/stream.socket;
将连接传递给位于 /tmp/stream.socket
的 Unix 域套接字。使用变量动态设置目标地址
你可以使用变量动态设置目标地址,这在需要灵活路由时非常有用:
stream {
server {
listen 12345;
# 假设 $upstream 变量已经定义好
pass $upstream;
}
}
在这个例子中:
pass $upstream;
使用 $upstream
变量动态设置目标地址。你需要确保 $upstream
变量已经在其他地方定义并赋值。注意事项
SSL/TLS 支持:
ssl_certificate
和 ssl_certificate_key
。性能考虑:
日志记录:
pass 指令用于指定 Nginx 将请求传递到的目标地址。这个指令通常用于反向代理或负载均衡配置中。
Syntax: pass address;
Default: —
Context: server
address
:目标服务器的地址(可以是 IP 地址、域名或 Unix 套接字路径)。案例
基本用法
最简单的 pass
用法是指定目标地址:
server {
listen 80;
server_name example.com;
# 将请求传递到 backend 服务器
pass 192.168.1.1:8080;
}
在这个例子中:
example.com
时,Nginx 将请求转发到 IP 地址为 192.168.1.1
,端口为 8080
的后端服务器。复杂用法
使用 upstream
定义多个后端服务器,并通过 pass
进行负载均衡:
stream {
upstream backend_tcp {
server 192.168.1.1:12345;
server 192.168.1.2:12345;
}
server {
listen 12345;
# 将请求传递到 backend_tcp 组中的服务器
pass backend_tcp;
}
}
在这个例子中:
12345
的服务时,Nginx 将请求分发到 backend_tcp
组中的两个服务器之一。注意事项
ngx_stream_proxy_module 是 Nginx 的一个核心模块,用于在流(stream)上下文中代理 TCP 和 UDP 连接。这个模块允许你将客户端的连接转发到后端服务器,并处理诸如负载均衡、会话持久性、健康检查等功能。
主要功能
使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_proxy_module
来实现不同的功能。
基本 TCP 代理
假设你希望将客户端的 TCP 连接代理到后端服务器:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
}
}
在这个例子中:
upstream backend
定义了一个名为 backend
的后端服务器组,包含一个后端服务器。server { listen 12345; proxy_pass backend; }
监听端口 12345 上的所有连接,并将其代理到 backend
组中的服务器。多台后端服务器及负载均衡
假设你有多个后端服务器,并希望通过负载均衡来分发流量:
stream {
upstream backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12345;
# 可选:配置权重
# server backend1.example.com:12345 weight=3;
# server backend2.example.com:12345 weight=1;
# 可选:配置最大失败次数和失败超时
# server backend1.example.com:12345 max_fails=3 fail_timeout=30s;
}
server {
listen 12345;
proxy_pass backend;
}
}
在这个例子中:
upstream backend
定义了三个后端服务器,Nginx 会根据默认的轮询算法(round-robin)分发连接。weight
参数可用于调整每个服务器的权重,影响其被选中的概率。max_fails
和 fail_timeout
参数可用于配置健康检查策略,如果某个服务器连续失败超过指定次数,则会在一段时间内被视为不可用。配置超时和缓冲区大小
假设你需要配置超时时间和缓冲区大小以优化性能:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
# 设置连接超时时间为 5 秒
proxy_connect_timeout 5s;
# 设置代理超时时间为 1 分钟
proxy_timeout 1m;
# 设置代理缓冲区大小为 16KB
proxy_buffer_size 16k;
}
}
在这个例子中:
proxy_connect_timeout 5s;
设置了与后端服务器建立连接的超时时间为 5 秒。proxy_timeout 1m;
设置了代理连接的超时时间为 1 分钟。proxy_buffer_size 16k;
设置了代理缓冲区大小为 16KB。结合 SSL/TLS 加密
假设你希望在代理过程中提供 SSL/TLS 加密:
stream {
upstream backend {
server backend.example.com:8883;
}
server {
listen 8883 ssl;
proxy_pass backend;
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 可选:配置其他 SSL 参数
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
}
}
在这个例子中:
listen 8883 ssl;
启用了 SSL/TLS 加密。ssl_certificate
和 ssl_certificate_key
分别指定了服务器证书和私钥文件的路径。ssl_protocols
和 ssl_ciphers
参数可用于进一步配置加密协议和密码套件。注意事项
性能优化:根据实际需求调整超时时间和缓冲区大小,避免过长的等待时间和不必要的内存占用。例如,在高并发环境中,适当减少 proxy_buffer_size
可能有助于提高性能。
安全性:确保 SSL/TLS 配置正确,使用强加密协议和密码套件。定期更新证书并检查其有效性。
健康检查:合理配置健康检查参数,如 max_fails
和 fail_timeout
,以确保在后端服务器出现故障时能够及时发现并切换到其他可用服务器。
日志管理:定期轮转日志文件,防止日志文件过大导致磁盘空间不足。可以使用工具如 logrotate
来自动化日志管理。
proxy_download_rate 指令用于设置从上游服务器下载数据的速率限制。这有助于控制带宽使用情况。
Syntax: proxy_download_rate rate;
Default: proxy_download_rate 0;
Context: stream, server
This directive appeared in version 1.9.3.
rate
:下载速率限制,单位为字节/秒,默认值为 0 表示不限制。案例
基本用法
最简单的 proxy_download_rate
用法是指定下载速率限制:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
proxy_pass backend;
# 设置下载速率为 100 KB/s
proxy_download_rate 102400; # 100 * 1024 = 102400 bytes per second
}
}
在这个例子中:
backend
下载数据时,将限制下载速率为 100 KB/s。复杂用法
根据不同的客户端 IP 地址设置不同的下载速率限制:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
if ($remote_addr = "192.168.1.10") {
proxy_download_rate 51200; # 50 KB/s for specific client
}
if ($remote_addr != "192.168.1.10") {
proxy_download_rate 102400; # 100 KB/s for other clients
}
proxy_pass backend;
}
}
在这个例子中:
192.168.1.10
,则下载速率为 50 KB/s;否则,下载速率为 100 KB/s。注意事项
proxy_half_close 指令用于控制是否启用半关闭模式。半关闭模式允许一端关闭写入操作,而另一端继续读取数据。
Syntax: proxy_half_close on | off;
Default: proxy_half_close off;
Context: stream, server
This directive appeared in version 1.21.4.
on
:启用半关闭模式。off
:禁用半关闭模式,默认行为。案例
基本用法
最简单的 proxy_half_close
用法是启用或禁用半关闭模式:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
proxy_pass backend;
# 启用半关闭模式
proxy_half_close on;
}
}
在这个例子中:
backend
通信时,如果一端关闭了写入操作,另一端仍然可以继续读取数据。复杂用法
结合不同场景启用或禁用半关闭模式:
stream {
upstream backend_tcp {
server 192.168.1.1:12345;
}
upstream backend_udp {
server 192.168.1.1:54321;
}
server {
listen 12345;
proxy_pass backend_tcp;
# 对 TCP 流量启用半关闭模式
proxy_half_close on;
}
server {
listen 54321 udp;
proxy_pass backend_udp;
# 对 UDP 流量禁用半关闭模式
proxy_half_close off;
}
}
在这个例子中:
注意事项
proxy_requests 指令用于设置每个连接的最大请求数。这有助于控制连接上的请求次数,特别是在长连接场景下。
Syntax: proxy_requests number;
Default: proxy_requests 0;
Context: stream, server
This directive appeared in version 1.15.7.
number
:每个连接的最大请求数,默认值为 0 表示不限制。案例
基本用法
最简单的 proxy_requests
用法是指定最大请求数:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
proxy_pass backend;
# 设置每个连接的最大请求数为 100
proxy_requests 100;
}
}
在这个例子中:
backend
建立连接时,每个连接最多处理 100 个请求。复杂用法
根据不同的客户端 IP 地址设置不同的最大请求数:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
if ($remote_addr = "192.168.1.10") {
proxy_requests 50; # 最大请求数为 50
}
if ($remote_addr != "192.168.1.10") {
proxy_requests 100; # 最大请求数为 100
}
proxy_pass backend;
}
}
在这个例子中:
192.168.1.10
,则每个连接的最大请求数为 50;否则,最大请求数为 100。注意事项
proxy_responses 用于在 Nginx 的流(stream)模块中指定代理服务器期望接收的响应数量。这有助于控制代理行为,特别是在处理多个响应时。
Syntax: proxy_responses number;
Default: —
Context: stream, server
This directive appeared in version 1.9.13.
number
:指定代理服务器期望接收的响应数量。案例
基本用法
最简单的 proxy_responses
用法是指定代理服务器期望接收的响应数量:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_responses 1; # 期望接收一个响应
}
}
处理多个响应
根据实际需求处理多个响应:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_responses 3; # 期望接收三个响应
}
}
注意事项
proxy_session_drop 用于控制是否在连接关闭时丢弃会话数据。启用该选项可以在某些情况下减少资源占用。
Syntax: proxy_session_drop on | off;
Default: proxy_session_drop off;
Context: stream, server
This directive appeared in version 1.15.8.
on
:在连接关闭时丢弃会话数据。off
:不丢弃会话数据(默认值)。案例
启用会话数据丢弃
最简单的 proxy_session_drop
用法是启用会话数据丢弃功能:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_session_drop on; # 在连接关闭时丢弃会话数据
}
}
禁用会话数据丢弃
根据实际需求禁用会话数据丢弃功能:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_session_drop off; # 不丢弃会话数据
}
}
注意事项
proxy_ssl 用于控制是否在代理请求中使用 SSL/TLS 加密。启用该选项可以增强安全性,但在高并发场景下可能会带来额外的性能开销。
Syntax: proxy_ssl on | off;
Default: proxy_ssl off;
Context: stream, server
on
:启用 SSL/TLS 加密。off
:禁用 SSL/TLS 加密(默认值)。案例
启用 SSL/TLS 加密
最简单的 proxy_ssl
用法是启用 SSL/TLS 加密:
stream {
server {
listen 12345 ssl;
proxy_pass backend.example.com:12345;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
proxy_ssl on; # 启用 SSL/TLS 加密
}
}
禁用 SSL/TLS 加密
根据实际需求禁用 SSL/TLS 加密:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_ssl off; # 禁用 SSL/TLS 加密
}
}
注意事项
proxy_upload_rate 用于限制从客户端到代理服务器的上传速率。这有助于控制带宽使用,特别是在有限带宽的情况下。
Syntax: proxy_upload_rate rate;
Default: proxy_upload_rate 0;
Context: stream, server
This directive appeared in version 1.9.3.
rate
:指定上传速率,单位为字节每秒(bytes per second)。如果设置为 0
,则不限制上传速率。案例
限制上传速率
最简单的 proxy_upload_rate
用法是指定上传速率:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_upload_rate 10240; # 限制上传速率为 10 KB/s
}
}
不限制上传速率
根据实际需求不限制上传速率:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_upload_rate 0; # 不限制上传速率
}
}
结合其他速率限制指令
结合其他速率限制指令进行更复杂的配置:
stream {
server {
listen 12345;
proxy_pass backend.example.com:12345;
proxy_upload_rate 10240; # 限制上传速率为 10 KB/s
proxy_download_rate 20480; # 限制下载速率为 20 KB/s
}
}
注意事项
ngx_stream_proxy_protocol_vendor_module 是一个用于流(stream)上下文的模块,它允许从云平台(如 AWS、Google Cloud Platform 和 Microsoft Azure)的应用特定 TLV(Type-Length-Value)字段中获取连接的额外信息。这些信息可以通过 PROXY 协议头进行传递。
支持的云平台
常用指令和变量
启用 PROXY 协议
在使用此模块之前,必须通过设置 proxy_protocol
参数启用 PROXY 协议。这通常在 listen
指令中完成:
server {
listen 12345 proxy_protocol;
# 其他配置...
}
内置变量
该模块提供了多个内置变量,用于提取 PROXY 协议头中的特定信息:
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_proxy_protocol_vendor_module
来获取并利用连接的额外信息。
基本配置
假设你想根据客户端连接中的信息设置 HTTP 头部,并将其转发到后端服务器:
stream {
server {
listen 12345 proxy_protocol;
# 设置 HTTP 头部以包含 GCP 连接 ID
proxy_set_header X-Conn-ID $proxy_protocol_tlv_gcp_conn_id;
# 将请求代理到后端服务器
proxy_pass backend_server;
}
}
在这个例子中:
listen 12345 proxy_protocol;
启用了 PROXY 协议。proxy_set_header X-Conn-ID $proxy_protocol_tlv_gcp_conn_id;
设置了一个自定义的 HTTP 头部 X-Conn-ID
,其值为从 PROXY 协议头中提取的 GCP 连接 ID。proxy_pass backend_server;
将请求代理到后端服务器。结合负载均衡
假设你的应用部署在多个后端服务器上,并希望通过提取的连接信息选择合适的后端服务器:
stream {
upstream backend_usa {
server backend_usa_1.example.com;
server backend_usa_2.example.com;
}
upstream backend_eu {
server backend_eu_1.example.com;
server backend_eu_2.example.com;
}
server {
listen 12345 proxy_protocol;
# 根据提取的信息选择不同的上游服务器组
if ($proxy_protocol_tlv_aws_vpce_id ~* "us-") {
proxy_pass backend_usa;
}
if ($proxy_protocol_tlv_aws_vpce_id ~* "eu-") {
proxy_pass backend_eu;
}
}
}
在这个例子中:
upstream backend_usa { ... }
和 upstream backend_eu { ... }
定义了两个不同的上游服务器组。listen 12345 proxy_protocol;
启用了 PROXY 协议。server
块中,根据 $proxy_protocol_tlv_aws_vpce_id
的值选择不同的上游服务器组进行代理。注意事项
ngx_stream_realip_module 是 Nginx 的一个模块,用于在处理 TCP 和 UDP 流量时修改客户端的真实 IP 地址。通常情况下,当使用代理或负载均衡器时,Nginx 会看到代理服务器的 IP 地址而不是客户端的真实 IP 地址。ngx_stream_realip_module
模块通过解析来自代理服务器的特定头部信息(如 X-Real-IP
或 X-Forwarded-For
),来恢复客户端的真实 IP 地址。
主要功能
常用指令
以下是与 ngx_stream_realip_module
模块相关的常用配置指令及其简要说明:
set_real_ip_from
:指定信任的代理服务器的 IP 地址或地址范围。只有来自这些地址的请求才会被信任,并从中提取真实的客户端 IP 地址。
real_ip_header
:指定用于提取客户端真实 IP 地址的头部字段。常见的头部字段包括 X-Real-IP
和 X-Forwarded-For
。
real_ip_recursive
:启用递归查找真实 IP 地址。如果设置了这个指令,Nginx 将遍历 X-Forwarded-For
头部中的所有 IP 地址,直到找到一个未被信任的 IP 地址为止。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_realip_module
来恢复客户端的真实 IP 地址。
设置信任的代理服务器和头部字段
假设你的应用部署在一个反向代理后面,并且你希望从 X-Forwarded-For
头部中提取客户端的真实 IP 地址:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置信任的代理服务器
set_real_ip_from 192.168.1.0/24; # 信任的代理服务器网段
set_real_ip_from 203.0.113.5; # 另一个信任的代理服务器
# 指定用于提取真实 IP 地址的头部字段
real_ip_header X-Forwarded-For;
proxy_pass backend_servers;
}
}
在这个例子中:
set_real_ip_from 192.168.1.0/24;
和 set_real_ip_from 203.0.113.5;
定义了信任的代理服务器网段和单个 IP 地址。real_ip_header X-Forwarded-For;
指定了用于提取客户端真实 IP 地址的头部字段为 X-Forwarded-For
。启用递归查找
如果你的应用有多层代理,你可以启用递归查找来确保找到最终的客户端 IP 地址:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置信任的代理服务器
set_real_ip_from 192.168.1.0/24; # 信任的代理服务器网段
set_real_ip_from 203.0.113.5; # 另一个信任的代理服务器
# 指定用于提取真实 IP 地址的头部字段
real_ip_header X-Forwarded-For;
# 启用递归查找
real_ip_recursive on;
proxy_pass backend_servers;
}
}
在这个例子中:
real_ip_recursive on;
启用了递归查找,Nginx 将遍历 X-Forwarded-For
头部中的所有 IP 地址,直到找到一个未被信任的 IP 地址为止。使用
X-Real-IP
头部
除了 X-Forwarded-For
,你还可以使用 X-Real-IP
头部来传递客户端的真实 IP 地址:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置信任的代理服务器
set_real_ip_from 192.168.1.0/24; # 信任的代理服务器网段
set_real_ip_from 203.0.113.5; # 另一个信任的代理服务器
# 指定用于提取真实 IP 地址的头部字段
real_ip_header X-Real-IP;
proxy_pass backend_servers;
}
}
在这个例子中:
real_ip_header X-Real-IP;
指定了用于提取客户端真实 IP 地址的头部字段为 X-Real-IP
。记录真实 IP 地址到日志
你可以将恢复后的客户端真实 IP 地址记录到日志中,便于后续分析和监控:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
log_format stream_log '$remote_addr [$time_local] '
'"$protocol" $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$realip_remote_addr"'; # 记录真实 IP 地址
server {
listen 12345;
# 设置信任的代理服务器
set_real_ip_from 192.168.1.0/24; # 信任的代理服务器网段
set_real_ip_from 203.0.113.5; # 另一个信任的代理服务器
# 指定用于提取真实 IP 地址的头部字段
real_ip_header X-Forwarded-For;
access_log /var/log/nginx/stream_access.log stream_log;
proxy_pass backend_servers;
}
}
在这个例子中:
log_format stream_log ...
定义了一个新的日志格式 stream_log
,其中包括 $realip_remote_addr
变量,用于记录恢复后的客户端真实 IP 地址。access_log /var/log/nginx/stream_access.log stream_log;
使用自定义的日志格式记录日志。注意事项
安全性:
性能考虑:
日志记录:
ngx_stream_return_module 是 Nginx 的一个模块,用于在流(stream)上下文中快速返回预定义的响应。这个模块特别适用于需要简单处理 TCP 或 UDP 连接而不进行实际代理的情况。它可以帮助你实现诸如拒绝连接、返回特定数据或执行其他简单的操作。
主要功能
return
指令可以大大简化配置文件。使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_return_module
来实现不同的功能。
拒绝所有连接
假设你希望拒绝所有到达特定端口的连接:
stream {
server {
listen 12345;
return 503; # 返回 503 Service Unavailable 状态
}
}
在这个例子中:
listen 12345;
监听端口 12345 上的所有连接。return 503;
配置了当有连接请求到达时,Nginx 将返回 503 状态码并关闭连接。返回自定义消息
假设你希望在收到连接请求时返回一个自定义的消息:
stream {
server {
listen 12345;
# 返回自定义消息
return "Connection refused by policy.\n";
}
}
在这个例子中:
return "Connection refused by policy.\n";
配置了当有连接请求到达时,Nginx 将返回一条自定义的消息并关闭连接。注意:在 stream 上下文中,直接返回文本消息并不常见,因为 TCP 和 UDP 协议本身不支持像 HTTP 那样的消息体。你可以通过其他方式如关闭连接或发送特定字节序列来实现类似的效果。
基于条件返回不同响应
假设你希望根据客户端 IP 地址返回不同的响应:
stream {
map $remote_addr $response {
default "Access denied\n";
"~^192\.168\." "Welcome to internal network\n";
}
server {
listen 12345;
# 根据映射表返回不同的响应
return $response;
}
}
在这个例子中:
map $remote_addr $response
定义了一个映射表 $response
,根据客户端 IP 地址返回不同的响应。server { listen 12345; return $response; }
根据映射表中的值返回不同的响应。结合 SSL/TLS 加密
假设你希望在返回自定义消息的同时提供 SSL/TLS 加密:
stream {
server {
listen 12345 ssl;
return "Connection refused by policy.\n";
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 可选:配置其他 SSL 参数
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
}
}
在这个例子中:
listen 12345 ssl;
启用了 SSL/TLS 加密。ssl_certificate
和 ssl_certificate_key
分别指定了服务器证书和私钥文件的路径。return "Connection refused by policy.\n";
配置了当有连接请求到达时,Nginx 将返回一条自定义的消息并关闭连接。注意事项
TCP/UDP 特性:由于 TCP 和 UDP 协议本身的特性,直接返回文本消息并不总是可行。通常情况下,return
指令主要用于关闭连接或发送特定字节序列。如果你需要更复杂的交互,可能需要考虑使用其他模块或自定义脚本。
安全性:确保 SSL/TLS 配置正确,使用强加密协议和密码套件。定期更新证书并检查其有效性。
日志记录:虽然 ngx_stream_return_module
主要用于简单的响应,但你仍然可以通过访问日志记录连接信息,以便于后续分析和调试。
ngx_stream_set_module 是 Nginx 的一个模块,用于在流(stream)上下文中动态设置变量。这个模块允许你根据连接的某些属性或条件来设置变量,并在后续处理中使用这些变量,例如路由、访问控制和日志记录等。
主要功能
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_set_module
来动态设置变量。
基本配置
假设你想根据客户端的 IP 地址设置一个变量 $client_type
,并将其用于后续处理:
stream {
# 根据客户端 IP 地址设置变量
set $client_type "untrusted";
if ($remote_addr = "192.168.1.10") {
set $client_type "trusted";
}
if ($remote_addr = "203.0.113.5") {
set $client_type "special";
}
server {
listen 12345;
proxy_pass backend_server;
# 根据变量设置不同的代理服务器
if ($client_type = "trusted") {
proxy_pass trusted_backend;
}
if ($client_type = "special") {
proxy_pass special_backend;
}
if ($client_type = "untrusted") {
proxy_pass untrusted_backend;
}
}
}
在这个例子中:
set $client_type "untrusted";
初始化变量 $client_type
。if
指令根据客户端 IP 地址更新 $client_type
的值。server
块中,根据 $client_type
的值选择不同的后端服务器进行代理。结合 map 指令
你可以使用 map
指令来简化上述配置:
stream {
# 使用 map 指令定义键值映射
map $remote_addr $client_type {
default "untrusted";
192.168.1.10 "trusted";
203.0.113.5 "special";
}
server {
listen 12345;
proxy_pass backend_server;
# 根据变量设置不同的代理服务器
if ($client_type = "trusted") {
proxy_pass trusted_backend;
}
if ($client_type = "special") {
proxy_pass special_backend;
}
if ($client_type = "untrusted") {
proxy_pass untrusted_backend;
}
}
}
其中 map
指令定义了一个键值映射表,根据 $remote_addr
的值设置 $client_type
。
结合负载均衡
假设你的应用部署在多个后端服务器上,并希望通过提取的连接信息选择合适的后端服务器:
stream {
upstream trusted_backend {
server backend_trusted_1.example.com;
server backend_trusted_2.example.com;
}
upstream special_backend {
server backend_special_1.example.com;
server backend_special_2.example.com;
}
upstream untrusted_backend {
server backend_untrusted_1.example.com;
server backend_untrusted_2.example.com;
}
# 使用 map 指令定义键值映射
map $remote_addr $client_type {
default "untrusted";
include /etc/nginx/client_types.conf;
}
server {
listen 12345;
# 根据变量选择不同的上游服务器组
if ($client_type = "trusted") {
proxy_pass trusted_backend;
}
if ($client_type = "special") {
proxy_pass special_backend;
}
if ($client_type = "untrusted") {
proxy_pass untrusted_backend;
}
}
}
其中 /etc/nginx/client_types.conf
文件的内容可能如下:
192.168.1.10 "trusted";
203.0.113.5 "special";
注意事项
map
指令代替多个 if
指令,可以提高配置的可读性和执行效率。ngx_stream_split_clients_module 是 Nginx 的一个模块,用于在处理 TCP 和 UDP 流量时根据指定的条件将客户端请求分发到不同的后端服务器组。这个模块允许你通过定义不同的分割规则来实现流量分配和 A/B 测试等功能。
主要功能
常用指令
以下是与 ngx_stream_split_clients_module
模块相关的常用配置指令及其简要说明:
split_clients
:定义分割规则,指定如何根据条件将流量分配到不同的后端服务器或上游组。
$variable
:用于生成键的变量,例如 $remote_addr
(客户端 IP 地址)、$binary_remote_addr
(二进制格式的客户端 IP 地址)、$random
(随机数)等。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_split_clients_module
来实现流量分割和 A/B 测试。
根据客户端 IP 地址分割流量
假设你想根据客户端 IP 地址将流量分配到两个不同的后端服务器组:
stream {
upstream backend_a {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
upstream backend_b {
server backend3.example.com:12345;
server backend4.example.com:12345;
}
# 定义分割规则
split_clients $binary_remote_addr $backend {
50% backend_a;
* backend_b;
}
server {
listen 12345;
# 根据分割结果选择后端服务器
proxy_pass $backend;
}
}
在这个例子中:
split_clients $binary_remote_addr $backend { ... }
定义了一个分割规则,基于二进制格式的客户端 IP 地址 $binary_remote_addr
进行分割。
50% backend_a;
表示 50% 的客户端会被分配到 backend_a
。* backend_b;
表示剩余的客户端(即另外 50%)会被分配到 backend_b
。proxy_pass $backend;
根据分割结果选择后端服务器。使用随机数进行流量分割
如果你想使用随机数而不是客户端 IP 地址来进行流量分割,可以这样做:
stream {
upstream backend_a {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
upstream backend_b {
server backend3.example.com:12345;
server backend4.example.com:12345;
}
# 定义分割规则
split_clients $remote_addr $backend {
10% backend_a;
90% backend_b;
}
server {
listen 12345;
# 根据分割结果选择后端服务器
proxy_pass $backend;
}
}
在这个例子中:
split_clients $remote_addr $backend { ... }
定义了一个分割规则,基于客户端 IP 地址 $remote_addr
进行分割。
10% backend_a;
表示 10% 的客户端会被分配到 backend_a
。90% backend_b;
表示剩余的客户端(即 90%)会被分配到 backend_b
。为了更灵活地使用随机数,可以使用 $random
变量:
stream {
upstream backend_a {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
upstream backend_b {
server backend3.example.com:12345;
server backend4.example.com:12345;
}
# 定义分割规则
split_clients $random $backend {
10% backend_a;
* backend_b;
}
server {
listen 12345;
# 根据分割结果选择后端服务器
proxy_pass $backend;
}
}
在这个例子中:
split_clients $random $backend { ... }
定义了一个分割规则,基于随机数 $random
进行分割。
10% backend_a;
表示 10% 的连接会被分配到 backend_a
。* backend_b;
表示剩余的连接(即 90%)会被分配到 backend_b
。组合多个条件进行流量分割
你可以组合多个条件来进一步细化流量分割策略。例如,根据不同的条件执行不同的操作:
stream {
upstream backend_a {
server backend1.example.com:12345;
}
upstream backend_b {
server backend2.example.com:12345;
}
upstream backend_c {
server backend3.example.com:12345;
}
# 定义分割规则
split_clients $remote_addr $backend {
10% backend_a;
20% backend_b;
* backend_c;
}
server {
listen 12345;
# 根据分割结果选择后端服务器
proxy_pass $backend;
}
}
在这个例子中:
split_clients $remote_addr $backend { ... }
定义了一个分割规则,基于客户端 IP 地址 $remote_addr
进行分割。
10% backend_a;
表示 10% 的连接会被分配到 backend_a
。20% backend_b;
表示 20% 的连接会被分配到 backend_b
。* backend_c;
表示剩余的连接(即 70%)会被分配到 backend_c
。记录分割结果到日志
你可以将分割结果记录到日志中,便于后续分析和监控:
stream {
upstream backend_a {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
upstream backend_b {
server backend3.example.com:12345;
server backend4.example.com:12345;
}
log_format stream_log '$remote_addr [$time_local] '
'"$protocol" $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$backend"'; # 记录分割结果
# 定义分割规则
split_clients $binary_remote_addr $backend {
50% backend_a;
* backend_b;
}
server {
listen 12345;
access_log /var/log/nginx/stream_access.log stream_log;
# 根据分割结果选择后端服务器
proxy_pass $backend;
}
}
在这个例子中:
log_format stream_log ...
定义了一个新的日志格式 stream_log
,其中包括 $backend
变量,用于记录分割结果。access_log /var/log/nginx/stream_access.log stream_log;
使用自定义的日志格式记录日志。注意事项
性能考虑:
安全性:
日志记录:
ngx_stream_ssl_module 是 Nginx 的一个模块,用于在流(stream)上下文中启用 SSL/TLS 加密。这个模块允许你在代理 TCP 连接时提供安全的通信通道,适用于需要加密传输的应用场景,如数据库连接、邮件服务器等。
主要功能
使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_ssl_module
来实现不同的功能。
基本 SSL/TLS 配置
假设你希望为 TCP 代理启用 SSL/TLS 加密:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345 ssl;
proxy_pass backend;
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 支持的 SSL/TLS 协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 支持的加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
}
}
在这个例子中:
listen 12345 ssl;
启用了 SSL/TLS 加密。ssl_certificate
和 ssl_certificate_key
分别指定了服务器证书和私钥文件的路径。ssl_protocols TLSv1.2 TLSv1.3;
指定了支持的 SSL/TLS 协议版本。ssl_ciphers HIGH:!aNULL:!MD5;
指定了支持的加密套件。配置会话缓存和超时
假设你希望通过会话缓存来加快后续连接的建立速度,并设置会话缓存的有效期:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345 ssl;
proxy_pass backend;
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 支持的 SSL/TLS 协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 支持的加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
# 启用会话缓存
ssl_session_cache shared:SSL:10m;
# 设置会话缓存的有效期
ssl_session_timeout 10m;
}
}
在这个例子中:
ssl_session_cache shared:SSL:10m;
启用了共享会话缓存,大小为 10MB。ssl_session_timeout 10m;
设置了会话缓存的有效期为 10 分钟。结合健康检查
假设你希望在启用 SSL/TLS 加密的同时进行后端服务器的健康检查:
stream {
upstream backend {
server backend1.example.com:12345 max_fails=3 fail_timeout=30s;
server backend2.example.com:12345 max_fails=3 fail_timeout=30s;
}
server {
listen 12345 ssl;
proxy_pass backend;
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 支持的 SSL/TLS 协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 支持的加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
# 启用会话缓存
ssl_session_cache shared:SSL:10m;
# 设置会话缓存的有效期
ssl_session_timeout 10m;
}
}
在这个例子中:
upstream backend
定义了两个后端服务器,并启用了健康检查。max_fails=3 fail_timeout=30s;
配置了健康检查参数,如果某个服务器连续失败超过 3 次,则会在 30 秒内被视为不可用。启用会话票证
假设你希望通过启用会话票证来进一步优化连接性能:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345 ssl;
proxy_pass backend;
# SSL 证书和私钥
ssl_certificate /etc/nginx/ssl/example_com.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;
# 支持的 SSL/TLS 协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 支持的加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
# 启用会话缓存
ssl_session_cache shared:SSL:10m;
# 设置会话缓存的有效期
ssl_session_timeout 10m;
# 启用会话票证
ssl_session_tickets on;
}
}
在这个例子中:
ssl_session_tickets on;
启用了会话票证,这可以帮助加速后续连接的建立。注意事项
证书管理:确保使用的证书和私钥是有效的,并定期更新证书。过期或无效的证书会导致连接失败。
协议版本:尽量使用最新的 SSL/TLS 协议版本,如 TLSv1.2
和 TLSv1.3
,并禁用不安全的旧版本,如 SSLv3
和 TLSv1.0
。
加密套件:选择强加密套件,避免使用已知存在漏洞的加密算法,如 MD5 和 RC4。
性能优化:启用会话缓存和会话票证可以显著提高性能,尤其是在高并发环境中。
日志记录:通过访问日志记录连接信息,以便于后续分析和调试。
ssl_alpn 指令用于指定支持的应用层协议(Application-Layer Protocol Negotiation, ALPN)。这个指令帮助在TLS握手过程中协商应用层协议。
Syntax: ssl_alpn protocol ...;
Default: —
Context: stream, server
This directive appeared in version 1.21.4.
protocol
:指定一个或多个支持的应用层协议。常见的协议包括 http/1.1
, h2
(HTTP/2), mqtt
, 等。案例
基本用法
最简单的 ssl_alpn
用法是指定具体的协议列表:
stream {
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_alpn http/1.1 h2;
proxy_pass backend_server;
}
}
在这个例子中:
ssl_alpn http/1.1 h2
,这意味着Nginx将支持HTTP/1.1和HTTP/2协议。动态设置不同配置
你可以根据不同的服务器块动态设置不同的协议列表:
stream {
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/example1.com.crt;
ssl_certificate_key /etc/nginx/ssl/example1.com.key;
ssl_alpn http/1.1;
proxy_pass backend_example1;
}
server {
listen 444 ssl;
ssl_certificate /etc/nginx/ssl/example2.com.crt;
ssl_certificate_key /etc/nginx/ssl/example2.com.key;
ssl_alpn h2 mqtt;
proxy_pass backend_example2;
}
}
在这个例子中:
ssl_alpn http/1.1
。ssl_alpn h2 mqtt
。注意事项
ssl_handshake_timeout 指令用于设置SSL/TLS握手的最大超时时间。这个指令帮助控制连接建立过程中的等待时间。
Syntax: ssl_handshake_timeout time;
Default: ssl_handshake_timeout 60s;
Context: stream, server
time
:指定最大等待时间,默认值为 60s
(60秒)。案例
基本用法
最简单的 ssl_handshake_timeout
用法是指定具体的时间值:
stream {
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_handshake_timeout 30s;
proxy_pass backend_server;
}
}
在这个例子中:
ssl_handshake_timeout 30s
,这意味着Nginx将在SSL/TLS握手过程中等待最多30秒。动态设置不同配置
你可以根据不同的服务器块动态设置不同的超时时间:
stream {
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/example1.com.crt;
ssl_certificate_key /etc/nginx/ssl/example1.com.key;
ssl_handshake_timeout 45s;
proxy_pass backend_example1;
}
server {
listen 444 ssl;
ssl_certificate /etc/nginx/ssl/example2.com.crt;
ssl_certificate_key /etc/nginx/ssl/example2.com.key;
ssl_handshake_timeout 90s;
proxy_pass backend_example2;
}
}
在这个例子中:
ssl_handshake_timeout 45s
。ssl_handshake_timeout 90s
。注意事项
ngx_stream_ssl_preread_module 是 Nginx 的一个模块,用于在流(stream)上下文中通过 SSL/TLS 握手数据预读取来识别客户端连接的协议类型。这个模块允许你根据客户端连接使用的协议(如 TLS 版本、SNI 主机名等)进行路由或访问控制,而无需完全解密流量。
主要功能
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_ssl_preread_module
来识别并处理 SSL/TLS 连接。
基本配置
假设你想根据客户端连接的 SNI 主机名将连接路由到不同的后端服务器:
stream {
upstream backend_example_com {
server backend1.example.com:443;
server backend2.example.com:443;
}
upstream backend_example_org {
server backend1.example.org:443;
server backend2.example.org:443;
}
map $ssl_preread_server_name $backend {
default backend_example_com;
example.org backend_example_org;
}
server {
listen 12345;
ssl_preread on;
# 根据 SNI 主机名选择不同的上游服务器组
proxy_pass $backend;
}
}
在这个例子中:
map $ssl_preread_server_name $backend { ... }
定义了一个映射表,根据 $ssl_preread_server_name
的值设置 $backend
变量。server
块中,启用 SSL/TLS 握手数据的预读取,并根据 $backend
变量选择不同的上游服务器组进行代理。基于协议版本的路由
假设你想根据客户端使用的 SSL/TLS 协议版本将连接路由到不同的后端服务器:
stream {
upstream tls12_backend {
server backend_tls12_1.example.com:443;
server backend_tls12_2.example.com:443;
}
upstream tls13_backend {
server backend_tls13_1.example.com:443;
server backend_tls13_2.example.com:443;
}
map $ssl_preread_protocol $backend {
default tls12_backend;
"TLSv1.3" tls13_backend;
}
server {
listen 12345;
ssl_preread on;
# 根据 SSL/TLS 协议版本选择不同的上游服务器组
proxy_pass $backend;
}
}
在这个例子中:
map $ssl_preread_protocol $backend { ... }
定义了一个映射表,根据 $ssl_preread_protocol
的值设置 $backend
变量。server
块中,启用 SSL/TLS 握手数据的预读取,并根据 $backend
变量选择不同的上游服务器组进行代理。结合负载均衡和 ALPN
假设你想根据客户端支持的应用层协议(ALPN)列表将连接路由到不同的后端服务器:
stream {
upstream http2_backend {
server backend_http2_1.example.com:443;
server backend_http2_2.example.com:443;
}
upstream http1_backend {
server backend_http1_1.example.com:443;
server backend_http1_2.example.com:443;
}
map $ssl_preread_alpn_protocols $backend {
default http1_backend;
"~*http/2" http2_backend;
}
server {
listen 12345;
ssl_preread on;
# 根据 ALPN 协议选择不同的上游服务器组
proxy_pass $backend;
}
}
在这个例子中:
map $ssl_preread_alpn_protocols $backend { ... }
定义了一个映射表,根据 $ssl_preread_alpn_protocols
的值设置 $backend
变量。server
块中,启用 SSL/TLS 握手数据的预读取,并根据 $backend
变量选择不同的上游服务器组进行代理。注意事项
map
指令代替多个 if
指令,可以提高配置的可读性和执行效率。ssl_preread 指令用于启用或禁用SSL预读功能。这个指令帮助在TLS握手之前读取客户端数据以决定如何处理连接。
Syntax: ssl_preread on | off;
Default: ssl_preread off;
Context: stream, server
on
:启用SSL预读功能。off
:禁用SSL预读功能(默认值)。案例
基本用法
最简单的 ssl_preread
用法是指定是否启用SSL预读功能:
stream {
upstream backend_http {
server 192.168.1.1:80;
}
upstream backend_mqtt {
server 192.168.1.2:1883;
}
map $ssl_preread_protocol $upstream {
default backend_http;
mqtt backend_mqtt;
}
server {
listen 443;
proxy_pass $upstream;
ssl_preread on;
}
}
在这个例子中:
ssl_preread on
,这意味着Nginx将在TLS握手之前读取客户端数据,并根据协议类型将请求转发到相应的上游服务器。动态设置不同配置
你可以根据不同的服务器块动态设置是否启用SSL预读功能:
stream {
upstream backend_http_1 {
server 192.168.1.1:80;
}
upstream backend_mqtt_1 {
server 192.168.1.2:1883;
}
map $ssl_preread_protocol $upstream_1 {
default backend_http_1;
mqtt backend_mqtt_1;
}
server {
listen 443;
proxy_pass $upstream_1;
ssl_preread on;
}
upstream backend_http_2 {
server 192.168.1.3:80;
}
upstream backend_mqtt_2 {
server 192.168.1.4:1883;
}
map $ssl_preread_protocol $upstream_2 {
default backend_http_2;
mqtt backend_mqtt_2;
}
server {
listen 444;
proxy_pass $upstream_2;
ssl_preread off;
}
}
在这个例子中:
ssl_preread on
。ssl_preread off
。注意事项