我尝试使用Nginx作为我的TCP守护程序的代理,使Nginx成为SSL / TLS前端,以及加载控制。
我的后端应用程序需要真正的客户端IP,这是一个问题。
stream {
server {
listen 3333;
proxy_pass 127.0.0.1:2222;
}
}
我在docs中找到了一个解决方案:
proxy_bind $remote_addr transparent;
但它太复杂了:
"为了使此参数有效,必须运行nginx 工作进程具有超级用户权限并配置内核 路由表拦截来自代理服务器的网络流量。"
还有其他方法可以将$ remote_addr传递给后端吗?
我尝试使用sub_filter修改客户端消息体,发送http标头等等。但是所有这些只能用于http上下文,而不能用于流。
答案 0 :(得分:1)
“set_real_ip_from”指令应该是边缘设备的地址/ CIDR
sudo chown -R $(whoami) /usr/local
答案 1 :(得分:1)
我的设置:
我的要求: 在 access.log 中拥有真实的客户端 IP(而不是来自流模块的 127.0.0.1),也用于地理封锁
我的解决方案:
对于地理封锁,您还必须使用 proxy_protocol_addr,但为了简短起见,我将在此处省略对此的描述。
nginx.conf:
...
stream {
upstream ssh {
server 127.0.0.1:2222;
}
upstream https {
server 127.0.0.1:444;
}
map $ssl_preread_protocol $upstream {
default ssh;
"TLSv1.2" https;
"TLSv1.3" https;
"TLSv1.1" https;
"TLSv1.0" https;
}
server {
listen 443;
proxy_pass $upstream;
proxy_protocol on;
ssl_preread on;
}
server {
listen 2222 proxy_protocol;
proxy_pass 192.168.2.76:22;
}
}
http {
log_format main '$proxy_protocol_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
...
server {
listen 444 ssl proxy_protocol;
...
}
}
答案 2 :(得分:0)
据我所知,只有两种解决方案:proxy_bind
和proxy_protocol
。
正如您从文档中引用的那样,工作流程需要超级用户权限。明显。这不是最好的做法。此外,它可能会导致连接问题回到远程客户端。
假设Nginx作为nginx
用户运行,请运行此命令为其授予权限。
usermod -aG sudo nginx
此解决方案要求上游目的地(例如后端应用程序)接受PROXY协议。
stream {
server {
listen 3333;
proxy_pass 127.0.0.1:2222;
proxy_protocol on;
}
}
以上解决方案假设Nginx服务器是网络的入口点。如果存在边缘设备(例如负载平衡器),则很可能正在改变源IP。在这种情况下,您需要在边缘设备上启用代理协议,并在proxy_protocol
块中启用server
侦听器。我还没有测试过,但这样的事情应该可行。
stream {
server {
listen 3333 proxy_protocol;
proxy_pass 127.0.0.1:2222;
proxy_protocol on;
set_real_ip_from $proxy_protocol_addr;
}
}