Opened 7 years ago
Closed 7 years ago
#1287 closed defect (duplicate)
Problem with proxy_pass when using upstream and map
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.11.x |
Keywords: | proxy_pass map upstream | Cc: | |
uname -a: | Linux corportal11t02.group.s7 3.8.13-44.1.1.el6uek.x86_64 #2 SMP Wed Sep 10 06:10:25 PDT 2014 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.12.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' |
Description
I have a problem with proxy_pass directive when using upstream name wrapped into variable via map.
This is my nginx.conf:
user nginx; worker_processes 2; worker_rlimit_nofile 30000; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; client_max_body_size 50m; sendfile on; keepalive_timeout 65; #include /etc/nginx/conf.d/*.conf; map $server_addr $backend { "default" "backend1"; "~^(172\.22\.33.*)" "backend1"; "~^(172\.20\.16.*)" "backend2"; } upstream backend1 { server 172.22.33.49; server 172.22.33.69 backup; } upstream backend2 { server 172.22.33.69; server 172.22.33.49 backup; } server { listen 172.22.33.112:80; server_name test.s7.aero; access_log /var/log/nginx/test.access.log; error_log /var/log/nginx/test.error.log; location /path1/ { proxy_pass http://backend1/simple/; } location /path2/ { proxy_pass http://backend2/simple/; } location /map/ { proxy_pass http://$backend/simple/; } } }
As you can see, I have a two backend servers, and two upstreams. I want to use different upstreams (different order of backends) depending on some external condition (map directive result). If I'm tryng proxy_pass to upstreams separately, it's ok. But if I try proxy_pass to $backend all part of url after location will be lost.
Will show in practice.
Request to first backend directly:
curl http://172.22.33.49/simple/test.html -v * Trying 172.22.33.49... * Connected to 172.22.33.49 (172.22.33.49) port 80 (#0) > GET /simple/test.html HTTP/1.1 > Host: 172.22.33.49 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.8.0 < Date: Thu, 01 Jun 2017 04:23:21 GMT < Content-Type: text/html < Content-Length: 18 < Last-Modified: Thu, 01 Jun 2017 04:22:50 GMT < Connection: keep-alive < ETag: "592f969a-12" < Accept-Ranges: bytes < I'm first backend * Connection #0 to host 172.22.33.49 left intact
Request to second backend directly:
curl http://172.22.33.69/simple/test.html -v * Trying 172.22.33.69... * Connected to 172.22.33.69 (172.22.33.69) port 80 (#0) > GET /simple/test.html HTTP/1.1 > Host: 172.22.33.69 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.8.0 < Date: Thu, 01 Jun 2017 04:23:41 GMT < Content-Type: text/html < Content-Length: 19 < Last-Modified: Thu, 01 Jun 2017 04:23:15 GMT < Connection: keep-alive < ETag: "592f96b3-13" < Accept-Ranges: bytes < I'm second backend * Connection #0 to host 172.22.33.69 left intact
Request to first upstream:
curl http://test.s7.aero/path1/test.html -v * Trying 172.22.33.112... * Connected to test.s7.aero (172.22.33.112) port 80 (#0) > GET /path1/test.html HTTP/1.1 > Host: test.s7.aero > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.12.0 < Date: Thu, 01 Jun 2017 04:24:23 GMT < Content-Type: text/html < Content-Length: 18 < Connection: keep-alive < Last-Modified: Thu, 01 Jun 2017 04:22:50 GMT < ETag: "592f969a-12" < Accept-Ranges: bytes < I'm first backend * Connection #0 to host test.s7.aero left intact
Request to second upstream:
curl http://test.s7.aero/path2/test.html -v * Trying 172.22.33.112... * Connected to test.s7.aero (172.22.33.112) port 80 (#0) > GET /path2/test.html HTTP/1.1 > Host: test.s7.aero > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.12.0 < Date: Thu, 01 Jun 2017 04:25:09 GMT < Content-Type: text/html < Content-Length: 19 < Connection: keep-alive < Last-Modified: Thu, 01 Jun 2017 04:23:15 GMT < ETag: "592f96b3-13" < Accept-Ranges: bytes < I'm second backend * Connection #0 to host test.s7.aero left intact
And now trying to request via $backend:
curl http://test.s7.aero/map/test.html -v * Trying 172.22.33.112... * Connected to test.s7.aero (172.22.33.112) port 80 (#0) > GET /map/test.html HTTP/1.1 > Host: test.s7.aero > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 403 Forbidden < Server: nginx/1.12.0 < Date: Thu, 01 Jun 2017 04:25:48 GMT < Content-Type: text/html < Content-Length: 168 < Connection: keep-alive < <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.8.0</center> </body> </html> * Connection #0 to host test.s7.aero left intact
In the backend logs I see an error:
172.22.33.112 - - [01/Jun/2017:11:25:48 +0700] "GET /simple/ HTTP/1.0" 403 168 "-" "curl/7.47.0" "-"
The problem is all data (including arguments) after /map/ will be lost.
Even if I try this:
curl http://test.s7.aero/map/a/b/d/e/f/g/h/j/k/test.html -v * Trying 172.22.33.112... * Connected to test.s7.aero (172.22.33.112) port 80 (#0) > GET /map/a/b/d/e/f/g/h/j/k/test.html HTTP/1.1 > Host: test.s7.aero > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 403 Forbidden < Server: nginx/1.12.0 < Date: Thu, 01 Jun 2017 04:31:05 GMT < Content-Type: text/html < Content-Length: 168 < Connection: keep-alive < <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.8.0</center> </body> </html> * Connection #0 to host test.s7.aero left intact
In backend logs URI the same:
172.22.33.112 - - [01/Jun/2017:11:31:05 +0700] "GET /simple/ HTTP/1.0" 403 168 "-" "curl/7.47.0" "-"
Summary: I expect the same behavior when using in proxy_pass upstream name and variable containing upstream name. But in practice first method working properly and second method not.
P.S. 403 on /simple/ is not a problem. Direct request show the same result:
P.P.S Sorry for the wrong nginx version, there isn't actual stable version in your dropdown list
curl http://172.22.33.49/simple/ -v * Trying 172.22.33.49... * Connected to 172.22.33.49 (172.22.33.49) port 80 (#0) > GET /simple/ HTTP/1.1 > Host: 172.22.33.49 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 403 Forbidden < Server: nginx/1.8.0 < Date: Thu, 01 Jun 2017 04:42:30 GMT < Content-Type: text/html < Content-Length: 168 < Connection: keep-alive < <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.8.0</center> </body> </html> * Connection #0 to host 172.22.33.49 left intact
curl http://172.22.33.69/simple/ -v * Trying 172.22.33.69... * Connected to 172.22.33.69 (172.22.33.69) port 80 (#0) > GET /simple/ HTTP/1.1 > Host: 172.22.33.69 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 403 Forbidden < Server: nginx/1.8.0 < Date: Thu, 01 Jun 2017 04:42:55 GMT < Content-Type: text/html < Content-Length: 168 < Connection: keep-alive < <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.8.0</center> </body> </html> * Connection #0 to host 172.22.33.69 left intact
Quoting documentation, as updated several days ago per ticket #803:
See http://nginx.org/r/proxy_pass for more information.