Multiple Web Servers over a Single IP, Using Apache as a Reverse Proxy

Multiple Web Servers over a Single IP, Using Apache as a Reverse Proxy

As a developer, I don’t get to play with the IT side of things quite as much as I would like to.  So I enjoy the little things, like learning how to use a reverse proxy on Apache.  At home, I only have one IP coming in with my regular Internet connection, and I want the ability to run multiple servers inside my network on port 80. In the past, I’ve always just setup a new port and routed it to whichever server I wanted. 8080 here, 8081 there, etc. Well with Apache reverse proxy (mod_proxy), I found it was very easy to setup route requests to other internal servers.

reverse_proxy

This diagram shows the basic idea of what I’m doing.  I have a “landing” server that takes all the traffic from the router. Using virtual hosts, I filter the web traffic by hostname and then provide mod_proxy directives to hand off the requests to other internal web servers.  Options like ProxyPreserveHost allow you to hand off the original hostname in the request so you can further use hostname filtering on the secondary servers.

Here is an example of the landing server configuration.

NameVirtualHost *:80

<VirtualHost *:80>
  ServerName foo.com

  DocumentRoot /srv/www/default

  <Location "/">
    Allow from all
    Order allow,deny
  </Location>
</VirtualHost>

<VirtualHost *:80>
  ServerName fooa.com

  ProxyPreserveHost on
  ProxyPass / http://server2/
  ProxyPassReverse / http://server2/
</VirtualHost>

<VirtualHost *:80>
  ServerName foob.com
  ServerAlias fooc.com

  ProxyPreserveHost on
  ProxyPass / http://server3/
  ProxyPassReverse / http://server3/
</VirtualHost>

You can see here, that the default site [foo.com] actually his hosted by the landing server. The rest of the hostnames are passed on to the other internal servers.  You can also proxy just virtual directories as well. So if you want the requested path, “/something-foo” to go to another internal server, you can. You just use /something-foo as the first argument in ProxyPass and ProxyPassReverse.

The other web servers would have normal configurations like this one below. You can also proxy requests to other web servers like IIS. The proxy will handle basic authentication with an internal Windows IIS server.

NameVirtualHost *:80

<VirtualHost *:80>
  ServerName fooa.com

  DocumentRoot /srv/www/fooa.com

  <Location "/">
    Allow from all
    Order allow,deny
  </Location>
</VirtualHost>

That’s it!

