Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Server behind nginx reverse proxy ignores relative path in URL

My title isn't the best, my knowledge of webstuff is quite basic, sorry.

What I want to achieve

I have one box fanbox running nginx on Archlinux that I use as main entry point to my home LAN from the internet (namely work where I can only get out to port 80 and 443) via the reverse proxy facility using a changing domain name over which I have no control and that we will call home.net for now.

fanbox has its ports 80 and 443 mapped to home.net, that part was easy.

I have 2 webservers behind the firewall, web1.lan, web2.lan, web2ilo.lan. Both of these have various applications (which may have same name on different machines) that can directly be accessed on the LAN via standard URLs (the names are given as examples, I have no control over the content):

http://web1.lan/phpAdmin/
http://web1.lan/gallery/
http://web2.lan/phpAdmin/
http://web2.lan/dlna/

...and so on...

Now web2ilo.lan is a particular case. It's the out of band management web interface of the HP server web2.lan. That particular webserver offers only 1 application, so it can only be accessed via its root URL:

http://web2ilo/login.html 

My goal is to access these via subpath of home.net like this:

http://home.net/web1/phpAdmin/
http://home.net/web1/gallery/
http://home.net/web2/phpAdmin/
http://home.net/web2/dlna/
http://home.net/web2ilo/login.html

My problem

That nearly works but the web applications tend to rewrite URLs so that after I login to, respectively:

http://home.net/web1/phpAdmin/login.php
http://home.net/web2ilo/login.html

the browser is redirected respectively to

http://home.net/phpAdmin/index.php
http://home.net/index.html 

Note that the relative subpaths web1 and web2ilo have gone, which logically give me a 404.

My config

So far, I've searched a lot and I tried many options in nginx without understanding too much what I was doing. Here is my config that reproduces this problem. I've left SSL out for clarity.

   server {
      listen       443 ssl;
      server_name  localhost;

      # SSL stuff left out for clarity 

      location / {
          root   /usr/share/nginx/html;
          index  index.html index.htm;
      }

      location /web1/ {
              proxy_set_header Host $host;
              proxy_redirect off;
              proxy_pass https://web1.lan/;
      }


      location /web2/ {
              proxy_set_header Host $host;
              proxy_redirect off;
              proxy_pass https://web2.lan/;
      }

      location /web2ilo/ {
              proxy_set_header Host $host;
              proxy_redirect off;
              proxy_pass https://web2ilo.lan/;
      }

  }

After first answers

After the first couple of answers (thanks!), I realise that my setup is far from common and that I may be heading for trouble all alone.

What would then be a better idea to access the webserver behind the firewall without touching frontend ports and domain/hostname ?

like image 360
FLBzh Avatar asked Jul 08 '14 14:07

FLBzh


1 Answers

You may wish to consider the use of setting proxy_redirect to let nginx know that it should modify the "backend" server response headers (Location and Refresh) to the appropriate front-end URLs. You can either use the default setting to allow nginx to calculate the appropriate values from your location and proxy_pass directives, or explicitly specify the mappings like below:

proxy_redirect http://web1.lan/ /web1/

See: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Note: This only affects response headers - not any links in HTML content, or any Javascript.

If you experience problems with links in content or Javascript, you can either modify the content on the backend servers (which you've indicated may not be possible), or adjust your proxy solution such that front end paths are the same as the back end ones (e.g., rather than http://frontend/web1/phpAdmin you simply have http://frontend/phpAdmin). This would entail adding location directives for each application, e.g.,

location /phpAdmin/ {
     proxy_set_header Host $host;
     proxy_redirect off;
     proxy_pass https://web1.lan/phpAdmin/;
}         
like image 78
Jason Musgrove Avatar answered Oct 04 '22 20:10

Jason Musgrove