﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
2103	First declared upstream site returns 403 forbidden when used with proxy_pass	dant89@…		"I have a versioned API with two separate repository file paths, I'm trying to use location matching combined with proxy_path to route to the applicable upstream server.

All of the paths work apart from the root path for the first upstream server, for example:

Works:
- api.com/api/v1/endpoint - 200 response
- api.com/api/v2 - 200 response
- api.com/api/v2/endpoint - 200 response

Does not work:
- api.com/api/v1 - 403 Forbidden

For some reason the non working URL returns a 301, redirects to the same url with a slash on the end and then looks in the wrong location for the file. This seems strange because other URLs such as api/v1/endpoint do not do this behaviour and serve from the correct server folder.

access log
{{{
127.0.0.1 - - [02/Dec/2020:16:19:09 +0000] ""GET /api/v1 HTTP/1.0"" 301 194 ""-"" ""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36""
127.0.0.1 - - [02/Dec/2020:16:19:09 +0000] ""GET /api/v1/ HTTP/1.0"" 403 580 ""-"" ""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36""
}}}

error log
{{{
2020/12/02 16:19:09 [error] 3286#3286: *7 directory index of ""/srv/api-v1/public/api/v1/"" is forbidden, client: 127.0.0.1, server: api, request: ""GET /api/v1/ HTTP/1.0"", host: ""api""
}}}

This is with the following configuration:
{{{
upstream v1 {
    server 127.0.0.1;
}

upstream v2 {
    server 127.0.0.1;
}

server {
    listen 443 http2;
    listen [::]:443 http2;
    server_name api.com;
 
    location /api/v1 {
        proxy_pass http://v1;
    }

    location /api/v2 {
        proxy_pass http://v2;
    }
}

server {
    server_name v1;
    root /srv/api-v1/public/;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        include /etc/nginx/fastcgi.conf;
        fastcgi_pass unix:/run/php-fpm-php7.2.socket;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        internal;
    }
}

server {
    server_name v2;
    root /srv/api-v2/public/;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        include /etc/nginx/fastcgi.conf;
        fastcgi_pass unix:/run/php-fpm-php7.2.socket;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        internal;
    }
}
}}}


I have documented the issue here in the *Attempted fix* section: https://stackoverflow.com/questions/65093486/nginx-alias-breaks-due-to-try-files-uri-alias-bug"	defect	closed	major		nginx-core	1.14.x	invalid			Linux censored.net 4.15.0-124-generic #127-Ubuntu SMP Fri Nov 6 10:54:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux	"nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.1  11 Sep 2018
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-GkiujU/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-headers-more-filter --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-cache-purge --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-ndk --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-fancyindex --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/nchan --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-lua --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/rtmp --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-uploadprogress --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-GkiujU/nginx-1.14.0/debian/modules/http-subs-filter
"
