SSH tunnelling outgoing routes

Lubster used Ask the Experts™
I have a linux server with 3 public IPs, and I use SSH tunnelling to connect to each of them.

Let's call them: (venet0:0) , (venet0:1) , (venet0:2).

When I tunnel using, outgoing IP for the public is: But when I tunnel using or , the outgoing IP for the public is still

I've been googling for hours, and I know it is possible to assign routes to set a relation between the inbound IP, and the outbound IP - but I simply failed to understand the logic/rules of how to achieve it.

Anybody mind to put me out of my misery?

Thanks, Lubster
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
could you show the command that you're using for tunneling?


gelonida:ssh -D 1080 user@ip

From what I've managed to gather, it has absolutely nothing to do with the ssh parameters.
probably your rouing configuration  on your linux server has it's default gw set to venet0:0

what does
route -n
report on your server?


# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface   U     0      0        0 venet0     U     0      0        0 venet0         UG    0      0        0 venet0
I don't know the answer, but I think what you try to achive is not that simple.

You have only one sshd process on your server which listens on all (venet0,venet1,venet2 and lo) interfaces acting as socks server.

For each client, which is connecting it will just create a new network connection, which will use the routing table information in order to decide which device to use for outgoing traffic.

In your case this is venet0.

You could split your problem into two problems.

1.) have one sshd per network device.
each sshd would just listen on its own interface.
this would also allow you to have different security policies for each interface.

I never did this, but basically you had to create a config file for each daemon and change your init scripts to start all three.

2.) you had to find out how to have a different routing table per sshd process.
I think this would be possible with IP-tables (determine the sshd process id and configure a dedicated route for each)
However I do not know how this can be done.


Well your suggestion would work, but as you can understand that's not a reasonable solution.

As far as I understand, the routing shouldn't have anything to do with ssh directly.
sshd is just a process
listening on multiple interfaces.
as a reaction to an incoming connection it will create a new outgiong connection.

I have difficulties to imagine how you would like to tell sshd to use a different outgoing interface for
a freshly created connection depending on which incoming device triggered this.
If this is not already built into sshd, then I guess it's not something you can do.

Perhaps there's some trick in ip-tables.
This might work if you're lucky as sshd will hopefully spawn a new child process for each connection to be treated.

So the question might be how to configure your ip-tables rules such, that a process shall use a different outgoing device depending on the nw device it is currently reading from.

Unfortunately I'm not an ip-tables specialist.
Distinguished Expert 2017

What is the purpose of your tunnel? If you tunnel into the linux route so that you can gain access through it to somewhere else, you have to setup a proxy that will bind to each IP and then you can tunnel to any of the three IPs and then alter the behavior based on the proxy/port you choose.


arnold: The purpose of the tunnel is to access the public via the server for various of reasons and protocols. openssh is acting as the proxy - wouldn't you say that your suggestion matches gelonida's? having multiple daemons?

Are you suggesting that there is no other solution, routing-wise?
Distinguished Expert 2017


The way you get in does not gurantee that the packets you send via this tunnel are marked with a specific route.

The problem deals with the inability to tag the packets in a particular way prior to sending it through the SSH tunnel which then would be treated by configured iptables to roue specific tagged packets with a specific source address.

The default behavior for any packet leaving an unbound application, will appear as though it originated from the first IP.


So I gather that daemons such as squid, and even ss5 - have this native ability, while almighty openssh, is lacking?

I guess I'll use a different server then.
Distinguished Expert 2017

you seem to be misunderstanding the issue.
The tunnel from ssh only provides you access/path to reach a resource on the other side of the tunnel, it does not and can not control nor alter how the remote system/resources behaves.

Lets say you are going into a night club where there are three entries with each having a bouncer/guard.  all three entry points lead to a central location from which the host/hostest directs individuals to three different ball rooms.
your friends tell you if you that ball room 2 is where you want to be.

