Configure two network cards in a different subnet on RHEL 6, RHEL 7, CentOS 6 and CentOS 7

The goal is to become symmetric routing:

Each interface on the server should have it’s own default gateway, which allows that interface to reply itself to incoming packets from other networks.

A normal routing table can only have one default gateway. This is quite logical since it’s the place where to send packets that do not match anything else in the rest of the table. To be able to have two default gateways, one for each interface, you need to setup policy based routing.

Policy based routing allows you to have multiple routing tables. Which table is used, depends on a set of rules.

To setup policy based routing for our example case, we will use two policy based tables. While it is possible to give a nice name to the tables (in /etc/iproute2/rt_tables), it’s not really when you only plan to have a few. Without a name, the tables are automatically created when you’re adding something to them.

Let’s start with adding a route for the network itself (link) and one for the default gateway for each interface. ens192 (192.168.0.10) will use table 1, ens224 (192.168.1.10) will use table 2.

[jensd@server ~]$ sudo ip route add 192.168.0.0/24 dev ens192 tab 1
[jensd@server ~]$ sudo ip route add 192.168.1.0/24 dev ens224 tab 2
[jensd@server ~]$ sudo ip route add default via 192.168.0.1 dev ens192 tab 1
[jensd@server ~]$ sudo ip route add default via 192.168.1.1 dev ens224 tab 2

To define when table 1 or 2 will be used, we’ll add a rule, based on the source of the packet to the policy and refresh the policy based routing:

[jensd@server ~]$ sudo ip rule add from 192.168.0.10/32 tab 1 priority 100
[jensd@server ~]$ sudo ip rule add from 192.168.1.10/32 tab 2 priority 200
[jensd@server ~]$ sudo ip route flush cache

To check if we did everything correctly, let’s list the tables and the rules:

[jensd@server ~]$ ip route show tab 1
default via 192.168.0.1 dev ens192
192.168.0.0/24 dev ens192  scope link
[jensd@server ~]$ ip route show tab 2
default via 192.168.1.1 dev ens224
192.168.1.0/24 dev ens224  scope link
[jensd@server ~]$ ip rule show
0:      from all lookup local
100:    from 192.168.0.10 lookup 1
200:    from 192.168.1.10 lookup 2
32766:  from all lookup main
32767:  from all lookup default
[jensd@server ~]$ ip route
default via 192.168.0.10 dev ens192
169.254.0.0/16 dev ens192  scope link  metric 1002
169.254.0.0/16 dev ens224  scope link  metric 1003
192.168.1.0/24 dev ens224  proto kernel  scope link  src 192.168.1.10
192.168.0.0/24 dev ens192  proto kernel  scope link  src 192.168.0.10

As you can see in the output from ip rule show, our policy based tables have a higher priority than the main table, which can be viewed with ip route. Nevertheless it’s import to still have a default route in the main table since packets leaving the machine itself can have a source IP of 0.0.0.0 and would not match any of the rules in our policy.

Make the changes permanent
Up to now, the changes would get lost after a reboot or restart of the networking. To make the changes permanent, create a route and rule file for every interface. For the above example, the contents would look like this:

[jensd@server ~]$ cat /etc/sysconfig/network-scripts/route-ens192
192.168.0.0/24 dev ens192 tab 1
default via 192.168.0.1 dev ens192 tab 1
[jensd@server ~]$ cat /etc/sysconfig/network-scripts/route-ens224
192.168.1.0/24 dev ens224 tab 2
default via 192.168.1.1 dev ens224 tab 2
[jensd@server ~]$ cat /etc/sysconfig/network-scripts/rule-ens192
from 192.168.0.10/32 tab 1 priority 100
[jensd@server ~]$ cat /etc/sysconfig/network-scripts/rule-ens224
from 192.168.1.10/32 tab 2 priority 200

Now your configuration should be persistent.

Some people pointed out in the comments that, in order for the routers to be persistent, you need to first perform the following actions:

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

While this solution is slightly more work than changing the value for rp_filter, it isn’t that hard and has a lot of advantages over the other solution.

TAKEN FROM: https://jensd.be/468/linux/two-network-cards-rp_filter