Bind outgoing SOCKS-server traffic to a specific IP

The SSH protocol has no way for clients to tell the server to bind to a certain address when doing a dynamic port forwarding, so no, you can't tell your SSH client to do it. You can't tell the OpenSSH server to do it either. It will blindly use getaddrinfo to connect to your remote host.

The only way to fix is to configure your server so it does what you want. Unfortunately, there is no way you can tell from the routing or iptables which connection was made by the OpenSSH server. The problem is hard: OpenSSH may open connection, but may also spawn a shell which can spawn other process which also can open connections. Distinguishing from the two cases is hard. It would be much easier if OpenSSH would just set a mark or anything, but it doesn't.

So your solutions are limited:

  • Use a separate SOCKS server that allows you to configure the bind address.

  • Configure your kernel so that it uses xx.yy.zz.2 by default for all outgoing connection, or for the actual destination IPs that are used if they are known in advance.

    To assign a source address when there is none, the kernel looks at the used route entry for your destination address, and if it has a preferred source address, it will use it. Else it will pick some address that look best for the task. Whatever it chooses can be checked by the ip route get (destination) command, after the src token:

    $ ip route get 8.8.8.8 8.8.8.8 via (maybe your gateway) dev eth0 src xx.yy.zz.1 [...]

    You may modify your routing table with the ip route command to add preferred source addresses with ip route change [...] src xx.yy.zz.2 You may even add more specific route going though the same gateway, but with a different preferred source address.

  • Put OpenSSH into a network namespace that only handles the xx.yy.zz.2 address. This solution is way overkill and may change the configuration of many services on your server, since it essentially isolates your two adresses. This solution will involve many changes in your system, especially regarding the way the sshd daemon and your socks server is started.


Unrelated to all of this: "interfaces aliases" (e.g. eth0:1) are deprecated on Linux. They still work as backward compatibility for historic tools like ifconfig, but you should really get rid of them and use the native functionality of the kernel to get multiple addresses per interfaces. Stop using ifconfig, route and use ip addr and ip route instead.

Use ip addr add ... dev eth0 to add an address to the eth0 interface. You can add as many addresses as you want. Use ip addr to list them all. See the manual page of ip addr and ip route to get more information.