0

I have a network setup as illustrated below. A Windows Server 2012 R2 box with a public IP, with multiple CentOS 7 web servers behind it. Each CentOS box is a web server for multiple sites. The CentOS boxes are running Apache 2.4 and PHP 5.5.

Windows server with web servers behind

The DNS entries for all the sites point to the public IP of Win Server (1.2.3.4).

My question is: How do I most efficiently serve the sites from the CentOS boxes, through to end users?

I've been looking at IIS reverse proxies. Here's my current (super-clunky) solution:

  • Win Server gets a request for foo.com
  • The URL is re-written to com.foo.web1 and IIS includes a $_SERVER variable to feed PHP the correct URL (foo.com).
  • The Win Server hosts file says com.foo.web1 goes to the IP of Web1 (192.168.1.2)
  • Web1 has a vhost for com.foo.web1 which then serves all the stuff for foo.com.

This works but it feels like a horrible hack. Ideally, I'd like to avoid rewriting URLs. I just want to say foo.com? Send that request to 192.168.1.2. thing.com? send that to 192.168.1.3. That sounds just like DNS to me, but obviously I can't just tell the user to go to some internal IP. Maybe I actually need a forward proxy? I can't just forward port 80 because of the need to split requests between multiple servers.

I feel like this problem must have been solved before, but I can't figure it out. (I'm really a developer, not a sys-admin). Help would be much appreciated!

I dumped Win Server for Linux and used HAProxy

To save anyone who finds this from reading through all the comments, I ended up dumping Windows Server and using Linux with HAProxy. HAProxy is able to forward the requests without re-writing the URLs.

I haven't yet found a good solution for Windows, but I think this might be acceptable:

Re-write all URLs by adding a port, so:

  • foo.com -> foo.com:8081
  • bar.com -> bar.com:8081
  • thing.com -> thing.com:8082
  • stuff.com -> stuff.com:8082

Then, on the Windows Server:

  • Forward port 8081 to port 80 on Web1
  • Forward port 8082 to port 80 and Web2

This is untested.

jxmallett
  • 109
  • 1
  • 5
  • Are you open or able to turn the Windows box into another CentOS machine? If so, this becomes trivial with any of the myriad Linux reverse proxies out there. – GregL Sep 10 '15 at 23:39
  • I'd rather not, but I'm thinking that might be the best option. – jxmallett Sep 10 '15 at 23:40
  • I've never directly played with IIS's ARR features, but it seems like it might do what you need. That said, your time might be better spent setting up the box with Linux and using HAProxy or some other Linux load-balancer/reverse-proxy. Actually, now that I think of it, you might be able to do it on Windows with Apache's `mod_proxy`. – GregL Sep 10 '15 at 23:44
  • Thanks for the tip. Investigating now. It looks like `Apache's` reverse proxy has the same problem though - You need to re-write the URL, rather than just point it to an IP address. – jxmallett Sep 10 '15 at 23:50
  • `you need to rewrite the URL`, I'm not sure that's true... You should be able to make routing choices based on the `Host:` header, but I could be wrong. Although we're not supposed to provide product recommendations, I know for a fact that HAProxy can do what you want, but it's Linux only... – GregL Sep 10 '15 at 23:54
  • 1
    Looks like HAProxy may be the winner. Time to take it for a test drive! – jxmallett Sep 11 '15 at 00:16
  • 1
    And we're good. HAProxy works perfectly for this. Thanks @GregL! I'm going to investigate `Application Request Routing` before I destroy my Windows box, but it's looking like an all Linux future for me :) – jxmallett Sep 11 '15 at 00:43
  • Whow, that is amazing. Even in 2015 ARR (Application Request Routiing) for IIS was around. – TomTom May 16 '18 at 17:53

3 Answers3

1

If you have Application Request Routing (ARR) installed, you should see a new item "Server Farms" in the IIS manager.

You can create a Server Farm with a single server 192.168.1.2.

After this, you can add a reverse proxy rule (rewrite rule) for foo.com and route it to the server farm that you created in the first step.

See http://masteringlync.com/2013/02/12/using-iis-application-request-routing-arr-as-a-tmg-replacement/ for more info

anneb
  • 196
  • 2
  • 8
  • Thanks for the link. I think that's basically the solution I'm using at the moment, though it's a better explanation of the workings of IIS than I've seen. – jxmallett Sep 11 '15 at 00:56
1

I've never directly played with IIS's ARR features, but according to its docs it seems like it might do what you need:

Balance loads more efficiently across servers to maximize resource utilization

IIS Application Request Routing offers administrators the ability to create powerful routing rules based on the URL, HTTP headers, and server variables to determine the most appropriate Web application server for each request. ARR makes request routing decisions at the application level, and can be used in conjunction with hardware load balancers or Windows Network Load Balancing as an added layer of control over HTTP requests. In addition, ARR enable hosting providers to route requests from clients to specific Web application servers in a server farm by creating an affinity between the client and server.

That said, I don't know if it will actually work, or even how well. I would think perhaps your time might be better spent setting up the box with Linux and using HAProxy or some other Linux load-balancer/reverse-proxy (Nginx, Apache with mod_proxy).

In fact, you might be able to do it on Windows using Apache with mod_proxy as well.

Either way, I know for a fact that HAProxy can do exactly what you want since that's what it's meant for.

GregL
  • 9,370
  • 2
  • 25
  • 36
0

You can override DNS with the Windows hosts file (c:\windows\system32\drivers\etc\hosts), and add the line:

192.168.1.2 foo.com

Now your Windows box, will contact 192.168.1.2 for foo.com, even if foo.com has another ip in DNS.

So if systems on the internet contact foo.com, they will look up foo.com using DNS and they will connect to your Windows box. Now if you have a 'redirect' (microsoft terminology, I prefer 'reverse proxy rule') to foo.com as a redirect rule, your windows box will lookup 'foo.com' using the hosts file and connect to your internal server.

anneb
  • 196
  • 2
  • 8
  • Thanks for the response. Unfortunately I don't think it works. It seems that if IIS has a site for `foo.com` and a reverse proxy rule to redirect it to `foo.com` it will ignore any entry in the hosts file and just serve it straight from IIS. :( I completely agree that your solution *should* work though. Stupid MS... – jxmallett Sep 11 '15 at 00:11
  • I am sure this trick works for Apache and HaProxy. Maybe use Apache and mod_proxy + mod_proxyhttp instead of IIS? – anneb Sep 11 '15 at 00:13
  • IIS may have cached the ip for foo.com. Maybe restart IIS after editing the hosts file? – anneb Sep 11 '15 at 00:23
  • Looks like I'll go with HAProxy. IIS is still ignoring the hosts file after a full restart :( – jxmallett Sep 11 '15 at 00:46