The other thing your freinds tell you is if you approach guard 2 and say X, you'll be allowed into the night club.

Once you are in, whether you end up in ball room 1 totally depends on whether the hosts directs to that room.  Complaining to the guard that you were directed to one of the other two is a waste of time.

This is what you are doing.  You are complaining about SSH that provides you with access into the remote system about how the remote system handles the inbound/outgoing traffic.

In what capacity are you talking about an SS5?

Presumably the SS5 you mention is the security appliance where you setup a public to private IP mapping such that access to public IP 1 is directed to private IP 1 and then when the traffic from private IP 1 is sent to the net, it appears as though it originated from public IP 1?
If so, there is a rule on the SS5 that deals with if traffic originates from private IP 1, the NAT stamps it with the source IP of public IP 1.

With the SSH tunnel to a linux system you would need to TAG the packets you are sending through SSH such that iptables on the linux box can be configured to direct/stamp the source address of the packet as something other than the default outgoing IP.


arnold: Were you under the assumption I'm trying to solve it from a CLIENT point of view?
Obviously I'm looking at the server's point of view. SSH is not only creating the tunnel, the daemon on the SERVER does the dynamic forwarding, so obviously I'm targeting the correct item in my chain.

(Why else would I compare its behavior to other servers, such as squid and ss5, which are capable?)

Regards your last suggestion/reference... of TAG-ing (which actually meaning MARK-ing?)... unfortunately I'm not experienced enough even to say whether it's relevant or not, yet alone - actually understand how.
Distinguished Expert 2017

You can not tag/mark since the traffic is seen as local originating from the SSH server.

I think the night club example would have made things clearer.

Squid is an application that is configured to BIND to an IP address. This way whenever it sends out anything it is stamping the packet as originating from this bound IP address.
Unless your system is on the public network and squid can bind to a Public IP address, it too will not be able to handle what you want

i.e. Internet <=> Router <=>NAT default_public_ip<=> LAN <=> two squid daemons each bound IP1 and IP2

Unless the NAT has a map for IP1 -> public_ip1 and IP2 -> public_IP2, the use of either squid daemon, will result in the source IP of the squid request appearing to come from default_public_ip.

Have a look at using openVPN as a VPN connection to the server and you may within this process be able to tag/mark the packets entering the linux server such that you can then have iptables reroute specifically taged/marked packets to exit the server on an IP other than default_public_ip.

You may have to have multiple openVPN daemons if you want to distinguish between connections. If tagging/marking is allowed, it will tag/mark all the packets from a specific openvpn connection the same way without regard to the username/certificate used to establish the connection to this daemon.

i.e. openvpn_daemon1 tag1
openvpn_daemon2 tag2.

If you establish a VPN to SS5 through which you want to reach the outside, I do not believe you can change the IP from which the VPN originated traffic is seen on the outside from the default_public_ip unless you randomize all outgoing traffic.
I.e. you configure SS5 to "randomly" stamp the source of the outgoing packet with one of several available public IPs unless you are assigning an internal IP to the VPN user and then have a map setup that maps a public_ip to the private_ip that is assigned to the VPN user.


arnold: Let me clarify regards squid's behavior...

I have -1- daemon of squid, which listens to the public IPs: , , , at the very same port.

When I connect to the public IP, from a remote machine (over the internet)... and then I surf to a public website, that website sees me as:

When I connect to the IP , squid forwards my requests while binding to , therefore the website sees:

This is the exact behavior I'm trying to achieve with openssh's daemon. So according to you, it's impossible? (multiple daemons - not the same behavior)
Distinguished Expert 2017

I have not looked/configured squid to bind to specific IP to see whether it alters the source IP based on the bound IP through whicih the request came in.

in this case squid is likely programed to send the requests through the same binding that it receives them.

If your proxy is already accessible from the outside since it is bound to the external public IPs, why are you tunneling in?  Configuring squid with authentication and you would not need to ssh/tunnel into the server.

