How to use 1 ip to receive connections, and another to establish connections
When Linux makes outgoing connection, it first tries to use whichever address application requested on socket creation. If it didn't requested anything particular (or requested 0.0.0.0
), it looks for a hint in the route.
You may set a route to have such hint to any address you have assigned, this is done with src
keyword of ip
command:
ip route add DESTINATION via GATEWAY src PREFERRED_SRC_ADDRESS
For example, on my machine I have two addresses, 192.168.168.4/24
and 192.168.168.6/24
(output is stripped down for clarity):
muon ~ # ip addr
...
3: br0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 ... state UP ...
inet 192.168.168.4/24 brd 192.168.168.255 scope global br0
inet 192.168.168.6/24 scope global secondary br0
...
To use 192.168.168.6
for outgoing routes I have either to tell all programs to bind to it explicitely, for example:
ssh -b 192.168.168.6 dst-address
or set up my default route so it will be chosen by default:
ip route add default via 192.168.168.1 src 192.168.168.6
(Default route doesn't have a hint by default; system uses "connected" hint in that case.) Also notice, some src will already be in the "connected" route, spawned from the ip address add
command and defined by the netmask:
192.168.168.0/24 dev br0 proto kernel scope link src 192.168.168.4
That's because .4
address was "primary" on this system, and .6
was added afterwards. These two routes is all I have in the main table, so now I'll connect from .4
to machines in the same LAN (when I go through "connected" route) and from .6
to the machines outside of it (when I go through "default" route). I may update this route too to use .6
address in it:
ip route change 192.168.168.0/24 dev br0 src 192.168.168.6
To use .4
address now I must bind to it excplicitly, for example, with ssh -b
, or setup additional routes with "longer prefix" to certain systems for which I want to use .4
address.
All the time machine is accessible for incoming connections to both IP addresses. If I want it to accept connections to only one of them, I may simply block unwanted connections in the firewall.