Domain Name Routing Across Multiple Varying Servers

How can you use one public IP address to host multiple domain names that span across multiple servers in your LAN?

Let's say I have 5 web servers, serving 5 different domain names, using 5 different server-side technologies, and I currently have 5 public IP addresses.

DNS is setup so that each of the 5 domain names are mapped to each of the respective public IPs, and the firewall has port-forwarders so all requests get forwarded to the respective internal ip-addresses of the correct server within the LAN.

How would I consolidate to using one IP instead of 5? I understand how dynamic-dns works and if there was just one web-server I'd have no problems. However, since there are multiple web-server, using varying technologies, I'm not sure how to accomplish using only one public IP.

Is there a server (preferably Linux based) that I can send all requests to, that is capable of transparently routing each request to a specific internal IP+port based strictly on domain name within the request?


You could try setting up a Load Balancer with a Reverse Proxy.

It's basically a server where all the requests goes to, but it does not process the requests; rather, it only sends the request to be processed by one of the servers behind it.

There are different algorithms to send requests to the right servers in order not to workload one of the servers more than others, but for basic setups, even making it random or sending requests to one server at one time could work. Since who's going to make the request to the actual server is Nginx, you'll lose the original user's IP address. To make it available again, you'll have to set up Nginx and your servers to pass the original IP address as a HTTP header (such as X-Forwarded-For).


An Apache or Nginx reverse proxy would do.

Below is a simple example with nginx reverse proxy, including load balancing.

http {
  upstream backend_server_2 {     # load balanced server block
     ip_hash;
     server 10.1.1.2:8080 weight=2;
     server 10.1.1.3:8080 weight=1;
  }

  server {
     listen public_ip:80;
     server_name example1.com;
     location / {
         proxy_pass http://10.1.1.1/;
     }
  }

  server {
     listen public_ip:80;
     server_name example2.com;
     location / {
         proxy_pass http://backend_server_2/;
     }
   }
}