I have an interesting problem, and I thought I'd see what you guys thought would be the best solution before blindly trying random stuff.

Basically, I have two servers (one Linux and one Windows) running at my house behind a standard Linksys router. Right now Port 80 is being forwarded to my Linux machine, because it hosts a number of websites. But with the addition of my Windows server I need that to be able to use port 80 too. Obviously I can't have the router forward 80 to both, so I was wondering if there was a way to have the Linux server automatically (and transparently) tunnel/forward/whatever any requests with a given domain to the Windows machine. So when a request from the domain blah.example.com hits the Linux Server I want it to send it directly to the Windows Server to process, and if it's any other domain, the Linux Server should process it itself and not forward it. Ideally I'd like this to be done in such a way that the Windows Server doesn't need to be configured specially: it shouldn't be able to tell the difference between requests forwarded by the other server or requests forwarded directly by the router.

I understand this might require modifying the IP tables or something similar, and if so, please go slow, because I've never fooled with those before. Also, I don't have physical access right now, only SSH, so please warn me if anything you suggest might disrupt/disable the SSH connection (which would be really bad, obviously). Any help is greatly appreciated, thanks in advance! :)


Check out Apache's mod_proxy ( http://httpd.apache.org/docs/2.0/mod/mod_proxy.html ). Basically, you'll setup a VHOST for forwardthistowindows.example.com, and and tell mod_proxy to pass all those requests off to windows.example.com.

Check the documentation, but you'll probably want something like

ProxyPass / http://windows.example.com

| improve this answer | |
  • Thanks for the quick response! I got this to "work", in that it properly forwards the request, but it's not transparent. The Windows Server sees the requests as coming from the local IP of the Linux Server. Because this is going to be hosting a forum, it's vital that the Originating IPs, browser info, etc all get passed to the Windows Server exactly as the Linux Server received them. It is my understanding that this will require a routing mechanism at a much lower level than Apache. – DataWizard Jul 14 '11 at 20:59
  • No, you just have to set the headers that the proxy sends to the windows machine. I have multiple apps setup like that using nginx (see my answer) and working fine. – tomeduarte Jul 14 '11 at 21:24
  • @DataWizard fundamentally what you're asking can't happen at a lower level. The device doing the routing has to look inside the HTTP request in order to know what the hostname is. You'll need to do some research on Reverse Proxies but you can pass all of the information you want through the proxy. The hard one will be IP. You can pass it in a header or something, but the request will still come from your proxy server. – matthew Jul 14 '11 at 21:31
  • Hmm, that makes sense, because ultimately the Windows Server has to respond to the Linux Server, and thus have it's IP. I guess the difference between this and what a Router does is that in this case the domain needs to be examined, which requires it to be intercepted instead of passed directly. So I have one final question. If the proxy sends the right headers, will IIS/ASP be smart enough to use that IP when asked for within a script, or will it send the local one? I'm working with a legacy code base that probably references IP-based functions hundreds of times. – DataWizard Jul 14 '11 at 22:17
  • @DataWizard it's certainly possible but you likely will have to make some small tweaks somewhere for it to look at the header instead. I'm not really an IIS expert and without knowing your application, I can't point you to what exactly you'ld need to change. – matthew Jul 15 '11 at 0:12

In case you are not already using Apache on your Linux machine, I don't recommend you use it just to do this, it's overkill and a lot more heavy on the resources of the machine.

I recommend you use nginx: it's lightweight, stable and it's been used by major sites like wordpress.com (see here). From nginx's about page:

nginx [engine x] is a HTTP and reverse proxy server

You'll want to use nginx as a reverse proxy - here's how to do that on Ubuntu. I also recommend you look at the nginx's official wiki proxy examples.

Edit as per your comments:

To have the real IP forwarded to the windows host, set this header:

proxy_set_header  X-Real-IP  $remote_addr;

Hope that helps.

| improve this answer | |

What you probably want to do is a reverse proxy. Assuming the other websites on the linux server are running under Apache. Then using mod_proxy your config would be something like this:

<VirtualHost *:80>
    ServerName externalwin.example.com
    ProxyPass / http://internal.example.com/
    ProxyPassReverse / http://internal.example.com/ 

There are many other ways to configure a reverse proxy both with Apache and with other web or proxy server software.

The only thing you need to configure on the Windows server is to make sure any URLs output by it use the external address.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.