5

I have an NGINX server that acts as reverse proxy to a bunch of backend IIS servers. I would like to pass each incoming HTTPS request to a certain backend (upstream) server, depending on the URI specified, WHILE keeping the same URL in the address bar (to keep the backend servername or address invisible to users)

E.g.
address bar request looks like:
https://test.blahblah.com/url_a
actually goes to -->
https://upstreamserver_a/url_a
but in the address bar still looks like:
https://test.blahblah.com/url_a

Here is my nginx.conf so far:

    ## 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;
            }
     }

Of course, once I can get one server working, then I will add multiple upstream servers, eg upstreamserver_b, upstreamserver_c, etc.
I dont need help with the SSL part, just the mapping and/or variable reference.
I've proven that the SSL works by substituting this line:
proxy_pass http://$upstream_host$uri;
with
proxy_pass http://upstreamserver_a;
which works. AKA, It redirects to upstreamserver_a, while keeping the URL disguised under the url 'test.blahblah.com'.

Any help would be so much appreciated!
I have found many examples with answers that are very close to what I need, but Ive been too stupid to mold them to my particular need!

2 Answers2

2

you need to describe your URI pattern in regular expression and use it in your location to capture the parts of it that you can use in the rewrite or proxy_pass target. e.g.:

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.
}

hope it helps

1

Depending on what exactly is it that you want, there are a few directives that come to mind:

E.g., if you basically just want to have nginx proxy everything to your various upstream servers that aren't fully aware of their internet names, and have a mapping between internal and external names, then something like this should do it:

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. Note that it's important to use $request_uri in this context (and not just $uri, because otherwise you'll be leaving $args behind), or, alternatively, if you're using rewrite directives as well, then $uri$is_args$args is also a good option (note that the two are not equivalent).

cnst
  • 14,646