stream-lua-nginx-module icon indicating copy to clipboard operation
stream-lua-nginx-module copied to clipboard

When using OpenResty as a proxy for forwarding TCP traffic, how can I obtain the address of the backend server that the client wants to access from the captured traffic?

Open ZxyNull0 opened this issue 2 years ago • 9 comments

ZxyNull0 avatar Oct 25 '23 09:10 ZxyNull0

You need to self-parse your traffic data by ngx.req.socket, Or match your protocol in the preread buffer. It depends on your traffic data pattern.

oowl avatar Oct 25 '23 09:10 oowl

您需要通过 自行解析您的流量数据ngx.req.socket,或者在预读缓冲区中匹配您的协议。这取决于您的流量数据模式。 Thank you very much for your response. I am a newcomer to OpenResty. Here is my configuration file, and I want to obtain the destination address from the raw data using ngx.req.socket, but it seems that I only get the request content without the desired destination address.

stream {
    lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;;"; 
    preread_by_lua_no_postpone on;

    lua_add_variable $tcp_backend;

    upstream backend_tcp_server {
        server 172.31.102.229:8888;
    }

    server {
        error_log "/usr/local/openresty/logs/TCP_error.log" debug;
        listen 8083;
        preread_by_lua_block {
            local sock = assert(ngx.req.socket(raw))
            local data, err = sock:receive("*a") 
            if data then
                local data_str = tostring(data)  
                ngx.log(ngx.INFO, "Raw data: ", data_str)
            else
                ngx.log(ngx.ERR, "Failed to receive data: ", err)
            end
        }

        # preread_by_lua_file "/usr/local/openresty/nginx/conf/lua/TCP_access.lua";
        # proxy_pass $tcp_backend;
        proxy_pass backend_tcp_server; 
    }
}

I am hopeful to receive your guidance and insights on this matter. image

ZxyNull0 avatar Oct 26 '23 01:10 ZxyNull0

No, I mean which have two approaches

  1. using ngx.req.socket(raw) to hook the whole proxy_pass path, that means you can not using proxy_pass
  2. using socket peek API in the preread phase to peek some traffic what do you use, that's can not break your proxy_pass https://github.com/openresty/stream-lua-nginx-module#reqsockpeek

oowl avatar Oct 26 '23 03:10 oowl

No, I mean which have two approaches

  1. using ngx.req.socket(raw) to hook the whole proxy_pass path, that means you can not using proxy_pass
  2. using socket peek API in the preread phase to peek some traffic what do you use, that's can not break your proxy_pass https://github.com/openresty/stream-lua-nginx-module#reqsockpeek My requirement is to obtain the destination address of TCP traffic redirected to OpenResty using iptables. I tried using 'peek' , as shown below, but I only received the transmitted content and did not retrieve the original destination IP.
        preread_by_lua_block{
            ngx.log(ngx.INFO,"coming in")
            local sock = assert(ngx.req.socket())
            local data = assert(sock:peek(1)) -- peek the first 1 byte that contains the length
            ngx.log(ngx.INFO, "1-----")
            data = string.byte(data)
            ngx.log(ngx.INFO, "2-----")
            ngx.log(ngx.INFO, "data:"..data)
            data = assert(sock:peek(data+1)) -- peek the length + the size byte
            ngx.log(ngx.INFO, "3-----")
            local payload = data:sub(1) -- trim the length byte to get actual payload
            ngx.log(ngx.INFO, "payload is: ", payload)
        }

ZxyNull0 avatar Oct 27 '23 06:10 ZxyNull0

No, I mean which have two approaches

  1. using ngx.req.socket(raw) to hook the whole proxy_pass path, that means you can not using proxy_pass
  2. using socket peek API in the preread phase to peek some traffic what do you use, that's can not break your proxy_pass https://github.com/openresty/stream-lua-nginx-module#reqsockpeek My requirement is to obtain the destination address of TCP traffic redirected to OpenResty using iptables. I tried using 'peek' , as shown below, but I only received the transmitted content and did not retrieve the original destination IP.
        preread_by_lua_block{
            ngx.log(ngx.INFO,"coming in")
            local sock = assert(ngx.req.socket())
            local data = assert(sock:peek(1)) -- peek the first 1 byte that contains the length
            ngx.log(ngx.INFO, "1-----")
            data = string.byte(data)
            ngx.log(ngx.INFO, "2-----")
            ngx.log(ngx.INFO, "data:"..data)
            data = assert(sock:peek(data+1)) -- peek the length + the size byte
            ngx.log(ngx.INFO, "3-----")
            local payload = data:sub(1) -- trim the length byte to get actual payload
            ngx.log(ngx.INFO, "payload is: ", payload)
        }

sock:peek(1) not contains the length. why?

Qu6133326intinaLouise avatar Nov 07 '23 07:11 Qu6133326intinaLouise

You need to write a Nginx module to get the original IP address.

zhuizhuhaomeng avatar Nov 08 '23 09:11 zhuizhuhaomeng

不,我的意思是有两种方法

  1. 使用ngx.req.socket(raw)hook整个proxy_pass路径,这意味着你不能使用proxy_pass
  2. 在预读阶段使用socket peek API来查看一些流量你用什么,这不能破坏你的proxy_pass https://github.com/openresty/stream-lua-nginx-module#reqsockpeek 我的要求是使用iptables获取目标地址重定向到 OpenResty 的 TCP 流量。我尝试使用 'peek' ,如下所示,但我只收到了传输的内容,并没有搜索到原始的目标IP。
        preread_by_lua_block{
            ngx.log(ngx.INFO,"coming in")
            local sock = assert(ngx.req.socket())
            local data = assert(sock:peek(1)) -- peek the first 1 byte that contains the length
            ngx.log(ngx.INFO, "1-----")
            data = string.byte(data)
            ngx.log(ngx.INFO, "2-----")
            ngx.log(ngx.INFO, "data:"..data)
            data = assert(sock:peek(data+1)) -- peek the length + the size byte
            ngx.log(ngx.INFO, "3-----")
            local payload = data:sub(1) -- trim the length byte to get actual payload
            ngx.log(ngx.INFO, "payload is: ", payload)
        }

sock:peek(1) 不包含长度。为什么?

The result I obtained using sock:peek(1) is a valid numerical value, representing the length of the message.

ZxyNull0 avatar Nov 09 '23 00:11 ZxyNull0

您需要编写一个Nginx模块来获取原始IP地址。

Could you please provide a more detailed explanation?,It seems that this project does not yet support this function.

ZxyNull0 avatar Nov 09 '23 01:11 ZxyNull0

This module will not provide this function. I think you can refer to https://stackoverflow.com/questions/5615579/how-to-get-original-destination-port-of-redirected-udp-message.

zhuizhuhaomeng avatar Jan 10 '24 01:01 zhuizhuhaomeng