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:

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:

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.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.