Is it possible to run Virtual Hosts (or equivalent) across several servers, but one public IP, using Tomato?

3

1

Here's my home setup. I have a single IP address provided by my ISP. I have one top-level-domain (TLD) and several sub-domains that point at that IP. Internet comes in through my cable modem and plugs into my AdvancedTomato router. I want to install several web servers on separate machines and have the router forward the traffic based upon the domain name. Here's a basic picture

    Internet
    |
    |
    └── example.com-x.x.x.x(router)
        ├── machine1-192.168.1.101
        │   ├── project11.example.com
        │   └── project12.example.com
        ├── machine2-192.168.1.102
        │   ├── project21.example.com
        │   └── project22.example.com
        └── machine3-192.168.1.103
            ├── project31.example.com
            └── project32.example.com

I have been able to do this already on a single machine using basic port forwarding on the router (everything on port 80 goes to machine1), then using Apache's VirtualHost's on that machine to open different websites.

    Internet
    |
    |
    └── example.com-x.x.x.x(router)
        ├── machine1-192.168.1.101
            ├── project11.example.com
            └── project12.example.com

My question: is it even possible to do this at the router level? If not, how do large websites set this up.I know HTTP is at the application level, and that's where the domain request is, so can the router even look at that information? Would I need a proxy server?

Also, should this be on server fault instead?

TinyTheBrontosaurus

Posted 2016-03-26T19:03:10.770

Reputation: 220

Answers

2

What you are describing is Reverse Proxy how do large websites set this up ? -- They have Proxy Servers behind routers

Yes it's possible at the router level but don't think just any router can do it

AdvancedTomato can do this directly from the UI. Enter the following into Web Services->Web Server->HTTP Section. Then Save and press the play button. Tomato adds some extra bits, so to verify it's the config you want, you can see it in /etc/nginx.conf (or look at /var/log/nginx/error.og if it failed)

    # Because end of http://nginx.org/en/docs/http/server_names.html
    server_names_hash_bucket_size  64; 


    # Adapted from NixCraft
    # http://www.cyberciti.biz/tips/using-nginx-as-reverse-proxy.html

    # Host required
    server {
        listen      80 default_server;
        server_name "";
        return      444;
    }        

    ## Start primary proxy ##
    server {
        listen       80;
        server_name  jira.example.com
                     confluence.example.com
                     stash.example.com
                     cacti.example.com;
        access_log  /var/log/nginx/log/lamp.example.access.log  main;
        error_log  /var/log/nginx/log/lamp.example.error.log;

        ## send request back to apache1 ##
        location / {
             proxy_pass  http://192.168.1.99/;
             proxy_redirect default;
             proxy_buffering off;
             proxy_set_header        Host            $host;
             proxy_set_header        X-Real-IP       $remote_addr;
             proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    ## End ##



    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    # Websockets
    server {
        listen 8686;
        server_name other.example.com;
        location / {
            proxy_pass http://192.168.1.99:8686;
            proxy_redirect default;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    } 

Alternatively you can place a reverse proxy behind the router to redirect the traffic

I personally use DD-WRT -- i have read about it but haven't personally implemented Reverse Proxy at the router level DD-WRT Reverse Proxy

SeanClt

Posted 2016-03-26T19:03:10.770

Reputation: 1 960

Reverse Proxy! Thanks this is exactly what I need. AdvancedTomato as an nginx webserver on board, so I'm going to take a shot with that. I'll update with my results – TinyTheBrontosaurus – 2016-03-27T15:16:58.650

Welcome to the team SU. Thanks for updating and fixing the answer, It's always nice to have questions with tested answers, if you do end up getting a full working solution please post link or something, i might even switch from dd-wrt to tomato based on your link – SeanClt – 2016-03-29T01:24:44.680

1

I know this is an old question, and the answer above is correct. However there is a reason this isn't done at the router level.

In order for a packet level device to do this (router), it needs to be able to see which site is being requested. In HTTP this comes in a request header (Host) in an http message, and in HTTPS this is commonly provided in the TLS handshake (client hello packet) using an extension called Server Name Indication (SNI).

Both of these are only sent after the TCP connection is set up (TCP 3 way handshake), and for a router to do this, it would need to become the TCP endpoint itself, accept the connection itself on behalf of the server behind it (hopefully that server is running), wait until the client sent the http request or TLS client hello packet, and then set up a connection to the correct back-end server. This basically makes the router a reverse proxy itself. Proxy software typically does a better job and will give you more options.

Adrien

Posted 2016-03-26T19:03:10.770

Reputation: 1 107