How to Configure Virtual Routing and Forwarding (VRF) in Ubuntu Using systemd-networkd

In modern enterprise server and cloud networking environments, multi-tenant isolation and out-of-band management require separating routing decisions on a single Linux operating system. Virtual Routing and Forwarding (VRF) allows the Linux kernel to support multiple distinct routing tables concurrently, ensuring that traffic originating within one network domain cannot leak into another even if IP subnets overlap. While administrators traditionally configure VRFs imperatively using the iproute2 suite, Ubuntu Server provides robust, declarative VRF orchestration through systemd-networkd. This article demonstrates how to define declarative VRF network devices, bind physical and VLAN slave interfaces, manage dedicated routing tables, and validate packet isolation in Ubuntu using systemd-networkd.

Understanding Linux VRF Architecture and Routing Isolation

By default, the Linux kernel evaluates network packets against the global main routing table (table 254). When network segmentation requires isolated administrative planes—such as isolating dedicated management traffic from customer-facing application services—standard interface binding is insufficient. Linux VRF operates by creating a virtual master network device associated with an independent kernel routing table number (between 1 and 2,147,483,647).

When slave interfaces (such as eth1, bonding interfaces, or 802.1Q VLANs) are enslaved to a VRF master device:

  • Inbound traffic arriving on the slave interface is automatically routed according to the VRF’s dedicated routing table rather than the host’s default gateway.
  • Connected and static routes assigned to slave interfaces populate the isolated VRF table exclusively.
  • Network daemons and management services can be bound explicitly to the VRF domain using socket options (SO_BINDTODEVICE) or the ip vrf exec wrapper, preventing uncoordinated network traversal.

Configuring the Declarative VRF Virtual Device (.netdev)

To define a VRF in systemd-networkd, create a declarative .netdev definition file within /etc/systemd/network/. In this example, we configure an isolated management VRF named vrf-mgmt tied to kernel routing table 100.

Create the file /etc/systemd/network/10-vrf-mgmt.netdev:

[NetDev]
Name=vrf-mgmt
Kind=vrf

[VRF]
Table=100

The Kind=vrf directive instructs systemd-networkd to create a virtual network device backed by the kernel’s VRF driver, while Table=100 binds all enslaved routing logic to routing table 100.

Configuring the VRF Master and Slave Interfaces (.network)

Once the virtual device is declared, create corresponding .network configuration files to activate the VRF master device and attach slave interfaces.

First, create /etc/systemd/network/15-vrf-mgmt.network to bring up the master interface:

[Match]
Name=vrf-mgmt

[Network]
# The master VRF interface operates at layer 3 and does not require an IP address
ConfigureWithoutCarrier=yes

Next, configure the physical or virtual interface that will participate in this VRF. For example, to enslave interface eth1 and assign a static management IP address and isolated default gateway, create /etc/systemd/network/20-eth1-management.network:

[Match]
Name=eth1

[Network]
VRF=vrf-mgmt
Address=192.168.50.10/24

[Route]
Gateway=192.168.50.1
Table=100

The critical parameter is VRF=vrf-mgmt, which assigns eth1 as a subordinate slave to the vrf-mgmt master. The route configuration explicitly places the default gateway into routing table 100.

Applying Network Configuration and Verifying Interfaces

Set appropriate file permissions and restart systemd-networkd to instantiate the declarative configuration:

sudo chmod 644 /etc/systemd/network/*
sudo systemctl restart systemd-networkd

Verify that the VRF device is created and running using networkctl:

networkctl status vrf-mgmt

Inspect the link state and slave relationship using ip link:

ip -d link show vrf-mgmt
ip link show eth1

The output for eth1 will display master vrf-mgmt, confirming successful enslavement to the VRF domain.

Inspecting Isolated Routing Tables and Policy Rules

Verify that connected routes and gateways are correctly isolated from the main routing table:

# Inspect the standard host routing table (must NOT contain eth1 routes)
ip route show

# Inspect the dedicated VRF table 100
ip route show table 100

You will observe that 192.168.50.0/24 dev eth1 and the default route via 192.168.50.1 reside exclusively in table 100. To check the kernel policy database rules automatically created for the VRF, run:

ip rule show

The kernel installs lookup rules pointing to the VRF master device (e.g. from all oif vrf-mgmt lookup 100).

Executing Services and Diagnostics Within the VRF Domain

Standard network tools such as ping or curl query the default routing table unless directed into the VRF. To execute diagnostics through the isolated management interface, use ip vrf exec:

sudo ip vrf exec vrf-mgmt ping -c 3 192.168.50.1

To bind an existing systemd service—such as an SSH daemon dedicated exclusively to management access—edit the service unit with systemctl edit sshd.service and inject the BindToInterface directive:

[Service]
BindToInterface=vrf-mgmt

This ensures that the SSH server listens exclusively on interfaces enslaved to vrf-mgmt, achieving robust network plane isolation across your Ubuntu infrastructure.

Get the best tech tips delivered straight to your inbox.

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