DIY Debian Router - Part 2: Network configuration with systemd-networkd
Introduction
This is Part 2 of the DIY Debian Router series. See Part 1 for the series introduction and links to all parts.
This part covers the implementation of WAN/LAN separation, Linux bridge setup for LAN ports, and IPv4/IPv6 addressing using systemd-networkd, the network management daemon included with systemd. As discussed in Part 1, I'll be using five Ethernet interfaces: one WAN uplink and four LAN ports aggregated into a Layer 2 bridge.
Initial system preparation
Package installation
Install all packages (used throughout all posts in this series):
Package summary:
kea: ISC Kea DHCP server (DHCPv4/DHCPv6)unbound: Validating recursive DNS resolvernftables: Modern Linux firewall frameworkdnsutils: DNS troubleshooting tools (dig,nslookup)iperf3: Network performance testingwireguard: WireGuard userland utils
SSH server access and hardening
To enable SSH, run:
Before proceeding with network configuration, secure SSH access to prevent lockout or unauthorized access. Start by ensuring you have SSH keys properly configured before applying these settings to avoid lockout.
Edit /etc/ssh/sshd_config and enforce the following settings:
This disables root login and password-based authentication, requiring SSH key authentication for all access.
Restart SSH to apply changes:
Enable serial console
If your system has a serial console, I would recommended enabling it as a last resort access method:
Edit your /etc/default/grub to contain:
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
Update grub:
Enable serial port services (this might not be entirely needed, but hey):
Reboot your system and test with a serial cable to confirm everything works as expected.
Disable conflicting network managers
Debian may have multiple network management systems active. Disable legacy networking and NetworkManager if present:
# Disable traditional networking
# Disable ifupdown if installed
# Disable NetworkManager if installed
# Disable dhcpcd if installed
Enable systemd-networkd:
systemd-networkd configuration
Network configuration in systemd-networkd uses .network, .netdev, and .link files in /etc/systemd/network/. Files are processed in lexicographical order.
Network device definitions
First, define the bridge device for LAN aggregation.
/etc/systemd/network/10-br0.netdev
[NetDev]
br0
bridge
[Bridge]
STP=no
This creates a bridge named br0 with Spanning Tree Protocol disabled (not needed for a simple single-bridge topology).
WAN interface configuration
Configure the WAN interface for IPv4 DHCP and IPv6 autoconfiguration.
✏️ Replace
enp8s0with your actual WAN interface name. Useip linkto identify interface names.
/etc/systemd/network/20-wan.network
[Match]
enp8s0
[Network]
DHCP=yes
yes
[DHCPv4]
no
yes
100
[IPv6AcceptRA]
no
100
[Link]
yes
Configuration breakdown:
DHCP=yes: Enable DHCPv4 client for obtaining public IPv4 address from ISPIPv6AcceptRA=yes: Accept IPv6 Router Advertisements from ISP for SLAACUseDNS=no: Do not use DNS servers from DHCP/RA (router runs its own DNS resolver in Part 3)UseRoutes=yes: Accept default gateway from DHCP (DHCPv4 section only)- IPv6AcceptRA section automatically accepts routes from RAs by default
RouteMetric=100: Route preference (lower is preferred)RequiredForOnline=yes: System considers network "online" only when WAN is configured
LAN bridge member interfaces
Add the four LAN ports to the bridge.
✏️ Replace
enp4s0,enp5s0,enp6s0,enp7s0with your actual LAN interface names.
/etc/systemd/network/30-lan-members.network
[Match]
enp4s0 enp5s0 enp6s0 enp7s0
[Network]
br0
yes
[Link]
no
Configuration breakdown:
Name=enp4s0 enp5s0 enp6s0 enp7s0: Apply configuration to all four LAN portsBridge=br0: Attach interfaces to bridgeConfigureWithoutCarrier=yes: Allow configuration even if no cable is connectedRequiredForOnline=no: Individual LAN ports don't need to be up for system to be "online"
LAN bridge interface configuration
Configure the bridge interface with static IPv4 and IPv6 addressing.
✏️ Recall from Part 1, the static LAN IPv6 address below (
fd09:dead:beef::/48) is a fake example. You should use a proper randomly generated address instead, per RFC4193.
/etc/systemd/network/40-br0.network
[Match]
br0
[Network]
fd09:dead:beef::1/48
no
yes
[Link]
carrier
Configuration breakdown:
Address=192.168.0.1/24: Static IPv4 address for LAN gatewayAddress=fd09:dead:beef::1/48: Static IPv6 ULA address for LAN gatewayIPv6AcceptRA=no: Do not accept RAs on LAN interface (router generates RAs, doesn't consume them)ConfigureWithoutCarrier=yes: Configure bridge even if no member ports have carrierRequiredForOnline=carrier: Bridge needs at least one port with carrier to be considered online
IPv6 Global Unicast Addresses (GUA) will be configured dynamically via DHCPv6-PD in Part 5.
Interface verification
Restart systemd-networkd to apply configuration:
Verify interface status:
Check detailed interface information:
Verify IP addresses:
Check bridge status:
Verify routing tables:
IPv4 should have a default route via the WAN interface's DHCP gateway. IPv6 should have default routes via the WAN interface's RA-learned gateway (if available) and local routes for the ULA prefix.
Troubleshooting common issues
If bridge member ports do not attach to the bridge, verify the configuration file is being loaded:
Check for syntax errors in .network files then reload:
Manually bring up an interface:
Check dmesg for physical link detection issues (cable, NIC driver).
If WAN interface not receiving DHCP, verify DHCP client is running:
|
If DHCP fails, check ISP-side issues (modem reboot, provisioning, etc).
Manually trigger DHCP renewal:
If IPv6 is not configured on WAN, ensure IPv6 is enabled globally (covered in Part 7):
Should return 0. If 1, enable IPv6:
Verify RA reception:
# Install rdisc6 if not already installed
This sends Router Solicitations and displays received RAs. If no response, the ISP may not provide IPv6, or the modem/ONT is not forwarding RAs.
Per-interface security hardening
Per-interface security hardening is applied via sysctl parameters in Part 7. These settings include:
Next steps
With network interfaces configured and secured, the router has functional WAN/LAN connectivity but no service layer (DNS, DHCP, firewall). Part 3 covers DNS resolver deployment with Unbound, providing recursive DNS resolution and blocklist integration for the LAN.