I have this setup:

a (Host) FreeBSD 9.2 host server running VirtualBox with another (Guest) FreeBSD guest server. I have set up port forwarding on the Host to the Guest like this:

VBoxManage modifyvm "Guest" --natpf1 "guestssh,tcp,,9201,,22"
VBoxManage modifyvm "Guest" --natpf1 "guestmysql,tcp,,9202,,3306"
etc ...

This works fine. I can for example ssh -p 9201 user@localhost just fine.

Also I have a domain (let's say example.com) with DNS adress record pointing to the Host ip. And this also works as expected ssh -p 9201 user@example.com.

Beside the main domain I have subdomains like ssh.example.com, mysql.example.com. Now I need incoming traffic from those domains to be forwarded to specifc ports on the virtual machine. So

ssh.example.com:22 -> localhost:9201
mysql.example.com:3306 -> localhost:9202

For SSH this is easily achieved on a single *nix clinet by setting up ~/.ssh/config like this:

Host ssh.example.com
    Port 9201

But I need to forward services other then SSH as well (like MySQL, VNC, HTTP, etc.). Plus the ports may change as I'll add new Virtual Machines for specific services.

So my question is: how can I configure the Host machine to forward incoming traffic domain_name:port1 to localhost:port2?

I've tried to set up firewall for this, but this was obviously wrong way to go, as the domain names resolve to ip adresses. Setting up a SSH forwarding with ssh -L is also a bad idea. So what else is left?

EDIT: I can acces the raw DNS record and reconfigure it, so I was thinking maybe if I can bind some kind of information to the domain and catch it with a proxy software on the Host side?


You cannot do port forwarding based on the hostname, because when somebody connects to your host, they don't tell you what hostname they looked up to get your IP address. All you know is the IP address and port number they connected to (and the IP address and port number they're connecting from).

You'll have to arrange for ssh.example.com and mysql.example.com to have different IP addresses. Or just accept that you're also forwarding

mysql.example.com:22 -> localhost:9201
ssh.example.com:3306 -> localhost:9202

The only information the client is extracting from the DNS record is the IP address, so that's the only thing you can change to affect port forwarding. (Of course, one machine can have multiple IP addresses, but if you're doing this on the internet, public IP addresses may be in short supply.)

  • I was afraid of this. So there is really no way? Not even with some kind of fancy DNS record configuration and/or proxy software on the host? – Maciej Sz Jan 10 '14 at 17:31
  • 1
    No, because the clients connecting won't know anything about your fancy software. All they do is 1: convert hostname to IP address and 2: connect to IP address and port. There's no way for your host to know what hostname they used in step 1. – cjm Jan 10 '14 at 18:12

Check out sslh. It's a tool for multiplexing a single port to multiple services. As another user mentioned, subdomains only resolve to an IP address-- The actual routing happens on the protocol level.


It is possible but the question is the effort worth the gain?

One could create a "proxy" software that speaks the protocol for the different applications, and uses for instance the http's Host header to determine which machine/port to forward to.

I reffer to the project seaport, which is an http proxy that does this forwarding internally on one machine. https://github.com/tellnes/seaport

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.