18 Comments

  • Nathan on Jan 12, 2012

    @xahoor
    That sounds like what I described above. In the end, this is just a reverse proxy by hostname. So one server will receive all the traffic on port 80. Then by the requested hostname, some of the traffic will be peeled off and routed to the other server.

    Make sense?

    So Server A can still handle whatever you want it to, and for the sites that are handled by Server B, just reverse proxy them over using the info above.

    Is there a specific issue you’re running into?

  • xahoor on Jan 10, 2012

    Hi everybody,
    I am stuck here…. I have only one IP address but two different applications servers running here to share the same IP. Let us suppose that Server A and Server B with different applications and both are running with CentOS.
    It is needed that request for any server should be received by anyone of the above and should be forwarded to the other if request is for the other.
    Specially requested to Nathan.

  • Nathan on Mar 03, 2011

    @Ade
    I’m not sure how much I can help you with that. My setup at home only requires one machine with SSL so I just translate port 443 in directly to the server that uses it. But after some googling, I found this link which may help. It seems you can proxy an SSL connection with a little setup.

    http://www.wlug.org.nz/ApacheReverseProxy

    Good luck!

  • Ade on Mar 03, 2011

    Nathan,

    Thanks for the information. I have been racking my brains as to how to create a reverse proxy with cent os. I wish to do the following

    me.mysite.com > 192.168.1.0
    you.mysite.com > 192.168.2.0
    it.mysite.com > 192.168.3.0

    Is it possible for me to do the above and have the connection operate both http & https. The reason I say this is that one of my internal servers me.mysite.com connects initially with http and then on clicking a login link changes over to https. This has blow my mind a bit is there any way you could enlighten me by way of example as to a config or anything special required to overcome such a thing?.

    Thanks for your time.

  • Nathan on Nov 18, 2010

    @Amar

    Well not knowing exactly what your config looks like, that seems to be correct; although I haven’t tried using a proxy over a second tier. I think Aliases and directories will take precedence over ProxyPass; so be sure you’re not overriding the proxy directive on server 2. (I’m assuming the requests are making it to server2)? One of the things I did while testing virtual directory proxy was to setup a documentroot on the virtualhost so if the request was not routed, I could clearly see it was served directly and which server it was served from by putting that info in an html doc in the request.

    Hope that helps!

  • Amar on Nov 18, 2010

    Nathan,

    Excellent posting. Question on proxy/reverse proxy with zone restrictions and two apache’s with multiple application servers.

    apache1 (zone1:server1:443) -> apache2(zone2:server2:80) –> apps2(zone2:server2:port1), apps3(zone2:server3:port1), apps4(zone2:server4:port1)

    Posting the sample config below for apache1 and apache2

    #
    #apache1 (landing config)
    #

    ProxyPreserveHost on

    ProxyPass / http://server2:80/
    ProxyPassReverse / http://server2:80/

    #
    #apache2 (This is where I am having trouble)
    #

    ProxyPreserveHost on

    #this application works as apache2 and apps2 are on the same server.
    ProxyPass /apps2 http://server2:port1/
    ProxyPassReverse /apps2 http://server2:port1/

    #no luck with this app. App sits on a server different from apache2 server
    ProxyPass /apps3 http://server3:port1/
    ProxyPassReverse /apps3 http://server3:port1/

    #no luck with this app. App sits on a server different from apache2 server
    ProxyPass /apps4 http://server4:port1/
    ProxyPassReverse /apps4 http://server4:port1/

    Thank You
    Amar

  • Serterkek on Nov 01, 2010

    Thanks Nathan, it’s working on my network.

  • Hampus on Oct 31, 2010

    (Proxy *)
    Order Deny,Allow
    Deny from all
    Allow from all
    (/Proxy)

    With instead of () of course.

  • Hampus on Oct 31, 2010

    Thanks for the great tip. A little notice though: I got everything to work after supplying

    Order Deny,Allow
    Deny from all
    Allow from all

    Within the section. Hope this might help future people :)
    On the specific Virtual Host

  • Serterkek on Oct 20, 2010

    Thanks for reply Nathan. I will try and let you all know about my experiance.

  • Nathan on Oct 19, 2010

    @Serterkek
    Thanks!

    Well by default on Ubuntu, the apache configuration is a little more organized than other distros by separating out available/enabled mods and site configurations. Typically your real config files live in the “available” folders and links to the real files live in the “enabled” folders. All of this you can find under /etc/apache2 on Ubuntu. By default also, Ubuntu is configured to include ALL files inside the enabled folders. So anything (regardless of extension) will be included into the apache configuration. Before you start, ensure that mod_proxy is enabled by checking the contents of your /etc/apache2/mods-enabled folder. If you don’t see it, link mod_proxy from your mods-available folder to the enabled folder with:
    sudo ln -s /etc/apache2/mods-available/proxy.conf /etc/apache2/mods-enabled/proxy.conf
    sudo ln -s /etc/apache2/mods-available/proxy_http.load /etc/apache2/mods-enabled/proxy_http.load

    So for things like this, you could copy each virtual host config above and paste them into their own file located in the sites-enabled folder. Or more properly, you’d drop it into the /etc/apache2/sites-available folder and then link the files you want to enable to the /etc/apache2/sites-enabled folder with this command:
    sudo ln -s /etc/apache2/sites-available/myvhost1.conf /etc/apache2/sites-enabled/vhost1

    What I also did to organize mine was to setup a separate virtual host per server redirect. You have three IIS servers and one linux server. So you’ll start with three virtual hosts, one for each machine. Then in each virtual host file, the ServerName is set to the domain name you want to route to that server. (This is all done by hostname filtering). You can use ServerAlias to add more if you like, but each ServerName must be unique FQDNs. It should look similar to the first example fooa.com above. After your config files are in place, just restart your web server with
    sudo service apache2 restart

    That’s pretty much it. You configure your router NAT to let port 80 through to your linux server and it will do the rest given your domain names all resolve to your public IP on the router.

    Hope that helps!

  • Serterkek on Oct 19, 2010

    Hi Guys,
    Good work Nathan, I was looking for something like this, but I am very new to linux, could you explain a bit more deep please, such as what file? is it httpd.conf file? under what folder please. I’m using Ubuntu 10 and Apache2 and three IIS 6 web servers, Thank you.

  • Paul Patterson on Oct 06, 2010

    Got it working!!

    Have Apache on Fedora running as a reverse proxy to my IIS machine. Tomorrow at work I’m going to help the infrastructure girl provision those new workstations sitting there, so I can take the old ones to the “recycle” (nudge nudge).

    Winters are cold here so the extra heat will help with the gas bill.

    Thanks again, Cheers!

  • Nathan on Oct 01, 2010

    @Paul Patterson
    Hah, nice! I hear ya. I’m running Ubuntu 10 on a couple of our old laptops as mine. They run well when the power goes out and don’t seem to pull too much power over time. They’re just down there closed up and leaning against the wall. :)

  • Paul Patterson on Oct 01, 2010

    @Nathan

    Awesome! Now to find the time :) I’m already applyng distros to a bunch old work pc’s that were destined for the recycle bin.

    Now to convince my wife that I need we need a air conditioner for the basement LOL!!

    Cheers.

  • Nathan on Oct 01, 2010

    @Paul Patterson
    Excellent!

    Nope, it shouldn’t be a problem at all. That is exactly what I’m doing with mine.

    With this solution, you would use one of the LAMP servers as your inbound proxy (Server1 in the diagram). Then put the Windows box as one of the secondary servers. Just setup a separate virtual host for each server you want to proxy traffic to and use ServerName and ServerAlias to associate domain names with that virtual host. Server1 can also dual serve as a proxy and an end point server with additional virtual hosts.

    Good luck!

  • Paul Patterson on Oct 01, 2010

    Nathan, this is exactly the information I was looking for.

    I have a scenario where I am running an Win 2008 server with IIS 7, but want to also run some full blown LAMP servers too.

    Do you see any challenges with that?

    Cheers,

    Paul

Leave Reply