Opened 6 months ago

Last modified 9 days ago

#2657 new defect

Specail redirect in location does not resolve upstream names

Reported by: AnotherOneAckap@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version:
Keywords: proxy_pass, upstream, variables Cc:
uname -a: Linux c66c82abfcc1 5.15.0-101-generic #111~20.04.1-Ubuntu SMP Mon Mar 11 15:44:43 UTC 2024 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.27.0
built by gcc 12.2.0 (Debian 12.2.0-14)
built with OpenSSL 3.0.11 19 Sep 2023
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/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-http_v3_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='-g -O2 -ffile-prefix-map=/data/builder/debuild/nginx-1.27.0/debian/debuild-base/nginx-1.27.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

Description

First things firsts: thank you for such titanic work, holding internet on your shoulders should be not easy.

So here is a self-explaining script reproducing my problem step by step.
I use official nginx image from docker hub.
The setup is simple: two nginxs, one for ingress, second impersonates some app.

(to pass antispam I had to replace http with h_t_t_p)

# common preparation
docker network create nginx_test_network

# setup ingress
tee <<CONF > ingress.conf
server {
  listen 81 default;
  server_name _;

  resolver 127.0.0.53      ipv6=off;
  set      \$app_upstream "h_t_t_p://nginx-test-app:9090";

  location / {
    proxy_pass \$app_upstream;
  }
}
CONF

docker run \
  --detach \
  --name nginx-test-ingress \
  --network nginx_test_network \
  --publish 81:81 \
  --rm \
  --volume "$(pwd)/ingress.conf":/etc/nginx/conf.d/default.conf \
  nginx:1.27

# setup app
tee <<CONF > app.conf
server {
  server_name _;
  listen 9090;

  location / {
    #add_header Content-Type text/plain;
    #return 200 "Here is an APP";
    root /usr/share/nginx/html;
  }
}
CONF

docker run \
  --detach \
  --name nginx-test-app \
  --network nginx_test_network \
  --rm \
  --volume "$(pwd)/app.conf":/etc/nginx/conf.d/default.conf \
  nginx:1.27

# setup problem
docker exec -i nginx-test-app mkdir /usr/share/nginx/html/css

# taking power nap
sleep 1

# getting troubles
curl -i "h_t_t_p://nginx-test.localhost:81/css"

# cleaning up
docker stop nginx-test-ingress nginx-test-app
docker network rm nginx_test_network

You should see in the end headers of the response

HTTP/1.1 301 Moved Permanently
Server: nginx/1.27.0
Date: Mon, 17 Jun 2024 07:51:08 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: h_t_t_p://nginx-test-app:9090/css/

So nginx made special redirect for location without trailling slash and served by proxy_pass, BUT forgot to resolve upstream defined by variable, see Location header.

May be variable is not a good idea at all, I thought, and rewrote it with upstreams

upstream app_upstream {
  server nginx-test-app:9090;
}

server {
  listen 81 default;
  server_name _;

  resolver 127.0.0.11 ipv6=off;

  location / {
    proxy_pass h_t_t_p://app_upstream;
  }
}

Upstreams did not help, the problem remains in this test case.

Change History (0)

Note: See TracTickets for help on using tickets.