Nginx: log the actual forwarded proxy_pass request URI to upstream
Asked Answered
H

2

6

I've got the following nginx conf:

http {

  log_format upstream_logging '[proxied request] '
                              '$server_name$request_uri -> $upstream_addr';
  
  access_log /dev/stdout upstream_logging;

  server {

    listen 80;
    server_name localhost;
    
    location ~ /test/(.*)/foo {
      proxy_pass http://127.0.0.1:3000/$1;
    }
  }
}

When I hit:

http://localhost/test/bar/foo

My actual output is:

[proxied request] localhost/test/bar/foo -> 127.0.0.1:3000 

While my expected output is:

[proxied request] localhost/test/bar/foo -> 127.0.0.1:3000/bar

Is there a variable or a way to produce the actual proxied URI in the log?

Hubsher answered 1/9, 2020 at 21:27 Comment(2)
darn i need that too! – Tatterdemalion
@Tatterdemalion then you may well vote the question up #reputationSeeker :) – Hubsher
A
2

If not production, you can test what is being sent by nginx after launching the simplest listening server on the desired local address and port (instead of a real one):

$ nc -l 127.0.0.1 3000
POST /some/uri HTTP/1.0
Host: 127.0.0.1
Connection: close
Content-Length: 14

some payload

Response can be simulated by manually entering HTTP/1.1 200 OK, followed with 2 new lines, while nc is running.

Ardussi answered 26/4, 2022 at 16:17 Comment(5)
Hmm, this could be an interesting work-around. πŸ˜ƒ But when I tried nc -l 127.0.0.1:3000, I got nc: getaddrinfo: nodename nor servname provided, or not known (?) – Hubsher
Thank you for the report. Sorry, I made a mistake by placing : in between host and port. They must be separated just by a space. Now I corrected the example in the answer. – Ardussi
Actually, I should've read the man page myself - sorry for that too haha. Gotta admit this is starting to look promising for a clever workaround! :) I can confirm now that at least I already partially got what I wanted: being able to see the /bar portion in the nc log when hitting localhost/test/bar/foo from the browser. Unfortunately, the response from the server didn't seem to get back to the browser (the browser kept loading). Any idea? – Hubsher
Indeed, there won't be any response. This workaround does what the original question requests - log the actual request. Response is out of the scope. If you have a real server which responds, you can monitor messages with tcpdump or wireshark. – Ardussi
Right, based on the idea of your workaround, I went down the path of setting up a small logger/forwarder using socat between nginx and my local server. Assuming my local server running on port 3000, I adapted my nginx conf to be proxy_pass http://127.0.0.1:3001/$1 and then ran socat -v tcp-listen:3001,fork tcp:localhost:3000, which did the job quite nicely. All in all, since I don't think there's a proper nginx-ic way to do it, I accept your solution for now till other better solution comes up. Thanks again! :)) – Hubsher
O
0

I have used tcpflow -cg directly inside my NGINX docker. It has a lot of output, but the interesting part is this one:

172.023.000.001.37378-172.023.000.007.00080: GET /react/home.html HTTP/1.1
Host: localhost
[...]

172.023.000.007.49748-172.023.000.002.01234: GET /home.html HTTP/1.0
Host: website-react:1234
[...]

From this you can read: http://localhost/react/home.html --> http://website-react:1234/home.html

Ornithine answered 31/1 at 19:27 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.