Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a way to do the following with IPTables (Debian Squeeze): Have users connect to a "host" server using a common ssh command and port 22, and then once the connection is established, reroute them to another address based on the string they used to connect in the first place.

E.g., if using a server in the cloud that hosts virtual servers where we can use "dummy" addresses (so the host server has one public address and the guest servers each have their own private address), we want to have users connect to the host server using a common external facing port and then reroute them to a virtual server using a separate address based on the original ssh connection string they use.

To make the initial connection, we need to use one ssh port...and then reroute users to their specific virtual servers once the initial connection is made.

Any help appreciated!

share|improve this question
Sounds like you need IPv6. – Michael Hampton Oct 22 '12 at 14:09

Sounds like you want to do port-forwarding.

Here's a good reference site


Per lain, to make my answer more relevant

This isn't an easy solution, but the closest you're going to get to easy is using port forwarding and assigning specific ports to specific people, and routing those ports to specific machines. If you wanted to spend the time building your own application, you could get around this problem, but that would take a lot of time.

So, on your linux box controlling the routing, add this to your IPTABLES:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 22 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -i eth1 -j ACCEPT 

iptables -A PREROUTING -t nat -i eth1 -p tcp --source --dport 22 -j DNAT --to

Note: you don't need to identify the --source, but it's much better if you do for security reasons. If people are connecting from a dynamic address, then it's probably best that you don't.

So, what the IPTABLES code I showed does is, it takes incoming requests to port 22 and forwards them to So, if I ssh, then I would be forwarded from to the internal server

You would have to use multiple entries for multiple servers. So, for example, for ports 22-25:

# Port 22
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 22 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -i eth1 -j ACCEPT 
# Port 23
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 23 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 23 -i eth1 -j ACCEPT 
# Port 24
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 24 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 24 -i eth1 -j ACCEPT 
# Port 25
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 25 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 25 -i eth1 -j ACCEPT 

iptables -A PREROUTING -t nat -i eth1 -p tcp --source --dport 22 -j DNAT --to
iptables -A PREROUTING -t nat -i eth1 -p tcp --source --dport 22 -j DNAT --to
iptables -A PREROUTING -t nat -i eth1 -p tcp --source --dport 22 -j DNAT --to
iptables -A PREROUTING -t nat -i eth1 -p tcp --source --dport 22 -j DNAT --to

That being said, I also forgot that you could probably do something with bash profiles, too. What this means is, if a specific user connects via SSH, they'll be redirected by their profile, instead of their connecting port. This would remove the need to make a long list of IPTABLE rules and port-forwarding.

To edit a user's bash profile

vi /home/user/.bash_profile

Add this line to the end of the file


So, whatever port you're using for SSH, all users can use the same port, and they're redirected automatically from to the internal server and there's no need for messy IPTABLE configurations or new applications, so long as the user exists on both the routing server and the internal server(s).

Hmmm... I guess I was mistaken. There was an easy answer. It came to me after I read mindthemonkey's answer.

share|improve this answer

What you are trying to do is a little hard to implement at the network layer as you would need a layer 7 (application level) load balancer or packet inspection to implement the forwarding rules. As you are dealing with encrypted traffic you can't just use something on the outside of the connection because it won't be able to read the encrypted part where the information you want is.

As CIA noted, SSH includes functionality to forward TCP ports from a local machine onto the remote network. I've not tried to have a server enforce a forwarded port before as the client generally specifies the port forwarding rules. You could at least limit what ports a client is allowed to use but that still requires knowledge/setup from the client side. This SO answer provides an authorized_keys string to set that up.

If you want to be in control of what happens to the users, you could provide them with a shell on the inbound ssh server that only gives them a connection to their virtual server via keys, or even a menu of servers

client -> ruser@sshserver:/sbin/user_ssh_shell -> ruser@vserver:/bin/bash

Then on sshserver create a file /bin/user_ssh_shell

ssh -i /path/to/privatekey.rsa ruser@

And make that the users shell

usermod ruser -s /sbin/user_ssh_shell
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.