Raspberry Pi as a router (yes, it works)

March 05, 2022 / 10 min read / - views​

Why run a Raspberry Pi as your router?

I’ve been messing with small routers for years, and the pattern is the same: consumer gear is decent until you turn on the features that actually make your internet feel fast. Things like SQM (Smart Queue Management) for bufferbloat, WireGuard, VLANs, decent logging, and proper DNS. That’s where many off‑the‑shelf routers fall over.

A Raspberry Pi (RPi 4 or 5) with OpenWrt gives you full Linux control, a modern firewall, and enough CPU to do the serious stuff. You don’t need to go full x86 unless you’re pushing multi‑gigabit or heavy IDS/IPS.

This post covers:

  • Hardware options (Pi 4 vs Pi 5, NICs, cooling, power)
  • Installing OpenWrt cleanly
  • Network setups that actually work (basic NAT, VLAN trunking, PPPoE)
  • Performance expectations: NAT, SQM/CAKE, WireGuard
  • Troubleshooting real‑world gotchas
  • A few network‑appliance ideas beyond “just a router”

If you’re comfortable with Linux and basic networking, you’ll be fine. If you enjoy VLAN diagrams more than sleep, you’ll be very fine.


TL;DR: What speeds can you expect?

  • RPi 4 (Cortex‑A72)

    • Plain NAT with flow offload: ~1 Gbps line‑rate is doable with a good USB 3.0 Gigabit NIC.
    • SQM/CAKE: typically 600–850 Mbps depending on ISP overhead (PPPoE hurts), IRQ tuning, and thermals.
    • WireGuard: hundreds of Mbps; plan for 300–800 Mbps depending on peer crypto, MTU, and cores available.
  • RPi 5 (Cortex‑A76)

    • Everything above, but with headroom. CAKE at close to gigabit is realistic. Add 2.5G USB NICs or a PCIe HAT if you’re feeling spicy, but remember PCIe is one lane (PCIe 2.0).

If you need stable 2.5 Gbps+ with SQM, skip the Pi and go x86/Intel N100 or ARM boards built for routing.


Hardware I actually recommend

Choose your Pi

  • Pi 4B (2–8 GB): cheap and proven. Great for up to 1 Gbps with SQM and WireGuard for most home use.
  • Pi 5 (4/8 GB): faster CPU, active cooler support, and a PCIe 2.0 x1 connector via the M.2 HAT+. Feels snappier for VPN + CAKE + logging.

Memory: 2 GB is fine for router‑only. If you’re adding containers or fancy monitoring, 4 GB+ is convenient.

Network ports

You need two NICs for a router: one for WAN, one for LAN (or a VLAN trunk).

  • Onboard Gigabit = one port.
  • Add USB 3.0 to Gigabit for the second: Realtek RTL8152/RTL8153/RTL8156B or ASIX AX88179/AX88179A perform well.
  • On Pi 5 you can also add a PCIe HAT with dual 2.5GbE or expose PCIe to an M.2 card. It’s fun, not mandatory.

Power and cooling

  • Use a good PSU (Pi 4: 5V/3A, Pi 5: official 5V/5A USB‑C). Brown‑outs look like random link drops.
  • Cool it. SQM + VPN will keep cores busy. The Pi 5’s official active cooler is worth it; Pi 4 benefits from a fan case.

Wi‑Fi strategy

The Pi’s onboard Broadcom Wi‑Fi is fine for light AP duty, but driver support and features are limited. I strongly prefer a separate AP (UniFi, Omada, OpenWrt AP, etc.) wired to the Pi.


Install OpenWrt on Raspberry Pi

You’ve got two main tracks:

  • Stable release (recommended) for both Pi 4 and Pi 5. Grab the correct image for your board.
  • Snapshot only if you need bleeding‑edge features. It does not include LuCI by default; you’ll opkg install luci later.

1) Flash the image

  1. Download the Raspberry Pi image for your model.
  2. Flash it to a microSD using Raspberry Pi Imager or balenaEtcher.
  3. Boot the Pi with a monitor and keyboard the first time if you like, but I usually just leave it headless on a test subnet.

2) First login

  • Default IP is 192.168.1.1 on the LAN bridge. SSH to root@192.168.1.1 with no password, then set one immediately:
passwd
  • If you flashed a snapshot build, install LuCI:
opkg update
opkg install luci
/etc/init.d/uhttpd enable
/etc/init.d/uhttpd start

Network setups that actually work

