Configure Linux as a Router (IP Forwarding)
Author: Matt Wildman
Other contributors: Nathaniel Stickman
View edit history on GitHub → Originally authored by Matt WildmanTraducciones al EspañolEstamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
A computer network is a collection of computer systems that can communicate with each other. In order to communicate with a computer that’s on a different network, a system needs a way to connect to that other network. A router is a system that acts as an intermediary between multiple different networks. It receives traffic from one network that is ultimately destined for another. It identifies where a particular packet should be delivered, then forwards that packet over the appropriate network interface.
There are lots of options for off-the-shelf router solutions for both home and enterprise use. These solutions are often preferred for numerous reasons. They are relatively easy to configure, have lots of features, tend to have a user-friendly management interface, and may even come with support options. Under the hood, these routers are stripped-down computers running common operating systems, such as Linux.
Instead of using one of these pre-built solutions, you can create your own using any Linux server, such as an Akamai Cloud Compute Instance. Routing software like iptables provides total control over configuring a router and firewall to suit your individual needs. This guide covers how to set up a Linux system as a basic router, including enabling IP forwarding and configuring network routing.
Use Cases for a Cloud-based Router
Many workloads benefit from custom routing or port forwarding solutions, including those workloads hosted on cloud platforms like Akamai. For example, it’s common practice for security-minded applications to connect most of their systems together through a private network, like a VLAN. These systems might need access to an outside network, such as other VLANs or the public internet. Instead of giving each system their own interface to the other network, one system on the private network can act as a router. The router is configured with multiple network interfaces: one to the private VLAN and another to the other network. It then forwards packets from one interface to another. This can make monitoring, controlling, and securing traffic much easier, as it can all be done from a single system. Akamai Cloud Compute Instances can be configured with up to three interfaces, each connecting to either the public internet or a private VLAN:
- Connect systems on private VLAN to the public internet.
- Connect systems on two separate private VLANs.
- Forward IPv6 addresses from a /56routed range.
Configure a Linux System as a Router
Here are the basic steps needed to configure a Linux system as a router:
- Deploy at least two Compute Instances (or other virtual machines) to the same data center. Connect all systems to the same private network, like a VLAN. Designate one system as the router and connect it to the public internet or a different private network. 
- Enable IP Forwarding on the Compute Instance designated as the router. 
- Configure the Routing Software on that router instance. This guide covers using nftables, iptables, or Firewalld. 
- Define the Gateway on each system other than the router. This gateway should point to the router’s IP address on that network. 
Continue reading for detailed instructions on each of these steps.
Deploy Compute Instances
To get started, use the Akamai Cloud Compute platform to deploy multiple Compute Instances. These can mimic a basic application that is operating on a private VLAN with a single router. Skip this section if you already have an application deployed and just wish to know how to configure IP forwarding or the router software.
- Deploy two or more Compute Instances to the same region and designate one as the router. This guide uses Debian 12, but the instructions are generally applicable to other Linux distributions. On the deployment page, skip the VLAN section for now. See Creating a Compute Instance to learn how to deploy Linode Compute Instances. 
- Edit each Compute Instance’s configuration profile. See Managing Configuration Profiles for information on viewing and editing configuration profiles. - Router Instance: On the Compute Instance designated as the router, leave eth0 as the public internet and set eth1 as a VLAN. Enter a name for the VLAN and assign it an IP address from whichever subnet range you wish to use. For example, if you wish to use the - 10.0.2.0/24subnet range, assign the IP address- 10.0.2.1/24. By convention, the router should be assigned the value of- 1in the last segment.
- Other Instance/s: On each Compute Instance other than the router, remove all existing network interfaces. Set eth0 as a VLAN, select the VLAN you just created, and enter another IP address within your desired subnet (e.g. - 10.0.2.2/24,- 10.0.2.3/24, and so on).
 
- Confirm that Network Helper is enabled and reboot each Compute Instance for the changes to take effect. 
- Log in to each instance and test the connectivity on each Compute Instance to ensure proper configuration. To do this, you can use SSH, or Lish if utilizing an Akamai Cloud Compute Instance. - Ping the VLAN IPv4 address of another system within the same VLAN: Router Instance- ping 10.0.2.2Other Instance/s- ping 10.0.2.1- Each Compute Instance should be able to ping the IP addresses of all other instances within that VLAN. 
- Ping an IP address or website of a system on the public internet. All Instances- ping linode.com- This ping should only be successful for the Compute Instance configured as the router. 
 
