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 Answers 2

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

4
  • Thanks Michael! This helps, I think this means Im on the right track. But I have one qualm - my urls dont have a pattern like youre suggesting. Ie. they dont all start with the prefix "url_". Thats why im using a mapping to correlate specific URIs with specific upstream servers. Commented Dec 19, 2013 at 19:41
  • @user202985 well, you need to have a pattern, without pattern you are stuck with static mappings that you can do just with locations alone Commented Dec 19, 2013 at 20:12
  • Thanks again for the response, much appreciated. Thats really too bad....Apache has a major leg up in this scenario then, as Ive got this working on Apache - which apparently has much more versatile mapping capabilities. Im becoming more and more bitter about NGINX...what with the terrible official documentation and inaccurate wiki... But anyways thanks again, Ill mark your answer as correct. Commented Dec 19, 2013 at 22:11
  • @MichaelTabolsky hi can you answer this.. i ended up at this question with google but it doesn't seem to be it serverfault.com/questions/678521/… Commented Mar 26, 2015 at 18:06
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).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.