Chapter 14. Configuring policy-based routing to define alternative routes
By default, the kernel in RHEL decides where to forward network packets based on the destination address using a routing table. Policy-based routing enables you to configure complex routing scenarios. For example, you can route packets based on various criteria, such as the source address, packet metadata, or protocol.
14.1. Routing traffic from a specific subnet to a different default gateway by using nmcli
You can use policy-based routing to configure a different default gateway for traffic from certain subnets. For example, you can configure RHEL as a router that, by default, routes all traffic to internet provider A using the default route. However, traffic received from the internal workstations subnet is routed to provider B.
The procedure assumes the following network topology:
Prerequisites
-
The system uses
NetworkManager
to configure the network, which is the default. The RHEL router you want to set up in the procedure has four network interfaces:
-
The
enp7s0
interface is connected to the network of provider A. The gateway IP in the provider’s network is198.51.100.2
, and the network uses a/30
network mask. -
The
enp1s0
interface is connected to the network of provider B. The gateway IP in the provider’s network is192.0.2.2
, and the network uses a/30
network mask. -
The
enp8s0
interface is connected to the10.0.0.0/24
subnet with internal workstations. -
The
enp9s0
interface is connected to the203.0.113.0/24
subnet with the company’s servers.
-
The
-
Hosts in the internal workstations subnet use
10.0.0.1
as the default gateway. In the procedure, you assign this IP address to theenp8s0
network interface of the router. -
Hosts in the server subnet use
203.0.113.1
as the default gateway. In the procedure, you assign this IP address to theenp9s0
network interface of the router. -
The
firewalld
service is enabled and active.
Procedure
Configure the network interface to provider A:
# nmcli connection add type ethernet con-name Provider-A ifname enp7s0 ipv4.method manual ipv4.addresses 198.51.100.1/30 ipv4.gateway 198.51.100.2 ipv4.dns 198.51.100.200 connection.zone external
The
nmcli connection add
command creates a NetworkManager connection profile. The command uses the following options:-
type
ethernet
: Defines that the connection type is Ethernet. -
con-name
<connection_name>
: Sets the name of the profile. Use a meaningful name to avoid confusion. -
ifname
<network_device>
: Sets the network interface. -
ipv4.method
manual
: Enables to configure a static IP address. -
ipv4.addresses
<IP_address>/<subnet_mask>
: Sets the IPv4 addresses and subnet mask. -
ipv4.gateway
<IP_address>
: Sets the default gateway address. -
ipv4.dns
<IP_of_DNS_server>
: Sets the IPv4 address of the DNS server. -
connection.zone
<firewalld_zone>
: Assigns the network interface to the definedfirewalld
zone. Note thatfirewalld
automatically enables masquerading for interfaces assigned to theexternal
zone.
-
Configure the network interface to provider B:
# nmcli connection add type ethernet con-name Provider-B ifname enp1s0 ipv4.method manual ipv4.addresses 192.0.2.1/30 ipv4.routes "0.0.0.0/0 192.0.2.2 table=5000" connection.zone external
This command uses the
ipv4.routes
parameter instead ofipv4.gateway
to set the default gateway. This is required to assign the default gateway for this connection to a different routing table (5000
) than the default. NetworkManager automatically creates this new routing table when the connection is activated.Configure the network interface to the internal workstations subnet:
# nmcli connection add type ethernet con-name Internal-Workstations ifname enp8s0 ipv4.method manual ipv4.addresses 10.0.0.1/24 ipv4.routes "10.0.0.0/24 table=5000" ipv4.routing-rules "priority 5 from 10.0.0.0/24 table 5000" connection.zone trusted
This command uses the
ipv4.routes
parameter to add a static route to the routing table with ID5000
. This static route for the10.0.0.0/24
subnet uses the IP of the local network interface to provider B (192.0.2.1
) as next hop.Additionally, the command uses the
ipv4.routing-rules
parameter to add a routing rule with priority5
that routes traffic from the10.0.0.0/24
subnet to table5000
. Low values have a high priority.Note that the syntax in the
ipv4.routing-rules
parameter is the same as in anip rule add
command, except thatipv4.routing-rules
always requires specifying a priority.Configure the network interface to the server subnet:
# nmcli connection add type ethernet con-name Servers ifname enp9s0 ipv4.method manual ipv4.addresses 203.0.113.1/24 connection.zone trusted
Verification
On a RHEL host in the internal workstation subnet:
Install the
traceroute
package:# dnf install traceroute
Use the
traceroute
utility to display the route to a host on the internet:# traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 10.0.0.1 (10.0.0.1) 0.337 ms 0.260 ms 0.223 ms 2 192.0.2.1 (192.0.2.1) 0.884 ms 1.066 ms 1.248 ms ...
The output of the command displays that the router sends packets over
192.0.2.1
, which is the network of provider B.
On a RHEL host in the server subnet:
Install the
traceroute
package:# dnf install traceroute
Use the
traceroute
utility to display the route to a host on the internet:# traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 203.0.113.1 (203.0.113.1) 2.179 ms 2.073 ms 1.944 ms 2 198.51.100.2 (198.51.100.2) 1.868 ms 1.798 ms 1.549 ms ...
The output of the command displays that the router sends packets over
198.51.100.2
, which is the network of provider A.
Troubleshooting steps
On the RHEL router:
Display the rule list:
# ip rule list 0: from all lookup local 5: from 10.0.0.0/24 lookup 5000 32766: from all lookup main 32767: from all lookup default
By default, RHEL contains rules for the tables
local
,main
, anddefault
.Display the routes in table
5000
:# ip route list table 5000 0.0.0.0/0 via 192.0.2.2 dev enp1s0 proto static metric 100 10.0.0.0/24 dev enp8s0 proto static scope link src 192.0.2.1 metric 102
Display the interfaces and firewall zones:
# firewall-cmd --get-active-zones external interfaces: enp1s0 enp7s0 trusted interfaces: enp8s0 enp9s0
Verify that the
external
zone has masquerading enabled:# firewall-cmd --info-zone=external external (active) target: default icmp-block-inversion: no interfaces: enp1s0 enp7s0 sources: services: ssh ports: protocols: masquerade: yes ...
Additional resources
-
nm-settings(5)
andnmcli(1)
man pages on your system
14.2. Routing traffic from a specific subnet to a different default gateway by using the network
RHEL system role
You can use policy-based routing to configure a different default gateway for traffic from certain subnets. For example, you can configure RHEL as a router that, by default, routes all traffic to internet provider A using the default route. However, traffic received from the internal workstations subnet is routed to provider B.
To configure policy-based routing remotely and on multiple nodes, you can use the network
RHEL system role.
This procedure assumes the following network topology:
Prerequisites
- You have prepared the control node and the managed nodes
- You are logged in to the control node as a user who can run playbooks on the managed nodes.
-
The account you use to connect to the managed nodes has
sudo
permissions on them. -
The managed nodes uses the
NetworkManager
andfirewalld
services. The managed nodes you want to configure has four network interfaces:
-
The
enp7s0
interface is connected to the network of provider A. The gateway IP in the provider’s network is198.51.100.2
, and the network uses a/30
network mask. -
The
enp1s0
interface is connected to the network of provider B. The gateway IP in the provider’s network is192.0.2.2
, and the network uses a/30
network mask. -
The
enp8s0
interface is connected to the10.0.0.0/24
subnet with internal workstations. -
The
enp9s0
interface is connected to the203.0.113.0/24
subnet with the company’s servers.
-
The
-
Hosts in the internal workstations subnet use
10.0.0.1
as the default gateway. In the procedure, you assign this IP address to theenp8s0
network interface of the router. -
Hosts in the server subnet use
203.0.113.1
as the default gateway. In the procedure, you assign this IP address to theenp9s0
network interface of the router.
Procedure
Create a playbook file, for example
~/playbook.yml
, with the following content:--- - name: Configuring policy-based routing hosts: managed-node-01.example.com tasks: - name: Routing traffic from a specific subnet to a different default gateway ansible.builtin.include_role: name: rhel-system-roles.network vars: network_connections: - name: Provider-A interface_name: enp7s0 type: ethernet autoconnect: True ip: address: - 198.51.100.1/30 gateway4: 198.51.100.2 dns: - 198.51.100.200 state: up zone: external - name: Provider-B interface_name: enp1s0 type: ethernet autoconnect: True ip: address: - 192.0.2.1/30 route: - network: 0.0.0.0 prefix: 0 gateway: 192.0.2.2 table: 5000 state: up zone: external - name: Internal-Workstations interface_name: enp8s0 type: ethernet autoconnect: True ip: address: - 10.0.0.1/24 route: - network: 10.0.0.0 prefix: 24 table: 5000 routing_rule: - priority: 5 from: 10.0.0.0/24 table: 5000 state: up zone: trusted - name: Servers interface_name: enp9s0 type: ethernet autoconnect: True ip: address: - 203.0.113.1/24 state: up zone: trusted
Validate the playbook syntax:
$ ansible-playbook --syntax-check ~/playbook.yml
Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
$ ansible-playbook ~/playbook.yml
Verification
On a RHEL host in the internal workstation subnet:
Install the
traceroute
package:# dnf install traceroute
Use the
traceroute
utility to display the route to a host on the internet:# traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 10.0.0.1 (10.0.0.1) 0.337 ms 0.260 ms 0.223 ms 2 192.0.2.1 (192.0.2.1) 0.884 ms 1.066 ms 1.248 ms ...
The output of the command displays that the router sends packets over
192.0.2.1
, which is the network of provider B.
On a RHEL host in the server subnet:
Install the
traceroute
package:# dnf install traceroute
Use the
traceroute
utility to display the route to a host on the internet:# traceroute redhat.com traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets 1 203.0.113.1 (203.0.113.1) 2.179 ms 2.073 ms 1.944 ms 2 198.51.100.2 (198.51.100.2) 1.868 ms 1.798 ms 1.549 ms ...
The output of the command displays that the router sends packets over
198.51.100.2
, which is the network of provider A.
On the RHEL router that you configured using the RHEL system role:
Display the rule list:
# ip rule list 0: from all lookup local 5: from 10.0.0.0/24 lookup 5000 32766: from all lookup main 32767: from all lookup default
By default, RHEL contains rules for the tables
local
,main
, anddefault
.Display the routes in table
5000
:# ip route list table 5000 0.0.0.0/0 via 192.0.2.2 dev enp1s0 proto static metric 100 10.0.0.0/24 dev enp8s0 proto static scope link src 192.0.2.1 metric 102
Display the interfaces and firewall zones:
# firewall-cmd --get-active-zones external interfaces: enp1s0 enp7s0 trusted interfaces: enp8s0 enp9s0
Verify that the
external
zone has masquerading enabled:# firewall-cmd --info-zone=external external (active) target: default icmp-block-inversion: no interfaces: enp1s0 enp7s0 sources: services: ssh ports: protocols: masquerade: yes ...
Additional resources
-
/usr/share/ansible/roles/rhel-system-roles.network/README.md
file -
/usr/share/doc/rhel-system-roles/network/
directory
14.3. Configuring zone priorities for traffic classification by using firewalld
With zone priorities, you can control the packet classification order by specifying priorities for ingress
and egress
traffic. The benefit is that you can specify the traffic classification order in a zone. So, zone A may be considered before zone B regardless of the source address or interfaces. A zone of a lower priority value has higher precedence over a zone with a higher priority value. This classification has a pair of ingress
priority value and egress
priority value.
14.3.1. Setting same priority value for both traffic types in a zone
By using the --set-priority
option, you can set a common value for both ingress
and egress
traffic classification without explicit specification.
Prerequisites
Create a new zone:
# firewall-cmd --permanent --new-zone=example-zone
Set a common zone priority value for the
example-zone
zone with--set-priority
:# firewall-cmd --permanent --zone example-zone --set-priority -10
By setting a lower value ensures the higher precedence. This ensures that all configured operations for both traffic types in this zone will take precedence over operations from other zones.
Apply permanent configuration to runtime:
# firewall-cmd --reload
Verification
Display the priority value for both traffic types:
# firewall-cmd --permanent --info-zone example-zone example-zone target: default ingress-priority: -10 egress-priority: -10 ... icmp-block-inversion: no ... services: dhcpv6-client mdns samba-client ssh ... forward: yes masquerade: no ...
This setting ensures that the traffic will be considered for classification into the
example-zone
before other zones.
14.3.2. Setting different priority value for each traffic type in a zone
By setting distinct values for ingress
and egress
traffic, you can set priorities for the traffic classification in a zone.
Procedure
Create a new zone:
# firewall-cmd --permanent --new-zone=example-zone
Set a zone priority value for
ingress
traffic in theexample-zone
zone with--set-ingress-priority
:# firewall-cmd --permanent --zone example-zone --set-ingress-priority -10
Set a zone priority value for
egress
traffic in theexample-zone
zone with--set-egress-priority
:# firewall-cmd --permanent --zone example-zone --set-egress-priority 100
Apply permanent configuration to runtime:
# firewall-cmd --reload
Verification
Display the priority value for both traffic types:
# firewall-cmd --permanent --info-zone example-zone example-zone (active) target: default ingress-priority: -10 egress-priority: 100 icmp-block-inversion: no interfaces: eth0 ... services: dhcpv6-client mdns samba-client ssh ... forward: yes masquerade: no ...
These values indicate that the
ingress
traffic has priority over theegress
traffic in theexample-zone
zone before other zones.