2

I have set up an nginx proxy with Openresty. The proxy takes up an HTTP SOAP POST request, modifies it by using a LUA script written within the root location ("/") of the HTTP server on port 8080, and sends it to a backend server for processing, which works correctly.

When the proxy relays the connection to the backend server, it creates a new connection, as per TCP specs, generating a new source port different from port 8080, where the backend server should respond.

Is there a way to intercept the response on nginx, so that it'll be able to intercept such response and modify it accordingly, with a LUA script?

Thanks for any insights you may be able to provide.

  • Hello again ) It seems you need a body_filter_by_lua. Can you provide more details about how do you want to alter a response? And why do you asking this on serverfault instead of stackoverflow? This is a Lua-related question. BTW, do you solve your problem with permissions? – Ivan Shatsky Dec 13 '18 at 10:55
  • Greetings Ivan, awesome to see you again around here! :) I asked the same question on Network Engineering but they said to post it here. I solved the problem trivially by installing again on Ubuntu, and your script worked perfectly. I want to reuse the same script again, but for the response. Thing is, that the session is created on another port, and I'm unable to intercept it, because it creates the session on another random TCP port (e.g. 54321) and the backend server responds on such port. Any ideas? – Alessandro Dec 13 '18 at 11:02
  • What happens next? Client established a connection with backend server on this random port? Or client tries to establish a connection on this port with a nginx server? Or this is the same server which runs nginx and backend software? Can we determine this port number from the first backend response? – Ivan Shatsky Dec 13 '18 at 11:38
  • The connection is created from the nginx server to the backend server (with the relative versions changed, if you recall), but this is being done on a random port (e.g. 54321). After that, the backend server responds on that same random port , but the proxy server is only listening on port 8080, so the response is not being intercepted and changed. – Alessandro Dec 13 '18 at 12:13
  • Maybe I don't understand your question at first. I think it is a backend server who opens a random port after first client request and awaits next client traffic on that port, something like a FTP server in active mode. Altering such traffic would be a non-trivial task, yes. But what you describing is a standard proxy behavior, any proxy software whether it nginx or squid or apache or anything else will behave that way. Why did you decide you are unable to intercept a backend response? As I said, all you need for this is to define body_filter_by_lua block after your proxy_pass directive. – Ivan Shatsky Dec 13 '18 at 12:58
1

Here is the example based on my previous answer:

    location / {
        access_by_lua '
            ngx.req.read_body()
            local body = ngx.req.get_body_data()
            body = string.gsub(body, "_v4", "_v2")
            ngx.req.set_body_data(body)
            local header = ngx.req.get_headers()["Content-Type"]
            header = string.gsub(header, "_v4", "_v2")
            ngx.req.set_header("Content-Type", header)
        ';
        proxy_pass http://192.168.1.3:1234;
        body_filter_by_lua '
            # getting response body
            local body = ngx.arg[1]
            # response body is in a "body" variable now
            # do some modifications with "body" variable
            # just an example: convert body to uppercase
            body = string.upper(body)
            # setting back modified response body
            ngx.arg[1] = body
        ';
    }

If your response body is large enough, things can be more complicated because response processed by parts (by data chunks in nginx terminology).

| improve this answer | |
  • Thanks a lot Ivan. If i need to also modify the header, do I need to put it in a variable called ngx.arg[2]? – Alessandro Dec 13 '18 at 13:43
  • No, for this you'll need to define a header_filter_by_lua block. – Ivan Shatsky Dec 13 '18 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.