TTR Networks

Intermediate · Debian as an office router: interfaces, VLANs and a firewall · section 1 of 8

Why a plain Debian router

✓ Lab-tested 5 November 2026 on Debian 13.7, systemd 257, nftables 1.1.3

Turn a fresh Debian 13 install into an office router: systemd-networkd for the WAN and three VLANs on one trunk, IP forwarding, an nftables policy between VLANs with NAT, protecting the router itself, and a configuration that survives a reboot.

By the end you will be able to:

  • Configure WAN, trunk and VLAN interfaces with systemd-networkd .network and .netdev files
  • Explain what IP forwarding does, and turn it on permanently with a sysctl.d file
  • Write an nftables policy between VLANs with a verdict map, plus NAT to the internet
  • Restrict access to the router itself by the interface traffic arrives on
  • Check that the configuration survives a reboot, and find the cause when a VLAN or a path doesn't work

Prerequisites: Linux Network Connectivity, nftables and iptables on Debian: host and router firewalls

A router doesn't have to be an appliance. A plain Debian machine with two network ports, or one port and a VLAN-capable switch, can route an office, keep the guests away from the servers and share one public address, using nothing but files in /etc and software that ships with Debian. This lesson builds that box from a fresh install; the rest of the Build a router in a box with Debian path adds DHCP and DNS, IPv6, a second ISP, a second router, VPNs and BGP to the same machine.

Why plain Debian?

  • You can see everything. Every setting is a text file you can read, diff, back up and copy to the next router. Nothing is hidden behind a web interface.
  • It's the same Linux you already run. The tools from Linux Network Connectivity and nftables and iptables on Debian work unchanged.
  • It grows. Need a VPN, a DNS server, BGP? apt install it on the same box.

The cost is that nothing is done for you: no wizard sets up forwarding or a firewall, so this lesson does each step and shows what fails without it. If you'd rather have a router distribution that does more for you, Setting up VyOS with NAT builds a similar office on VyOS.

The box and the plan

Three pieces of configuration, each a standard Debian component:

JobDone byFiles
Interfaces, VLANs, addresses, default routesystemd-networkd/etc/systemd/network/*.network, *.netdev
Routing between networksthe kernel, once forwarding is on/etc/sysctl.d/99-router.conf
Who may talk to whom, and NATnftables/etc/nftables.conf

The lab

The router has two ports. eth0 faces the ISP, with a fixed public address, 203.0.113.2. eth1 is a trunk to the office switch carrying three VLANs: staff (VLAN 10), guest Wi-Fi (VLAN 20) and servers (VLAN 30), each with its own /24 and the router as gateway (.1). A web server on the internet side logs who connects.

The policy the router must enforce:

From ↓ to →InternetStaffGuestServers
Staffyes–noyes
Guestyesno–no
Serversyesnono–

Replies to allowed connections always come back; the table is about who may start a connection.

Diagram: The router-in-a-box lab — One Debian box between the ISP and an office switch: a WAN port and a trunk carrying the staff, guest and server VLANs.
  1. One cable, three networks. eth1 is a trunk: every frame carries an 802.1Q tag, and the router hands it to the staff, guest or servers VLAN interface. Each VLAN has its own /24, with the router at .1.
  2. Staff to the internet. Forwarding on, and the verdict map allows staff to WAN. On the way out, masquerade replaces 10.10.10.20 with the router's public address, so the web server sees 203.0.113.2.
  3. Staff to the servers. The second allowed pair: staff may start connections to the server VLAN. No NAT inside the office: the server sees the staff PC's own address.
  4. Guests: internet only. A guest's connection to the server matches no line in the verdict map, so the forward chain's drop policy ends it. The guest can still reach the internet.
The versions in this lab (real output)
root@router:~# cat /etc/debian_version; systemctl --version | head -1; nft --version; dpkg-query -W dnsmasq; uname -r
13.7
systemd 257 (257.13-1~deb13u1)
nftables v1.1.3 (Commodore Bullmoose #4)
dnsmasq	2.91-1+deb13u2
7.0.14-linuxkit
  • Lines 2–5: Debian 13.7 with its own systemd (for networkd), nftables and dnsmasq (used in the next lesson). Nothing from outside Debian.