NGINX: можно ли использовать сопоставление вышестоящих серверов с директивой proxy_pass?

NGINX: можно ли использовать сопоставление вышестоящих серверов с директивой proxy_pass?

У меня есть сервер NGINX, который действует как обратный прокси для группы внутренних серверов IIS. Я хотел бы передавать каждый входящий HTTPS-запрос на определенный внутренний (вышестоящий) сервер, в зависимости от указанного URI, при этом сохраняя тот же URL в адресной строке (чтобы имя внутреннего сервера или адрес оставались невидимыми для пользователей)

Например,
запрос в адресной строке выглядит так:
https://test.blahblah.com/url_a
на самом деле переходит на -->,
https://upstreamserver_a/url_a
но в адресной строке все равно выглядит так:
https://test.blahblah.com/url_a

Вот мой текущий nginx.conf:

    ## Upstreamserver_A backend for test.blahblah.com
    upstream upstreamserver_a {
            server 10.10.1.12:80; #upstreamserver_a.blahblah.com
    }

    map_hash_bucket_size 128;
    map_hash_max_size 2048;


    # URI to Server Map
    map $1 $upstream_host {
            default         whatever;
            url_a       upstreamserver_a;
    }


    ## OUR HTTP SERVER AT PORT 80
    server  {
            listen      80;
            server_name test.blahblah.com;
            index       index.html;
            root        /usr/share/nginx/html;

            ## redirect http to https ##
            proxy_redirect http:// https://;
    }


    server  {
            listen      443 ssl;
            server_name test.blahblah.com;
            #root        /usr/share/nginx/html;
        ### ssl config - customize as per your setup ###
            ssl_certificate      ssl/blahblah.com/blahblah.pem;
            ssl_certificate_key  ssl/blahblah.com/blahblah.key;
            ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
            ssl_ciphers RC4:HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers on;
            keepalive_timeout    70;
            ssl_session_cache    shared:SSL:10m;
           ssl_session_timeout  10m;


        ## PROXY backend
            location ~ ^/(.*)$ {
                    rewrite ^/([^/]+)$ https://test.blahblah.com/webapps        /Application.html?firm=$1#login break;

                    proxy_pass http://$upstream_host$uri;
            }
     }

Конечно, как только я смогу заставить один сервер работать, я добавлю несколько серверов upstream, например upstreamserver_b, upstreamserver_c и т. д.
Мне не нужна помощь с частью SSL, только сопоставление и/или ссылка на переменную.
Я доказал, что SSL работает, заменив эту строку:
proxy_pass http://$upstream_host$uri;
на
proxy_pass http://upstreamserver_a;
что работает. Также известно, что он перенаправляет на upstreamserver_a, сохраняя URL-адрес замаскированным под URL-адрес 'test.blahblah.com'.

Любая помощь будет очень ценна!
Я нашел много примеров с ответами, которые очень близки к тому, что мне нужно, но я был слишком глуп, чтобы подогнать их под свои конкретные нужды!

решение1

вам необходимо описать ваш шаблон URI в регулярном выражении и использовать его в вашем местоположении, чтобы захватить те его части, которые вы можете использовать в цели rewrite или proxy_pass. Например:

location ~ ^/url_(.).*$ {
  #this will capture your /url_a or /url_b URI's 
  #and will store the "a" or "b" into $1 variable
  #which you can use to proxy the request to a specific server
  proxy_pass http://$1.$upstreams$uri;
  #the above will result in a.<upstreams>/url_a for your example.
  #don't forget the resolver configuration for domain names.
}

Надеюсь, поможет

решение2

В зависимости от того, чего именно вы хотите, на ум приходит несколько указаний:

Например, если вы просто хотите, чтобы nginx проксировал все на ваши различные вышестоящие серверы, которые не полностью знают свои интернет-имена, и имел сопоставление между внутренними и внешними именами, то это должно подойти примерно так:

map $host $host_upstream_mapped {
    hostnames;

    test.example.su  test_iis.internal:8070;
    example.com  bleeding_edge.internal:9999;

    default  localhost:8080;
}
server {
    listen [::]:80;
    location / {
        proxy_pass http://$host_upstream_mapped$request_uri;
    }
}

P.S. Обратите внимание, что важно использовать$request_uriв этом контексте (и не только)$uri, иначе вы останетесь позади), или, в качестве альтернативы, если вы также $argsиспользуете директивы, то это также хороший вариант (обратите внимание, что эти два варианта не эквивалентны).rewrite$uri$is_args$args

Связанный контент