How to Configure Netplan for Policy-Based Routing on Ubuntu Servers

The Need for Policy-Based Routing (PBR)

In standard network routing, a server decides where to send outgoing packets based purely on the destination IP address. It consults its routing table, finds the best match (usually the default gateway), and forwards the packet. However, in complex enterprise environments, destination-based routing is not always sufficient.

Suppose you have an Ubuntu server with two network interfaces connected to two different ISPs. You want web server traffic (port 80/443) to exit via ISP A, but you want database synchronization traffic (port 3306) to exit via ISP B. Or, you want traffic originating from a specific internal IP subnet to bypass the default gateway and use a dedicated VPN tunnel.

This is where Policy-Based Routing (PBR) comes in. PBR allows you to route traffic based on criteria other than the destination IP—such as the source IP address or the incoming interface. On modern Ubuntu servers, PBR is configured natively using Netplan and iproute2 routing tables.

Step 1: Understanding Multiple Routing Tables

To implement PBR, Linux utilizes multiple routing tables. Instead of just having one “main” routing table, you can create custom tables (numbered 1 through 252) and assign distinct default gateways to them.

You then create Routing Policy Rules (using the ip rule command) that dictate which traffic should consult which routing table.

Step 2: Designing the Netplan Configuration

Assume we have an Ubuntu server with two network interfaces:

  • eth0: Connected to the primary corporate network (Gateway: 192.168.1.1). This is the default route for all normal traffic.
  • eth1: Connected to a specialized high-speed backup link (IP: 10.0.5.50, Gateway: 10.0.5.1). We want traffic originating from 10.0.5.50 to strictly use the 10.0.5.1 gateway, ensuring asymmetric routing does not drop our packets.

Step 3: Writing the Netplan YAML File

Open your primary Netplan configuration file (typically located in /etc/netplan/):

sudo nano /etc/netplan/01-netcfg.yaml

Configure the standard eth0 interface as usual. For eth1, we will define a custom routing table (Table 100) and explicitly map a routing policy rule to it.

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
    eth1:
      dhcp4: no
      addresses:
        - 10.0.5.50/24
      routes:
        # Define a default route inside custom Table 100
        - to: default
          via: 10.0.5.1
          table: 100
      routing-policy:
        # Force traffic originating from this IP to consult Table 100
        - from: 10.0.5.50
          table: 100
        # Force traffic arriving on this interface to reply via Table 100
        - iif: eth1
          table: 100

Step 4: Applying the Configuration

Netplan translates this YAML syntax directly into systemd-networkd configuration files or NetworkManager connections, depending on your renderer.

To apply the configuration and instantly enforce the policy routing, run:

sudo netplan apply

Step 5: Verifying the Policy Routing

To ensure that the Linux kernel has correctly ingested your policy rules, you must inspect both the routing tables and the routing policy database.

First, check the custom routing table (Table 100) to ensure the alternative default gateway is present:

ip route show table 100

You should see: default via 10.0.5.1 dev eth1.

Next, verify the routing policy database using the ip rule command:

ip rule show

The output will list the rules in order of priority. You should see entries resembling:

0:      from all lookup local
32764:  from all iif eth1 lookup 100
32765:  from 10.0.5.50 lookup 100
32766:  from all lookup main
32767:  from all lookup default

This confirms that if a packet originates from 10.0.5.50, the kernel will hit rule 32765, stop evaluating, look inside Table 100, and immediately push the packet out to the 10.0.5.1 gateway.

Conclusion

Policy-Based Routing solves complex asymmetric routing and multi-homing challenges that standard destination-based routing cannot handle. By utilizing Netplan’s native routing-policy directives, Ubuntu administrators can permanently and declaratively configure advanced multi-gateway architectures without writing fragile ip route bash scripts that break upon reboot.

RELATED POSTS

  • How to Configure Linux chrony for High-Precision Network Time Protocol (NTP)
  • How to Use the fuser Command to Identify Processes Locking a File in Linux
  • How to Manage Log Files Using Logrotate on Ubuntu Linux
  • How to Manage Linux Services using the systemctl Command
  • How to Install and Configure the Cockpit Web Console on Ubuntu
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.