Enable IP Forwarding
IP forwarding plays a fundamental role on a router. This is the functionality that allows a router to forward traffic from one network interface to another. When configured along with routing software, it allows a computer on one network to reach a computer on a different network. Forwarding for both IPv4 and IPv6 addresses are controlled within the Linux kernel. The following kernel parameters are used to enable or disable IPv4 and IPv6 forwarding, respectively:
- IPv4: net.ipv4.ip_forwardornet.ipv4.conf.all.forwarding
- IPv6: net.ipv6.conf.all.forwarding
Forwarding is disabled on most Linux systems by default. However, this must be enabled to configure Linux as a router. To enable forwarding, the corresponding parameter should be set to 1. A value of 0 indicates that forwarding is disabled. To update these kernel parameters, edit the /etc/sysctl.conf file as shown in the steps below:
- On the Linux system you intend to use as a router, determine if IPv4 forwarding is currently enabled or disabled. The command below outputs the value of the given parameter. A value of - 1indicates that the setting is enabled, while- 0indicates it is disabled.Router Instance- sudo sysctl net.ipv4.ip_forward- net.ipv4.ip_forward = 0- If this parameter returns with a value of - 0, it is disabled, and you must continue with the instructions below.- Note - If you intend to configure IPv6 forwarding, check that kernel parameter as well: - sudo sysctl net.ipv6.conf.all.forwarding
- Open the - /etc/sysctl.conffile using a command-line text editor with- sudopermissions such as nano:Router Instance- sudo nano /etc/sysctl.conf
- Find the line corresponding with the type of forwarding you wish to enable, uncomment it, and set the value to - 1. Alternatively, you can add the following lines anywhere in the file.- File: /etc/sysctl.conf
- 27 28 29 30 31 32 33- # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 # Uncomment the next line to enable packet forwarding for IPv6 # Enabling this option disables Stateless Address Autoconfiguration # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1
 
- When done, press CTRL+X, followed by Y then Enter to save the file and exit - nano.
- Once the changes are saved, run the following command (or reboot the machine) to apply them: Router Instance- sudo sysctl -p- net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1
Configure the Routing Software
Linux network utilities like nftables, iptables, and Firewalld can serve as both a firewall and as a router. This section covers how to configure each of these tools to function as a basic router. You can, alternatively, opt for a commercial routing application.
- On the Linux system you intend to use as a router, review the existing network rules. On a fresh Linux installation, there may not be any preconfigured rules. If there are, look for any rules that might interfere with your intended configuration. Consult a system administrator or the network utility documentation linked below to help determine. Router Instance- sudo nft list ruleset- Refer to the nftables documentation for an explanation of any existing rules. - If necessary, flush the existing rules and configure nftables to allow all traffic: Router Instance- sudo nft flush ruleset sudo nft add table inet filter sudo nft add chain inet filter input '{type filter hook input priority 0; policy accept; }' sudo nft add chain inet filter forward '{type filter hook forward priority 0; policy accept; }' sudo nft add chain inet filter output '{type filter hook output priority 0; policy accept; }'Router Instance- sudo iptables -S- Refer to the iptables documentation for clarification on any extant rules. - If necessary, flush your existing rules and configure iptables to allow all traffic: Router Instance- sudo iptables -F sudo iptables -X sudo iptables -t nat -F sudo iptables -t nat -X sudo iptables -t mangle -F sudo iptables -t mangle -X sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD ACCEPTRouter Instance- sudo firewall-cmd --list-all-zones- Refer to the Firewall-cmd documentation for more on any existing configuration. - If necessary, return to Firewalld defaults and subsequently allow all traffic: Router Instance- sudo rm -rf /etc/firewalld/zones/ sudo firewall-cmd --zone=public --set-target=ACCEPT --permanent sudo firewall-cmd --complete-reload- success success
- Configure the utility to allow port forwarding. This is the default setting for many systems. Router Instance- sudo nft add chain inet filter forward '{type filter hook forward priority 0; policy accept; }'Router Instance- sudo iptables -A FORWARD -j ACCEPTRouter Instance- sudo firewall-cmd --zone=public --add-forward- success
- Configure NAT (network address translation) within the utility. This modifies the IP address details in network packets, allowing all systems on the private network to share the same public IP address of the router. Replace - 10.0.2.0/24in the following command with the subnet of your private VLAN.- nftables does not include a - nattable by default, so you should create one, along with- preroutingand- postroutingchains. While the masquerading rule only applies to the postrouting chain, the nftables configuration requires the complementary prerouting chain as well.Router Instance- sudo nft add table inet nat sudo nft add chain inet nat prerouting '{ type nat hook prerouting priority -100; }' sudo nft add chain inet nat postrouting '{ type nat hook postrouting priority 100; }'- From there, you can add the - masqueraderule to apply to connections from the private network.Router Instance- sudo nft add rule inet nat postrouting ip saddr 10.0.2.0/24 masquerade- Note - Alternatively, you can apply the rule without a specific subnet. In this case, the masquerade applies to any connection passed through the router. Router Instance- sudo nft add rule inet nat postrouting masqueradeRouter Instance- sudo iptables -t nat -s 10.0.2.0/24 -A POSTROUTING -j MASQUERADE- Note - Alternatively, you can forgo specifying a subnet and allow NAT over all traffic using the command below: Router Instance- sudo iptables -t nat -A POSTROUTING -j MASQUERADERouter Instance- sudo firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=10.0.2.0/24 masquerade'- success- Note - Alternatively, to masquerade and allow NAT over all traffic through the router, use the command below: Router Instance- sudo firewall-cmd --zone=public --add-masquerade
- Make the configurations persistent. - nftables rules apply immediately, but only hold until the nftables service restarts. To persist an nftables setup across restarts, you need to define that setup in the nftables configuration file, located at - /etc/nftables.conf. The file needs to begin with two lines, the first executing the nftables command and the second flushing the current ruleset:- File: /etc/nftables.conf
- 1 2 3- #!/usr/sbin/nft -f flush ruleset
 - After this, you can paste your ruleset. To get the current ruleset, use the same list command as shown further above: Router Instance- sudo nft list ruleset- Note - More conveniently, you can combine these steps into a set of commands to automatically recreate the configuration file from your current nftables rules. The first command recreates the configuration file with the necessary preamble lines, while the second adds your current configuration to the file: Router Instance- sudo sh -c 'echo -e "#!/usr/sbin/nft -f\n\nflush ruleset\n" > /etc/nftables.conf' sudo sh -c 'nft list ruleset >> /etc/nftables.conf'- By default, iptables rules are ephemeral. To make your configuration changes persistent, install the - iptables-persistentpackage. When you do this, the rules saved within- /etc/iptables/rules.v4(and- rules.v6for IPv6) are loaded when the system boots up.- You can continue making changes to iptables as normal. When you are ready to save, save the output of iptables-save to the - /etc/iptables/rules.v4(or- rules.v6) file. For more information, see the relevant section in the Controlling Network Traffic with iptables guide.Router Instance- sudo mkdir /etc/iptables | sudo iptables-save | sudo tee /etc/iptables/rules.v4- The Firewalld commands above are dynamic, meaning they take effect immediately but are not persistent. You can add the - --permanentoption to each command to make it persistent, however, Firewalld offers a dedicated command to persist its current dynamic configuration:Router Instance- sudo firewall-cmd --runtime-to-permanent- success- Note - Linux systems using SELinux may need to first set SELinux enforcement to - permissivein order to convert runtime rules to persistent rules. You can do so with the following command:Router Instance- sudo setenforce permissive- When you have made the rules persistent, you can return to the previous SELinux setting with - setenforce 1.
