Hosting multiple domains on seperate servers but only one public IP address

Is there a way to host multiple websites with different domains on the same public IP address, and when the user enters, say example1.com that goes to one server on my private network(192.168.1.20), and example2.com goes to 192.168.1.21? I have a VM host and want to experiment with some of the turnkey linux solutions, and it would be awesome if I could make those sites publicly accessible when I decide to use them. Many of the solutions I have come across on here involve using a redirect, but I haven't found a decent description of how that works. Would the user see a redirect happening in their browser? Is it slow? I'm guessing I'd have to have one "master" server running apache which would listen on port 80 and then redirect to my other servers?


Solution 1:

Everytime I need to do this I fall back to HAProxy, this is another reverse proxy package that allows you to host multple services behind a single (or multiple) public IP's.

In this example i would install HAproxy on your machine with public address.

This can be done from APT-GET or YUM depending on your disto of choice. Once installed take a look at the config file (In Ubuntu its in /etc/haproxy/haproxy.cfg)

HAProxy uses FRONTENDS and BACKENDS, Frontends to bind to an IP:PORT and then a backend in which you specify servers (one or more).

Here is an example of my config for running multiple web service applications behind my single home IP. In my case im using multiple ports on the same IP in my backends, in your examples you would want to use differnet IP's on port 80.

#GLOBAL CONFIG
global
        maxconn         1000
        daemon
        user            haproxy
        group           haproxy
        nbproc          1
        pidfile         /var/run/haproxy.pid
        stats socket    /var/run/haproxy.cmd mode 777 level admin

#ASSUMED DEFAULTS
defaults
        log             global
        mode            http
        option          httplog
        option          dontlognull
        retries         3
        maxconn         1000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000

#STATS PAGE
listen stats 192.168.10.253:9000
        mode http
        stats enable
        stats auth     username:password
        stats uri      /proxy_stats
        stats realm     PAGE TITLE

####SABNZBD####
backend sabnzbd
        server          sabnzbd 192.168.10.253:8080 weight 1 maxconn 1000 check inter 10000
        option          redispatch
        option          httpclose
        option          forwardfor
        balance         roundrobin

        timeout server  120000

####SICKBEARD####
backend sickbeard
        server          sickbeard 192.168.10.253:8081 weight 1 maxconn 1000 check inter 10000
        option          redispatch
        option          httpclose
        option          forwardfor
        balance         roundrobin
        timeout server  120000

####COUCHPOTATO####
backend router
        server          router 192.168.10.254:80 weight 1 maxconn 1000 check inter 10000
        option          redispatch
        option          httpclose
        option          forwardfor
        balance         roundrobin
        timeout server  120000

####TROLL####
backend troll
#        server          troll www.meatspin.com:80 weight 1 maxconn 1000 check inter 10000
         server          troll www.google.com:80 weight 1 maxconn 1000 check inter 10000
        option          redispatch
        option          httpclose
        option          forwardfor
        balance         roundrobin
        timeout server  120000


#NAS FrontEnd
frontend nas
        bind            PUBLIC_IP:80
        reqadd          X-Forwarded-Proto:\ http
        default_backend troll

        acl req_couchpotato hdr_beg(host) -i film.
        acl req_sickbeard hdr_beg(host) -i tv.
        acl req_router hdr_beg(host) -i home.
        acl req_sabnzbd hdr_beg(host) -i warez.

        use_backend couchpotato if req_couchpotato
        use_backend sickbeard if req_sickbeard
        use_backend sabnzbd if req_sabnzbd
        use_backend router if req_router

With this in place and the PUBLIC_IP configured in the Frontend, myserver listens on port 80, looks at the http header on incomming requests and if it sees a request for film.mypersonaldomain.com it used the couchpotato backend, if it sees tv.mypersonaldomain.com it uses the sickbeard backend.

Please note the 'troll' settings i used while testing this, the default backend if you go to my public IP without specifying a matched URL was to send your request out to meatspin.com (DO NOT EVER GO TO THIS ADDRESS IF YOU VALUE YOUR EYES), I have replaced this with google.com for this example.

Many more things can be done with HAProxy but this should give you a good idea of the basics. The documentation for HAPRoxy is pretty in depth but also very comprehensive.

http://haproxy.1wt.eu/#docs

J

Solution 2:

You need a reverse proxy sat between the servers and the public network. nginx is a popular choice for this and there are many examples out there once you know what to search for (http://www.howtoforge.com/how-to-set-up-nginx-as-a-reverse-proxy-for-apache2-on-ubuntu-12.04 is one of the first that a search for "nginx reverse proxy" returned).

For domains/directories to be served by different servers on the inside of the proxy, you define each vhost or directory as you would if the proxy machine were about to serve them from different local locations, but instead define each as a proxy using the relevant options.

nginx is not the only option: many web servers (including apache with the right module(s)) can operate this way. nginx is a popular choice because it is fast and light but if you need other features too then shop around to make the best choice.

If you use SSL on any of the sites, you need to configure the proxy with the relevant certificates, and obviously you'll need to configure the web server to deal with SNI if you need more than one SSL site to pass through the procy. For efficiency it is usual to have the proxy talk to the inner servers by non-ssl http if the network between them is trusted.