Follow through this guide to learn how to configure CentOS/Rocky/Oracle Linux as a Linux Router. A router is a device that connects two or more IP networks or subnetworks. Linux can be configured as a default gateway to route traffic between networks.
Configure CentOS/Rocky/Oracle Linux as a Linux Router
In this tutorial, we will be basing our configuration on this sample network architecture;
IP Address Assignment
Router (Oracle/CentOS/Rocky) Node;
ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:61:8b:f0 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.153/24 brd 192.168.100.255 scope global dynamic noprefixroute enp0s3
valid_lft 85790sec preferred_lft 85790sec
inet6 fe80::a00:27ff:fe61:8bf0/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: enp0s8: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:a3:6a:d3 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.1/24 brd 172.16.0.255 scope global noprefixroute enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::9369:6ae8:76af:9e67/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: enp0s9: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:32:e2:42 brd ff:ff:ff:ff:ff:ff
inet 172.16.1.1/24 brd 172.16.1.255 scope global noprefixroute enp0s9
valid_lft forever preferred_lft forever
inet6 fe80::ea61:99b4:6980:4dd2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Routing table;
ip r
default via 192.168.100.1 dev enp0s3 proto dhcp metric 100
172.16.0.0/24 dev enp0s8 proto kernel scope link src 172.16.0.1 metric 105
172.16.1.0/24 dev enp0s9 proto kernel scope link src 172.16.1.1 metric 106
192.168.100.0/24 dev enp0s3 proto kernel scope link src 192.168.100.153 metric 100
Host on 172.16.0.0/24 Network;
ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:90:ff:e8 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.10/24 brd 172.16.0.255 scope global noprefixroute enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::fffa:c73a:2ba0:bc02/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Routes;
ip r
default via 172.16.0.1 dev enp0s3 proto static metric 100
172.16.0.0/24 dev enp0s3 proto kernel scope link src 172.16.0.10 metric 100
Host on 172.16.1.0/24 network;
ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:87:01:a6 brd ff:ff:ff:ff:ff:ff
inet 172.16.1.10/24 brd 172.16.1.255 scope global noprefixroute enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::f5ff:ebb9:ef12:eb10/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Routes;
ip r
default via 172.16.1.1 dev enp0s3 proto static metric 100
172.16.1.0/24 dev enp0s3 proto kernel scope link src 172.16.1.10 metric 100
As you might have already figured out;
- No LAN system on 172.16.0.0/24 and 172.16.1.0/24 network has internet access, except the router itself
- LAN systems can access the router only.
- Systems on different LANs cannot communicate.
Enable Kernel IP forwarding on Ubuntu Linux Router
In order for the Linux router to function as a router, receive and forward packets, you need to enable kernel IP forwarding.
To enable IP forwarding, you need to uncomment the line net.ipv4.ip_forward
on the /etc/sysctl.conf
configuration file and set its value to 1, if by any chance it is set to 0.
So, first check if the said line is already defined on the configuration file;
grep net.ipv4.ip_forward /etc/sysctl.conf
if the line is present in the config file and commented, simply uncomment by running the command below;
sed -i '/net.ipv4.ip_forward/s/^#//' /etc/sysctl.conf
Otherwise, just insert the line;
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
Next, apply the changes;
sysctl -p
Check the status by running the command below;
sysctl net.ipv4.ip_forward
Value should be 1.
At this point, the systems on different LANs, 172.16.0.0/24 and 172.16.1.0/24 can now JUST ping each other. They do not have Internet access, however.
Configure Packet Forwarding on Linux Router
The configurations in the next step can be handled using iptables
or via the firewalld
.
We use IPtables in this guide;
Hence, stop Firewalld and install IPtables service and start IPtables;
systemctl disable --now firewalld
dnf install iptables-services -y
systemctl enable --now iptables
The current firewall rules are saved;
iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
139 10300 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 78 packets, 6552 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 103 packets, 14732 bytes)
pkts bytes target prot opt in out source destination
First of all, we will set the default policy for the FORWARD chain to DROP so we can explicitly define which traffic to be allowed.
iptables -P FORWARD DROP
Next, let’s configure the packets received from router LAN interfaces (enp0s8 and enp0s9) to be forwarded through the WAN interface, which in our case is enp0s3
.
iptables -I FORWARD -i enp0s8 -o enp0s3 -j ACCEPT
iptables -A FORWARD -i enp0s9 -o enp0s3 -j ACCEPT
Enable packet forwarding between LAN networks;
iptables -A FORWARD -i enp0s9 -o enp0s8 -j ACCEPT
iptables -A FORWARD -i enp0s8 -o enp0s9 -j ACCEPT
Similarly, configure packets that are associated with existing connections received on a WAN interface to be forwarded to the LAN interfaces;
iptables -A FORWARD -i enp0s3 -o enp0s8 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i enp0s3 -o enp0s9 -m state --state RELATED,ESTABLISHED -j ACCEPT
Note, if you do not want to use the individual FORWARD chain rules above, you can simply allow anything across the chain;
iptables -I FORWARD -j ACCEPT
Configure Router Network Address Translation
Next, configure the router to allow LAN systems to access Internet via the routers default GW IP address. This is called IP Masquerade.
IP Masquerade can only be done on the NAT table;
iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
Consult man iptables
for more information.
Save iptables rules Permanently in Linux
Yo permanently save iptables rules, use the iptables-save
command as follows.
cp /etc/sysconfig/iptables{,.bak}
iptables-save > /etc/sysconfig/iptables
Install IPtables services and restart the services to reload the rules and apply the newly added ones;
dnf install iptables-services
systemctl restart iptables
Confirm the rules;
iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
34 2296 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- enp0s8 enp0s3 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- enp0s9 enp0s3 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- enp0s9 enp0s8 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- enp0s8 enp0s9 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- enp0s3 enp0s8 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- enp0s3 enp0s9 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT 20 packets, 4388 bytes)
pkts bytes target prot opt in out source destination
Check the NAT tables rules;
iptables -t nat -L -nv
Chain PREROUTING (policy ACCEPT 6 packets, 440 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 1 packets, 60 bytes)
pkts bytes target prot opt in out source destination
5 380 MASQUERADE all -- * enp0s3 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Systems on different LANs should now be able to communicate with each other and to the outside world.
And there you go. Your CentOS/Rocky/Oracle Linux machine now should be able to route traffic through for your LAN.
That concludes our guide on how to configure Linux as a router.
Other Tutorials
Basic Operation of Firewalld in Linux