Define the Gateway
The last step is to manually adjust the network configuration settings for each Compute Instance other than the router.
- Log in to the Cloud Manager and disable Network Helper for each non-router Compute Instance you’ve deployed. While Network Helper was useful for automatically configuring the VLAN IP addresses, the configuration files controlled by Network Helper now need to be manually edited. 
- Log in to each Linux system that is not designated as the router. To do so, you can use SSH from the router, or Lish if using an Akamai Cloud Compute Instance. 
- Edit the configuration file that contains the settings for the private VLAN interface. The name and location of this file depends on the Linux distribution you are using. See the Manual Network Configuration on a Compute Instance series of guides and select the specific guide for your distribution. For a system running ifupdown on Debian 12, the network configuration is typically stored within - /etc/network/interfaces:Other Instance/s- sudo nano /etc/network/interfaces
- Within this file, adjust the parameter that defines the gateway for the VLAN interface. The value should be set to the IP address assigned to the router’s VLAN interface, such as - 10.0.2.1if using the examples in this guide. For a system running ifupdown on Debian 12, add the gateway parameter in the location shown in the example below:- File: /etc/network/interfaces
- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27- # Generated by Linode Network Helper # Wed Dec 20 16:02:08 2023 UTC # # This file is automatically generated on each boot with your Linode's # current network configuration. If you need to modify this file, please # first disable the 'Auto-configure networking' setting within your Linode's # configuration profile: # - https://cloud.linode.com/linodes/53248278/configurations # # For more information on Network Helper: # - https://www.linode.com/docs/guides/network-helper/ # # A backup of the previous config is at /etc/network/.interfaces.linode-last # A backup of the original config is at /etc/network/.interfaces.linode-orig # # /etc/network/interfaces auto lo iface lo inet loopback source /etc/network/interfaces.d/* auto eth0 iface eth0 inet static address 10.0.2.2/24 gateway 10.0.2.1
 
- When done, press CTRL+X, followed by Y then Enter to save the file and exit - nano.
- Once those settings are saved, restart the Compute Instance or run the corresponding command to apply the changes. Continuing to use ifupdown as an example, run the command below to apply the new network configuration settings: Other Instance/s- sudo ifdown eth0 && sudo ip addr flush eth0 && sudo ifup eth0- Note - The first part of the command shuts down networking services, causing you to briefly lose connection, which outputs the following error message: - RTNETLINK answers: No such process- This error can be safely ignored. 
Test the Connection
To verify the configuration settings are correct, run the same tests from the last step of the Deploy Compute Instances section. Specifically, ping a public IP address or domain from a Compute Instance within the private VLAN that’s not designated as the router:
ping linode.comThis ping should now complete successfully, indicating that the network traffic was successfully forwarded through the router to the public internet.
This page was originally published on