gutd — WireGuard traffic obfuscator via TC/XDP eBPF (n o kernel patches)

sh0rch <[email protected]> Wed, 25 Feb 2026 18:59:53 +0000
Newsgroups com.zx2c4.lists.wireguard
Message-ID <GVXP251MB0790009AEBCBE7855DDCB5B28375A@GVXP251MB0790.EURP251.PROD.OUTLOOK.COM>
Hi all,=0A=
=0A=
I've been working on a WireGuard obfuscator and wanted to share it in case =
it's useful or someone wants to try it out and give feedback.=0A=
=0A=
**gutd**=A0obfuscates WireGuard UDP traffic using Linux TC/XDP eBPF program=
s - no kernel patches, no kernel modules, no DKMS. It attaches at the TC eg=
ress hook on a veth pair and the XDP ingress hook on the physical NIC, so p=
acket processing happens in the kernel datapath at near-native speed, but t=
he implementation lives entirely in userspace-loaded BPF programs.=0A=
=0A=
##How it works:=0A=
- Egress (TC): masks each WireGuard UDP payload with a ChaCha keystream bef=
ore it leaves the host=0A=
- Ingress (XDP): unmasks the packet before passing it up the stack WireGuar=
d sees nothing unusual=0A=
- The WireGuard process is completely unaware of gutd=0A=
=0A=
##Key properties:=0A=
- No kernel patches or modules - just `bpf()` syscall=0A=
- Port striping across multiple UDP ports per peer=0A=
- Probabilistic keepalive drop to suppress timing patterns=0A=
- Hot reload via SIGHUP, no tunnel restart=0A=
- Static musl binary available (single file, no dependencies)=0A=
- IPv4 and IPv6 outer transport=0A=
=0A=
Shared symmetric key=A0(not WireGuard keypairs) -`gutd genkey` generates a =
random 256-bit key.=0A=
=0A=
Repo: https://github.com/sh0rch/gutd=0A=
=0A=
Would appreciate any feedback - especially on the BPF approach, the wire fo=
rmat, or anything that seems wrong or could be done better.=0A=
=0A=
Thanks=