2

I have 2 network interfaces on my "CentOS 7 Minimal" box. I need to setup policy based routing, so that if a request comes in on one interface, the reply gets sent out the same interface. Doing this with iproute2 in a non-persistent way is not terribly difficult:

echo '200 isp2' >> /etc/iproute2/rt_tables
ip route add default via 1.1.1.1 table isp2
ip rule add from 192.168.1.50 table isp2

Where 1.1.1.1 is my router, and 192.168.1.50 is my linux's IP. The problem is making this persistent.

From what I've read, there's no iproute2 persistence file - the way to make things persistent is to add them to your network startup scripts.

Normally, RedHat recommends creating the file /etc/sysconfig/network-scripts/route-ethX to add routes, but this does not appear to be able to add routes to a secondary routing table.

The solution seems to be to add the "ip route" and "ip rule" lines from above to /etc/sysconfig/network instead. This almost works, except for one thing: Every time the network is restarted, it keeps adding duplicate "ip rule" rules, dozens at a time.

After restarting my network 2 or 3 times with "systemctl restart network", my ip rule output looks like this:

0: from all lookup local
32670: from 192.168.1.50 lookup isp2
32671: from 192.168.1.50 lookup isp2
...
32764: from 192.168.1.50 lookup isp2
32765: from 192.168.1.50 lookup isp2
32766: from all lookup main
32767: from all lookup default

What is the proper way to add persistent policy-based-routing rules on CentOS 7?

PS. The ip route list table isp2 command shows a single entry, as expected, so that's not a problem.

Edit: According to the RedHat 7 manual:

in Red Hat Enterprise Linux the use of the global /etc/sysconfig/network file is deprecated

This is in favour of interface-specific config files, which don't appear to be able to add routes to a different routing table, and can't add ip rule rules.

1

Installing NetworkManager-config-routing-rules, and enabling NetworkManager-dispatcher seems to have fixed it:

$ sudo yum install NetworkManager-config-routing-rules
$ sudo systemctl enable NetworkManager-dispatcher.service
$ sudo systemctl start NetworkManager-dispatcher.service

Now I can have this in my /etc/sysconfig/network-scripts/route-ethX:

default via 1.1.1.1 table isp2

And this in my /etc/sysconfig/network/scripts/rule-ethX:

from 192.168.1.50 table isp2

And a definition for isp2 in my /etc/iproute2/rt_tables:

200 isp2

Restarting the network service no longer creates duplicate entries.

1

Given the reading of /etc/sysconfig/network-scripts/ifup-routes the lines from route-(interface) are parsed as is into ip route add, therefore to add the routes in a certain table, just add table XXX to the line. However, you might need to resort to table number instead of name from rt_tables to successfully add the route.

With rules, you can use rule-(interface) file, and actually current version of ifup-routes and ifdown-routes process these files like route files. This might not be the case with your set of scripts, to verify run grep rule /etc/sysconfig/network-scripts/ifup-routes.

Your primary problem actually arises from sourcing of /etc/sysconfig/network by each of ifup and ifdown scripts, therefore each command in that file is executed once per up/down of every interface. This in turn makes your system to add 2*interfaces (including lo) additions of IP rule per network restart.

PS: I have uninstalled CentOS network manager, so everything is done with ifup/ifdown scripts, and I have tested all this before posting this answer.

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.