1. Introduction
Networking is a critical part of most modern computer infrastructures. Whether for basic Web browsing and Internet usage or specialized applications, passing Internet Protocol (IP) packets around is often the main way to convey data. Yet, since only a small subset of network nodes are connected directly to each other on a global, regional, and even local level, we need ways to guide and pass packets forward.
In this tutorial, we’ll talk about the kernel mechanism that provides forwarding. First, we briefly refresh our knowledge about the difference between the relevant terminology. After that, we check how to enable Linux packet forwarding and discuss its consequences. Finally, we go over applications and use cases of the feature.
We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments unless otherwise specified.
2. Routing and Forwarding
Two main concepts are related to the movement of packets from one node to another:
- routing – determine an inter-device path for each packet based on a set of parameters
- forwarding – transition a received packet to another local device interface for sending
Routing is implemented via algorithms that consider many factors:
- number of routers
- current router state
- current link state
- round trip time (RTT) between routers
- bandwidth
Considering an autonomous system is a network under the control of a single entity with a single routing policy, we distinguish two main categories of routing algorithms:
- EGP (Exterior Gateway Protocol): between autonomous systems
- IGP (Interior Gateway Protocol): within an autonomous system
Thus, to implement routing at the Network Layer (Layer 3), each network device within an autonomous system implements forwarding at both the Data Link Layer (Layer 2) and the Network Layer, so it can pass packets from one of its interfaces to another. Hence, forwarding and routing are synonymous within Network Layer (Layer 3) nodes, so we use them interchangeably here as well:
+---------------------+ +---------------------+
| DEVICE1 | | DEVICE2 |
|____ ____| ... <ROUTE> ... |____ ____|
|if11| <FORWARD> |if12| |if21| <FORWARD> |if22|
+---------------------+ +---------------------+
Most of the time, such devices are routers. Non-router nodes can also function as forwarders.
3. Linux Kernel Forwarding
General-purpose machines can act as routers and forwarders when their operating system (OS) provides the relevant functionality. Since the Linux kernel supports forwarding, there are two main settings under /proc/sys/net/, depending on the IP protocol version:
- IPv4: /proc/sys/net/ipv4/ip_forward
- IPv6: /proc/sys/net/ipv6/conf/all/forwarding
As usual, we have several methods to toggle these options.
3.1. Temporarily Enable Forwarding
To begin with, we can simply change the setting by writing to the files within the relevant pseudo-filesystems:
$ echo 1 > /proc/sys/net/ipv4/ip_forward
$ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
Here, we employ echo and basic redirection to enable both IPv4 and IPv6 forwarding. Conversely, we can use 0 to turn each off.
Of course, we can achieve the same via sysctl:
$ sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
$ sysctl net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.forwarding = 1
Same as before, we write 0 to disable. Using these commands, we can temporarily enable forwarding for testing and troubleshooting purposes until the next reboot.
3.2. Permanently Enable Forwarding
To ensure forwarding settings persist between reboots, we can use the /etc/sysctl.conf file.
First, we write or uncomment the relevant lines in /etc/sysctl.conf:
$ cat /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
Each line is equivalent to the respective sysctl output from earlier.
Finally, we can apply the changes immediately with –load (-p) to avoid the need to reboot:
$ sysctl --load /etc/sysctl.conf
In general, after enabling the settings above, any packet from one interface that’s destined for another’s subnet will get forwarded appropriately without being processed locally. Because of this, if we enable forwarding without any firewall or similar protection, we may be putting the system at risk.
4. Linux Forwarding Applications
To actually leverage forwarding, we perform several steps:
- secure the system with iptables
- enable forwarding via the respective setting
- set up routes
- configure forwarding rules
- locally verify forwarding is in effect
Under Linux, we can use forwarding in diverse situations. Let’s explore some of them.
4.1. Router
Perhaps the most basic use of the kernel forwarding setting is to convert a general-purpose Linux machine into a router. Thus, any regular system can also serve to move packets from one of its interfaces to another.
In this scenario, we can even use virtual interfaces as one of the endpoints.
4.2. Gateway
One common function of routers is that of the default gateway, i.e., the default destination of unknown traffic. In short, this is the device that links an internal with an external network, the latter often being the Internet.
To do so, a device forwards packets between the internal-facing interface or interfaces and the external-facing interface. In other words, traffic to the device that’s not meant for it can go through to the outside.
4.3. Network Address Translation (NAT)
When it comes to Internet gateway routers, in particular, one common feature is Network Address Translation (NAT).
While NAT is a function of firewalls, we need forwarding to configure a Linux system as a NAT forwarder.
4.4. Traffic Capture
By placing a machine between any two directly-connected nodes and enabling forwarding, we can read and analyze, i.e., sniff, the traffic that goes between them with different tools:
In fact, since this scenario can involve two interfaces on the same network, we can get away with raw forwarding and remain hidden from the target, thereby facilitating an eavesdropping attack to capture handshakes, for example.
5. Summary
In this article, we talked about IP forwarding within the Linux kernel.
In conclusion, although there are dedicated forwarding devices, we can leverage Linux to convert a general-purpose machine into a feature-rich forwarder.