When IP aliasing how does the OS determine which IP address will be used as source for outbound TCP/IP connections?

Solution 1:

By default, on Linux, if an interface has multiple addresses that are on different subnets, traffic destined for the respective subnets will have the proper source IP. That is, if eth0 has two addresses 192.168.1.1/24 and 10.1.1.1/8, then traffic to anything on the 10.0.0.0 subnet will have source 10.1.1.1, and traffic to anything on the 192.168.1.0 subnet will have source 192.168.1.1. You can also assign source addresses explicitly in this case by using the "src 1.2.3.4" option to "ip route".

In your case, though, all your addresses are on the same subnet, so the "primary" one (as revealed by "ip addr list dev eth0") is used as the source IP for traffic exiting on that interface. I think it's possible to control the source IPs in this case just using "ip route", but I've found it easier to use iptables to rewrite the source addresses for traffic of interest.

If you want to force a specific source address to be used for specific destinations, you can do it with a SNAT rule:

iptables -t nat -I POSTROUTING -o eth0 -d dest-IP-or-net/mask -s primary-IP-of-eth0 -j SNAT --to-source desired-source-IP

So if your "primary" eth0 IP is 192.168.100.1, but you want traffic to 1.2.3.4 to have a source of 192.168.100.2, then do this:

iptables -t nat -I POSTROUTING -o eth0 -d 1.2.3.4/0 -s 192.168.100.1 -j SNAT --to-source 192.168.100.2

Note that the "-s 192.168.100.1" is important: it prevents forwarded traffic's source addresses being rewritten by this rule.

If you are going to implement complex network configurations on Linux, you should read the Linux Advanced Routing and Traffic Control documentation, http://lartc.org

Solution 2:

I see in your example that all the ips are too close not to be in the same network

are you sure that you are actually multihoming and not simply having 4 IP aliases?

if the latter is the case then you can set the source ip on a route with something similar to this

/sbin/ip route show 192.168.222.0/24 dev eth0 proto kernel scope link src 192.168.222.178 169.254.0.0/16 dev eth0 scope link default via 192.168.222.1 dev eth0

sudo /sbin/ip route replace default via 192.168.222.1 src 192.168.222.178

/sbin/ip route show
192.168.222.0/24 dev eth0 proto kernel scope link src 192.168.222.178 169.254.0.0/16 dev eth0 scope link default via 192.168.222.1 dev eth0 src 192.168.222.178

see man interfaces on how to make it persistent between reboots

Solution 3:

It uses whatever the default gateway is in the routing table, unless there is a specific route telling it to use another: route -n

EDIT: I read your question too quick it seems...

Since you are using passive mode and the client will always be initiating the connection, I think src ip field in the IP header will always appear as whatever IP the client connected to. If it were active mode the server was initiating the connection, I think it would always be the 'Primary' IP. If your addresses are in the same subnet, Linux will make the first address you added 'Primary' and the others secondary.

I am not entirely sure though, I would run tcpdump -n and see what it sees as the src IP.

EDIT2: Okay, I wrote the above from the standpoint that you were running the server, so since you are the client and initiating the connection, I think it will always appear to come from the Primary IP address, but again, try it and see with tcpdump.

Solution 4:

Unless your FTP job has a way of specifying the interface to use for connections, I believe it defaults to the first physical interface on the relevant subnet (eth0 in this case). If you had a server with two NICs on different subnets, it'd figure out which interface to use based on the routing table.

As there is only a single physical interface on the system (eth0) and four virtuals/aliases (eth0:0 through eth0:2) on the same subnet, outbound traffic will use the eth0 IP address as the source unless the application is smart enough to declare an outbound interface.