Configure CentOS/Rocky/Oracle Linux as a Linux Router

|
Last Updated:
|
|

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;

Basic 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.
Configure CentOS/Rocky/Oracle Linux as a Linux Router

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.

Configure CentOS/Rocky/Oracle Linux as a Linux Router

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

Install pfSense Firewall on KVM

Install and Configure Endian Firewall on VirtualBox

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
koromicha
I am the Co-founder of Kifarunix.com, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

Leave a Comment