Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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? #328

Open
ZxyNull0 opened this issue Oct 25, 2023 · 9 comments

Comments

@ZxyNull0
Copy link

No description provided.

@oowl
Copy link
Contributor

oowl commented Oct 25, 2023

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.

@ZxyNull0
Copy link
Author

ZxyNull0 commented Oct 26, 2023

您需要通过 自行解析您的流量数据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

@oowl
Copy link
Contributor

oowl commented Oct 26, 2023

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

@ZxyNull0
Copy link
Author

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)
        }

@Qu6133326intinaLouise
Copy link

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?

@zhuizhuhaomeng
Copy link
Contributor

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

@ZxyNull0
Copy link
Author

ZxyNull0 commented Nov 9, 2023

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

  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
Copy link
Author

ZxyNull0 commented Nov 9, 2023

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

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

@zhuizhuhaomeng
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants