nginx stream realip使用

前言

由于要开始用nginx的tcp代理,发现最终http打印出来的IP都是最后一个代理的内网IP,这就不方便去查问题了。那就依样画葫芦吧。但是发现个问题,TCP层面哪里有header头啊。还好nginx提供了stream_realip这个模块。

/configure --with-http_geoip_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_v2_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-file-aio --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module --with-stream_ssl_preread_module --with-pcre --prefix=/opt/nginx


我实际的网络结构如下:

user1 ---> SLB ---> nginx tcp proxy1 ---> nginx tcp proxy2 ---> nginx http server

先说这个处理的思路吧。大家都知道tcp是没有header这些东西的,那就只能从data部分来着手了。TCP proxy_protocol的定义其实就是在数据报文最前面加上对应的IP信息。然后最后一个server解开这个data前面的IP信息。

但是一开始没有这个思路,就看了官方文档大干快上。
Module ngx_stream_realip_module

排查

把nginx tcp proxy1和proxy2的配置改成如下:

server {
    set_real_ip_from 172.16.0.0/16;
    listen 21000 so_keepalive=on;
    proxy_pass goapi;
}

其中172.16.0.0/16是当中传输的网段,然后看了下nginx http server的日志,发现没有生效啊。这文档骗人啊。

然后放狗搜了下,这个哥们一样的问题
Nginx real client IP to TCP stream backend - Stack Overflow
于是上面的配置又改成了如下:

server {
    set_real_ip_from 172.16.0.0/16;
    listen 21000 proxy_protocol so_keepalive=on;
    proxy_protocol    on;
    proxy_pass goapi;
}

 结果这样改了,连服务都不通了,curl一下直接返回400了,看了下http server的日志

~ » curl -I http://api.timoq.com
curl: (52) Empty reply from server 

172.16.106.16 api.timoq.com - [2019-12-25T19:43:50+08:00] "PROXY TCP4 172.16.0.6 172.16.0.16 21000 80" 400 631 "-" "-" "-" 0.000|-|-|-|-||-|-$
 

nginx http server收到的请求变成了”PROXY TCP4 172.16.0.6 172.16.0.16 40173 80”, 而不是实际的URL。
现象就跟下面这个的一样

Verify if nginx is working correctly with Proxy Protocol locally - Stack Overflow

这看着还是配置文件不对导致的。看来各种教程有问题啊。于是又仔细看了看了下官方文档
Accepting the PROXY Protocol | NGINX Documentation

这篇还是说的比较清楚的,也就是我前面总结的那个。那我们重新梳理一下

 

user1 ---> SLB(透明代理) --->  nginx tcp proxy1(在data头部增加realip) ---> nginx tcp proxy2(默认tcp传输,不改变数据包) ---> nginx http server(解开nginx tcp proxy1里在data里增加的realip)

去nginx http server抓包看了下,确实如此:

>E@@I0j
ueWbQ/OH
fhPROXY TCP4 222.73.97.11 192.168.0.6 53136 21000
HEAD /aaaaa HTTP/1.1
Host: api.timoq.com
User-Agent: curl/7.54.0
Accept: */*

>E@@I0j
ueWbQ/OH
fhPROXY TCP4 222.73.97.11 192.168.0.6 53136 21080
HEAD /aaaaa HTTP/1.1
Host: api.timoq.com
User-Agent: curl/7.54.0
Accept: */*

终结

因此最终的配置就是如下了:

nginx tcp proxy1

server {
    set_real_ip_from 172.16.0.0/16;
    listen 21000 so_keepalive=on;
    proxy_protocol    on;  #特别注意这个
    proxy_pass goapi;
}

 nginx tcp proxy2

server {
    set_real_ip_from 172.16.0.0/16;
    listen 21000 so_keepalive=on;
    proxy_pass goapi;
}

nginx http server

http{
log_format proxy '$proxy_protocol_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';
#注意这里proxy_protocol_addr这个变量
server
{
    listen 80 proxy_protocol; #负责解开data头部数据

    set_real_ip_from 172.16.0.0/16;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    access_log /opt/logs/nginx/proxy_api.timoq.com proxy;
    server_name api.timoq.com;
    real_ip_header  proxy_protocol;
    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;

    include conf.d/include/api.conf;
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值