Hi all,
I’m chasing a throughput problem that I’ve now narrowed down quite far, but I’m stuck on the root cause. I’d appreciate fresh eyes before I do anything drastic.
The core observation
-
Plain routing Red ↔ Green runs at full line speed. The hardware, NICs and routing engine are clearly fine.
-
The moment a VPN server terminated on the IPFire itself sits in the path, throughput collapses to ~10–12 Mbit/s.
-
This happens with both WireGuard and OpenVPN (RoadWarrior), to the same degree.
-
Crucially: the same WireGuard tunnel terminated on a NAS behind the IPFire (IPFire only forwards the UDP port) runs at ~260 Mbit/s over the identical WAN connection, path and latency.
So the only variable that matters is where the tunnel is terminated: terminate it on the NAS → 260 Mbit; terminate it on the IPFire → 12 Mbit. Same box, same line, same client, same path.
Setup
-
IPFire Core Update 202 (so the Core 196 WireGuard improvements — per-device kernel thread, GSO backport — are already in place).
-
CPU: Intel Xeon Silver 4309Y (8C/16T).
/proc/cpuinfoflags includeaes vaes pclmulqdq avx512 sha_ni— full crypto acceleration. -
WAN (red0) on fiber. Client is remote with ~210 ms RTT.
-
Note on latency: the ~210 ms is identical for the fast NAS-terminated tunnel and the slow IPFire-terminated tunnel, so latency is not the differentiating factor (the NAS tunnel proves the path is fine at that latency).
Why hardware is ruled out
The same physical box forwards Red<->Green at line rate and the NAS tunnel passing through it hits 260 Mbit. If raw capacity (CPU, crypto, NIC, line) were the limit, those couldn’t run at full speed. During the slow VPN transfers the box shows essentially no CPU load (top ≈ 0.2 %, no openvpn/ksoftirqd process pegged). This looks like a software/termination-path limit, not a capacity limit.
What I have already tested and ruled out
-
IPS (Suricata): stopped completely → no change.
-
QoS / shaping:
tc qdisc showshows onlyfq_codel/pfifo_fast, nohtb/tbf, 0 drops. No traffic shaping configured. -
Firewall rate limits:
iptables-save | grep -i limit→ only LOG-rate limits, no rate limit on VPN traffic. -
Conntrack:
conntrack -C= ~2985 ofnf_conntrack_max262144 (~1 %). Not full. -
MTU / fragmentation:
ping -f -l 1400 8.8.8.8through the tunnel → 0 % loss.wg0MTU is 1420 on both the IPFire and the NAS; the WireGuard client config has no MTU override on either side. -
Kernel vs userspace WireGuard:
lsmod | grep wireguardshows the kernel module loaded; nowireguard-goprocess. Native kernel WG, same as the NAS. -
Socket buffers:
net.core.rmem_max/wmem_max= 4194304 (4 MB) → allows ~150 Mbit at 210 ms RTT, so buffers are not the cap. -
Parallel streams:
iperf3 -c <ipfire-wg-ip> -P 8 -t 20→[SUM] ~10.2 Mbit/stotal, i.e. the same as a single stream — throughput does not scale with parallel streams. -
VPN port: changed the WireGuard listen/endpoint port (10443 → another port) → no change.
-
Egress / routing:
tracert -d 8.8.8.8through the IPFire-terminated tunnel shows traffic leaving directly via the firewall’s own WAN IP (hop 2 = our public IP, redacted), straight to the ISP backbone — no second VPN hop, no detour. The decrypted traffic exits cleanly via Red0.
Why a reinstall is (probably) not the answer
A reinstall would be restored from backup, and the backup contains the current configuration — so if the cause is in the config, it would simply come back. More importantly, two independent VPN stacks (WireGuard and OpenVPN) are affected identically, which argues against a corrupted per-service config that a clean install would fix. That points at something systemic in the termination/egress path (a driver / NIC-offload behaviour on the decrypt-and-reinject path, or a kernel/sysctl/config aspect) — something a reinstall+restore would either preserve or reproduce.
My question
On capable hardware, what could cap locally terminated VPN throughput at ~10–12 Mbit/s while:
-
plain Red<->Green forwarding runs at full line speed,
-
a tunnel terminated on a NAS behind the same firewall runs at ~260 Mbit/s over the identical path/latency,
-
both WireGuard and OpenVPN are hit equally,
-
and the CPU stays near-idle?
Has anyone seen VPN-terminated throughput pinned like this independent of protocol, port, IPS, shaping and buffers? Where in the IPFire VPN-termination path would you look next — NIC offload on the decrypt path, IRQ/queue handling for tunnel traffic, or something in the server-side config?
Happy to provide any specific command output. Thanks!