A) Simple NAT router (onboard LAN, USB NIC as WAN)

Assume the onboard NIC is eth0 and your USB NIC appears as eth1.

# Create a LAN bridge on eth0
uci -q delete network.lan
uci set network.lan="interface"
uci set network.lan.proto="static"
uci set network.lan.device="eth0"
uci set network.lan.ipaddr="192.168.1.1"
uci set network.lan.netmask="255.255.255.0"
 
# WAN via DHCP on the USB NIC
uci -q delete network.wan
uci set network.wan="interface"
uci set network.wan.proto="dhcp"
uci set network.wan.device="eth1"
 
# Enable NAT + basic firewall defaults
/etc/init.d/network restart

If your WAN is PPPoE:

uci set network.wan.proto='pppoe'
uci set network.wan.username='YOUR_ISP_USER'
uci set network.wan.password='YOUR_ISP_PASSWORD'
uci commit network
/etc/init.d/network restart

B) VLAN trunk to a managed switch (single cable LAN)

This is my favourite home layout: one cable from the Pi to a small managed switch, with VLANs for LAN, Guest, IoT.

# Create a bridge and define VLANs 10 (LAN) and 20 (GUEST) on eth0
uci set network.br0='device'
uci set network.br0.type='bridge'
uci add_list network.br0.ports='eth0'
 
uci add network bridge-vlan
uci set network.@bridge-vlan[-1].device='br0'
uci set network.@bridge-vlan[-1].vlan='10'
uci add_list network.@bridge-vlan[-1].ports='eth0:t'
 
uci add network bridge-vlan
uci set network.@bridge-vlan[-1].device='br0'
uci set network.@bridge-vlan[-1].vlan='20'
uci add_list network.@bridge-vlan[-1].ports='eth0:t'
 
# Bind interfaces to the VLAN subinterfaces created by DSA
uci set network.lan='interface'
uci set network.lan.device='br0.10'
uci set network.lan.proto='static'
uci set network.lan.ipaddr='192.168.10.1'
uci set network.lan.netmask='255.255.255.0'
 
uci set network.guest='interface'
uci set network.guest.device='br0.20'
uci set network.guest.proto='static'
uci set network.guest.ipaddr='192.168.20.1'
uci set network.guest.netmask='255.255.255.0'
 
uci commit network
/etc/init.d/network restart

Then in Firewall (LuCI) create a guest zone, allow guest → wan, block guest → lan, and add a simple DHCP + DNS rule. If you run a separate AP, tag its uplink port with VLANs 10/20 and map SSIDs to those VLANs.

C) WAN on USB, LAN as trunk

If you only have the one onboard NIC, make that the trunk to your switch. Plug the ISP modem into the USB NIC. Same idea as A + B combined.


Performance tuning that matters

  • Packet Steering
uci set network.globals=globals
uci set network.globals.packet_steering='1'
uci commit network
/etc/init.d/network restart
  • irqbalance spreads interrupts across cores:
opkg update && opkg install irqbalance
/etc/init.d/irqbalance enable
/etc/init.d/irqbalance start
  • Flow offloading speeds up plain NAT, but don’t combine it with SQM:
uci set firewall.@defaults[0].flow_offloading='1'
uci commit firewall
/etc/init.d/firewall restart
  • USB NIC drivers: install the proper kmods for the chipset you actually have, e.g. kmod-usb-net-rtl8152 (covers RTL8152/53/56B) or kmod-usb-net-asix-ax88179 for AX88179/178A.
  • Thermals: keep the SoC under control. If you see throttling, your SQM/VPN numbers will sag.

SQM/CAKE: beating bufferbloat

Install packages:

opkg update
opkg install sqm-scripts luci-app-sqm

Find your WAN device name:

# Will print something like eth1 or pppoe-wan
echo $(uci -q get network.wan.device || echo eth1)

Configure CAKE with conservative starting rates (use ~90% of your clean speed test under load):

DEV=$(uci -q get network.wan.device || echo eth1)
uci set sqm.wan='queue'
uci set sqm.wan.interface="$DEV"
uci set sqm.wan.qdisc='cake'
uci set sqm.wan.script='layer_cake.qos'
uci set sqm.wan.download='900000'   # in kbps; adjust to your line
uci set sqm.wan.upload='900000'
uci set sqm.wan.debug_logging='0'
uci set sqm.wan.enabled='1'
uci commit sqm
/etc/init.d/sqm enable
/etc/init.d/sqm start

Validate with waveform bufferbloat test and adjust rates until latency under load stays flat.