You would define your proxy A record to each of the public IPs with a short TTL  30,60,90 seconds.
Then your requests will be forwarded to the squid on a random public IP.

openSSH is designed to grant access into a system the tunnels are an add on to provide an alternative to having to establish a VPN. The fact that you want to use the SSH tunnel to masquerade your IP is a different story.  As I said you would need to configure your proxy settings to use the proxy on the other side of the tunnel through which you want the traffic to exit.

To randomize, you could within your workstations hosts file define proxy with the multiple IPs or define the proxy within DNS pointing to multiple IPs.

your system <=> ssh connection/tunnel <=> internet <=> system <=> ssh daemon
Anything that happens within the system is outside of the ssh daemon.

I have not looked on whether you can bind ssh daemon on multiple internal IPs versus bind to any.  Then setup the port forwarding on the router to direct public_ip_1 port 22 to private_ip_1 port 22 and repeat the same, whether the outgoing traffic from each connection will be seen internally as originating from a different private_ip_x address on which you can define iptables to route src private_ip_x through public_ip_x.


Regards squid:
#  TAG: tcp_outgoing_address
#      Allows you to map requests to different outgoing IP addresses
#      based on the username or source address of the user making
#      the request.
#      tcp_outgoing_address ipaddr [[!]aclname] ...
#      Example where requests from will be forwarded
#      with source address, forwarded with
#      source address and the rest will be forwarded with
#      source address

Regards the idea of squid capability to do something in specific, doesn't means it can do other things :)
Yes, it may authenticate.
But what about encryption? what about other protocols? (where CONNECT is not optional)

Regards the rest of your suggestions, I'm sorry - but I either don't see it... or I can't understand it.

So thanks again for trying!
Distinguished Expert 2017

When you use the SSH tunnel, the source of the requests seen by the proxy is likely localhost/local linux IP depending on the access.

You would need to use something that will pass the source IP of the requests such as a VPN.

you are using the ssh -L localport:remotehost:remoeport
And you have your internal proxy setup to forward the requests through the localhost localport to the proxy on the remotehost:remoteport while trying to achieve the distribution of requests to be seen from other public_ips to which squid is bound??

Configure a VPN server and allocate IPs based on the user/password provided.
This way your squid can alter its behavior based on the user that loged in given their requests will come from a different range of IPs.


arnold: Huh, why ssh -L ??? server sits at: (remotely) , my client, sits at (locally).

This is what currently happens:
Locally, I set a tunnel: ssh -D 1234 user@
Locally, I set a browser to use SOCKS5, at:

My browser connects to -> (SOCKS) SSH TUNNEL -> -> SSH DAEMON -> forwarded requests while binding to

Now what I want to happen:
Locally, I set a tunnel: ssh -D 1234 user@
Locally, I set a browser to use SOCKS5, at:

My browser connects to -> (SOCKS) SSH TUNNEL -> -> SSH DAEMON -> forwarded requests while binding to

Now it makes more sense?
Needless to say, when I set the browser to use a HTTP Proxy of squid, -> outgoing IP will be

When I set -> outgoing IP will be

Hopes it settles it :)
Distinguished Expert 2017
It does and always did make sense, as I pointed out, the traffic sent over SSH tunnel appears from a single source (the local system on which the ssh connection terminates).  
The way you connect to the proxy is your solution. i.e. which proxy address you use will control the IP from which the connection will appear on the remote site.

What it seems you were looking to do is to alter the outgoing routing table on the remote site through the use of the ssh tunnel. This is why in http:#33125668 I referenced/pointed to the need to use a proxy server/daemon.

I think you've got the answer and a solution.


Well, that's not exactly the solution I been looking for :(
I wanted to use the SSH daemon as my tunnel+proxy, not as a tunnel + another proxy daemon.

But ok, I get it, almighty openssh simply can't do everything... I just need to accept reality.

Thanks for your effort!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial