16

I have two web applications (node.js express apps), web1 and web2. These web apps expect to be hosted on sites that are typically something like http://www.web1.com and http://www.web2.com. I'd like to host them behind an nginx reverse proxy as https://www.example.com/web1 and https://www.example.com/web2. I do not want to expose the two web apps as two subdomains on example.com.

Here is a snippet of my nginx configuration (without SSL termination details) that I had hoped would accomplish this:

server {
  listen 443;
  server_name .example.com;

  location /web1 {
    proxy_pass http://www.web1.com:80;
  }

  location /web2 {
    proxy_pass http://www.web2.com:80;
  }
}

This works, except for the relative links that the web apps use. So web app web1 will have a relative link like /js/script.js which won't be handled correctly.

What is the best/standard way to accomplish this?

Erik
  • 7,479
  • 8
  • 62
  • 99
  • I don't know ngix, but in the web request there is the http referrer that is the the page "preceding" the current request. Can you map the referrer in ngix? – bdn02 Jan 13 '16 at 12:15
  • I seen some places that see this as a potential solution but I am unsure of how this might be implemented. – Erik Jan 13 '16 at 14:36
  • look this: http://serverfault.com/questions/177304/different-nginx-rules-based-on-referrer – bdn02 Jan 13 '16 at 14:50

3 Answers3

4

I think something like this:

server {
  listen 443;
  server_name .example.com;
  location /web1 {
    proxy_pass http://www.web1.com:80;
  }
  location /web2 {
    proxy_pass http://www.web2.com:80;
  }
  location / {
    if ($http_referer ~* (/web1) ) {
        proxy_pass http://www.web1.com:80;
    }
    if ($http_referer ~* (/web2) ) {
        proxy_pass http://www.web2.com:80;
    }
  }
bdn02
  • 1,500
  • 9
  • 15
  • This looks pretty good. Any chance you know the what the referer header should be set to in express? – Erik Jan 13 '16 at 14:57
  • Ifs should be avoided, https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ – Bogdan M. Mar 21 '18 at 08:40
4

You should be able to do this by checking the $http_referer, something like:

location / {
  if ($http_referer ~ ^http://(www.)?example.com/web1) {
    proxy_pass http://www.web1.com:80;
  }

  if ($http_referer ~ ^http://(www.)?example.com/web2) {
    proxy_pass http://www.web2.com:80;
  }
}

The browser would be setting the referer to http://example.com/web1/some/page when it requests /js/script.js so the apps shouldn't need to change, unless they need to process or care about the referer internally.

The $http_referer does not seem to be easy to find in nginx docs, but is mentioned in a few sites:

Community
  • 1
  • 1
David Ulrich
  • 119
  • 4
1

How about using cookie and ngx_http_map_module?

Add add_header Set-Cookie "site=web1;Path=/;Domain=.example.com;"; to location /web1 {...} (web2 too).

Add map to under http

map $cookie_site $site {
  default http://www.web1.com:80;
  "web2" http://www.web2.com:80;
}

Default location is this

location / {
    proxy_pass $site;
}

You can pass the value of cookie to proxy_pass directly. But, using map is more secure way.

t_yamo
  • 781
  • 1
  • 12
  • 21