Note: Disable flow offloading if SQM is enabled. They’re different fast‑paths and don’t play nicely.


WireGuard on the Pi

Packages:

opkg update
opkg install wireguard-tools kmod-wireguard luci-app-wireguard

Sample UCI (site‑to‑site or remote‑access):

# Interface
uci set network.wg0='interface'
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key='REPLACE_WITH_PRIVATE_KEY'
uci set network.wg0.listen_port='51820'
uci add_list network.wg0.addresses='10.10.0.1/24'
 
# Peer
uci add network.wg0='wireguard_wg0'
uci set network.@wireguard_wg0[-1].public_key='PEER_PUBLIC_KEY'
uci set network.@wireguard_wg0[-1].allowed_ips='10.10.0.2/32'
uci set network.@wireguard_wg0[-1].endpoint_host='peer.example.com'
uci set network.@wireguard_wg0[-1].endpoint_port='51820'
uci commit network
/etc/init.d/network restart
 
# Firewall: either add wg0 to LAN zone or create a dedicated VPN zone

Tuning tips:

  • Keep MTU sane (1420–1424 when traversing typical ISPs/NAT).
  • Use multi‑core by letting the kernel schedule WG crypto across cores; avoid pinning everything to one CPU.
  • Avoid double encryption on the same box if you can help it.

Wi‑Fi: do yourself a favour

You can enable the onboard Wi‑Fi in AP mode, but a dedicated AP is better:

  • Better radios and DFS handling
  • Proper roaming with 802.11k/v/r
  • Cleaner channel planning, especially if the Pi’s USB 3.0 bus is busy

If you must use onboard Wi‑Fi, prefer 5 GHz and keep USB 3.0 cables and SSDs away from the antenna area. It’s a real interference problem on 2.4 GHz.


Troubleshooting playbook

  • USB NIC is slow: make sure it negotiated USB 3.0, not USB 2.0. Try a different port/cable, install the specific kmod for the chipset, and check dmesg.
  • WAN is eth2 or enx…: list devices with ip link and update network.wan.device accordingly.
  • PPPoE is capping SQM: PPPoE adds overhead. Reduce CAKE rates slightly and set the correct overhead in LuCI (or try cake nat dual-srchost presets).
  • Random drops under load: power supply. Use the official PSU and avoid sketchy USB SSDs without a powered hub.
  • Thermal throttling: active cooling, done.
  • LuCI missing on snapshot: install luci after bringing the box online via SSH.

Network‑appliance ideas worth adding

  • Ad blocking DNS: run AdGuard Home or Pi‑hole on a separate Pi, or use OpenWrt’s adblock/banIP to keep it lean.
  • Unbound with DNSSEC: lightweight recursive resolver, pairs well with DoT/DoH on clients.
  • WireGuard hub: road‑warrior profile, site‑to‑site for a lab/flat.
  • VLAN‑first home: separate IoT, Guest, Work. Map SSIDs to VLANs on the AP and trunk back to the Pi.

When not to use a Pi as your main router

  • You pay for >1 Gbps symmetric and insist on SQM at line‑rate.
  • You need IDS/IPS with Suricata or deep packet inspection.
  • You want multiple 2.5/10G copper ports built‑in.

In those cases: x86 mini‑PC with Intel i226‑V NICs, or a dedicated ARM router board.


The big picture

A Raspberry Pi makes a surprisingly solid router when you lean on OpenWrt’s modern stack. The Pi 4 handles 1 Gbps with clever tuning; the Pi 5 adds breathing room and fun PCIe toys. Keep the build simple: good NICs, clean VLAN design, SQM if your bufferbloat tests look ugly, and WireGuard if you care about privacy. It’s a great way to actually understand your home network instead of praying to a vendor’s dark‑themed web UI.

If you try this, start with a basic NAT build and add features in stages. Measure as you go. It’s not flashy, but it works — reliably.


Quick package list I usually install

# Base
opkg update
opkg install luci htop irqbalance ca-bundle ca-certificates
 
# SQM and diagnostics
opkg install sqm-scripts luci-app-sqm tc-tiny iperf3
 
# USB NIC drivers (pick your chipset)
opkg install kmod-usb-net-rtl8152 kmod-usb-net-asix-ax88179
 
# VPN
opkg install wireguard-tools kmod-wireguard luci-app-wireguard
 
# DNS / extras
opkg install unbound-daemon luci-app-unbound mwan3 luci-app-mwan3