I currently have this nginx setup:
events {
worker_connections 4096;
}
http {
log_format upstreamlog '[$time_local] Forwarding $request from $remote_addr to: ($upstream_addr $request_uri $request) - Statuscode: $upstream_status Response time: $upstream_response_time';
log_format upstreamlogmirror '[$time_local] Forwarding mirror $request from $remote_addr to: ($upstream_addr $request_uri $request): Statuscode: $upstream_status Response time: $upstream_response_time';
server {
listen 0.0.0.0:80;
listen 0.0.0.0:443;
location / {
access_log /dev/stdout upstreamlog;
mirror /mirror;
proxy_pass https://first.service.com/api/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /mirror {
internal;
proxy_pass http://127.0.0.1:55555/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 127.0.0.1:55555;
location / {
access_log /dev/stdout upstreamlogmirror;
proxy_pass https://second.service.com/;
}
}
}
However, I am facing some difficulties with this.
It seems like the mirrored server is indeed receiving a request (I see it in the logs), but when requesting e.g. https://localhost/myroute
, it will properly forward to https://first.service.com/api/myroute
, but the second service is only sent to https://second.service.com/
without having the route appended.
I also tried to do the whole thing with this setup:
location / {
access_log /dev/stdout upstreamlog;
mirror /mirror;
proxy_pass https://first.service.com/api/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /mirror {
internal;
access_log /dev/stdout upstreamlogmirror;
proxy_pass http://second.service.com/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
This works just fine, but in this case I am not getting any logs at all.
Where am I going wrong here?
CodePudding user response:
You have to add the $request_uri
to the proxy_pass
to send the full URI to the second, mirrored backend. Just tested in my lab:
server {
listen 9001;
log_subrequest on;
access_log /var/log/nginx/mirror.log upstream_time;
location / {
mirror /mirror;
proxy_pass http://127.0.0.1:9002/;
}
location = /mirror {
proxy_pass http://127.0.0.1:8000$request_uri;
}
}
server {listen 9002; return 200 "Server 1\n";}
Make sure adding the internal
directive to the mirror location.
As responses from the mirror will be ignored I am using an Python http.server to fake my backend and see the trace the incoming requests.
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [05/Feb/2022 22:00:45] code 404, message File not found
127.0.0.1 - - [05/Feb/2022 22:00:45] "GET /test/something HTTP/1.0" 404 -
The NGINX logs after submitting a simple curl
curl 127.0.0.1:9001/test/something
127.0.0.1 - - [05/Feb/2022:22:08:46 -0500] "GET /test/something HTTP/1.1" 404 156 "-" "curl/7.29.0" upa="127.0.0.1:8000/test/something" rt=0.003 uct="0.000" uht="0.003" urt="0.003"
127.0.0.1 - - [05/Feb/2022:22:08:46 -0500] "GET /test/something HTTP/1.1" 200 9 "-" "curl/7.29.0" upa="127.0.0.1:9002/test/something" rt=0.003 uct="0.000" uht="0.001" urt="0.001"
To have the correct URI in your log file, make sure you are adding $request_uri
to your logformat. The $uri
variable will change to /mirror
.
Read more https://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri