We have several "router" machines that gather a lot of external IP addresses on the same host and redirect, NAT or proxy the traffic to the internal network. They also act as routers for the machines on the internal network. This works fine, however I am unable to make the routing table, so I can change the source address, based on the destination a machine from the internal network want to access.

Let's say I have a router, that has public addresses P1 ( and P2 ( All traffic goes through P1, but if necessary, the host is reachable on P2 too. This looks like this and works fine:

> ip addr
1: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether aa:bb:cc:dd:ee:11 brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth1
    inet brd scope global secondary eth1:p2

Now I want to use P2 as the source address, if I want to access the Google DNS service for example ( So I add a row in the routing table like:

> ip route add via dev eth1 src
> ip route
default via dev eth1 dev eth1  proto kernel  scope link  src via dev eth1  src 

But this does not work. If I ping, the host still uses P1 as the source address, and does not use P2 at all for outgoing connections.

Am I doing it right? I guess not...

  • UPDATE: Pinging the ip from the router works, but when hosts from internal network do the same, it does not work. I guess it is related to iptables and the NAT configuration. Anyway, the question stands. – hgj Nov 4 '13 at 11:08

The fact that you can ping the destination with the right IP address from the host but not from the internal network (if I read your comment right) suggests that you have NAT enabled for the internal network.

In that case, you have to look at iptables rules and edit the according SNAT or MASQUERADE rules. For example:

iptables -A POSTROUTING -s <your-internal-network> -d -o eth1 \
-j SNAT --to-source

Please note, that this will only make the forwarded internal network traffic come from the desired IP ( in the example), you still need iproute rules/tables to make the same rules apply to the router. (Connections coming from the router itself.)

  • Well, this does work! I just have to manage to merge this with my existing NAT configuration. Thanks for the note @Szobi, we will probably not access the special hosts from the router itself, but I will add a note to the network configuration. – hgj Nov 4 '13 at 15:12

You need to set up specific routing tables for each connection, which is known as policy based routing. Each table has a policy, in that you can set the source address, and other options, if you need.

In your case, you'd add new tables:

echo 200 P1 >> /etc/iproute2/rt_tables
echo 200 P2 >> /etc/iproute2/rt_tables

Add in the routes:

ip route add dev eth1 src table P1
ip route add default via table P1
ip route add dev eth1 src table P2
ip route add default via table P2
ip route add via table P2

This is the important bit, where you tell it to respond with the same IP it received the connection on.

ip rule add from table P1
ip rule add from table P2

You can add as many tables as you like, just remember that they will all need a default route, a source interface and source address, so when a packet is routed through the table, the source address will be set properly and it will use the correct interface.

Have a look at these pages, it gives a lot of additional info how to set up this sort of table:


  • Thank you @nickw - but I should have noted that I am familiar with source based (policy) routing, this is not what I want. Though it might work if I set the rules with ip rule add to table P2 or so, but I've tried that, and it did not work from the internal network, just from the router itself. – hgj Nov 4 '13 at 14:49
  • That's interesting, maybe it's something you can do with fwmarks and differentiated NAT tables. – NickW Nov 4 '13 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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