* gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
@ 2026-02-25 18:59 sh0rch
2026-03-23 17:43 ` Jason A. Donenfeld
2026-03-24 10:42 ` Toke Høiland-Jørgensen
0 siblings, 2 replies; 5+ messages in thread
From: sh0rch @ 2026-02-25 18:59 UTC (permalink / raw)
To: wireguard@lists.zx2c4.com
Hi all,
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.
**gutd** obfuscates WireGuard UDP traffic using Linux TC/XDP eBPF programs - no kernel patches, no kernel modules, no DKMS. It attaches at the TC egress hook on a veth pair and the XDP ingress hook on the physical NIC, so packet processing happens in the kernel datapath at near-native speed, but the implementation lives entirely in userspace-loaded BPF programs.
##How it works:
- Egress (TC): masks each WireGuard UDP payload with a ChaCha keystream before it leaves the host
- Ingress (XDP): unmasks the packet before passing it up the stack WireGuard sees nothing unusual
- The WireGuard process is completely unaware of gutd
##Key properties:
- No kernel patches or modules - just `bpf()` syscall
- Port striping across multiple UDP ports per peer
- Probabilistic keepalive drop to suppress timing patterns
- Hot reload via SIGHUP, no tunnel restart
- Static musl binary available (single file, no dependencies)
- IPv4 and IPv6 outer transport
Shared symmetric key (not WireGuard keypairs) -`gutd genkey` generates a random 256-bit key.
Repo: https://github.com/sh0rch/gutd
Would appreciate any feedback - especially on the BPF approach, the wire format, or anything that seems wrong or could be done better.
Thanks
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
2026-02-25 18:59 gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) sh0rch
@ 2026-03-23 17:43 ` Jason A. Donenfeld
2026-03-23 22:41 ` sh0rch
2026-03-24 10:42 ` Toke Høiland-Jørgensen
1 sibling, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2026-03-23 17:43 UTC (permalink / raw)
To: sh0rch; +Cc: wireguard@lists.zx2c4.com
Hi sh0rch,
This is an awesome project! It seems like doing this with eBPF and
TC/XDP is exactly the right way to do this, and lets you just drop it
in on top of an existing configuration. I really like this
architecture.
I'll try to find some time to look at the internals in proper detail.
But I think this is basically the right direction. Thank you for
implementing it!
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
2026-03-23 17:43 ` Jason A. Donenfeld
@ 2026-03-23 22:41 ` sh0rch
0 siblings, 0 replies; 5+ messages in thread
From: sh0rch @ 2026-03-23 22:41 UTC (permalink / raw)
To: Jason A. Donenfeld, sh0rch; +Cc: wireguard@lists.zx2c4.com
Hi Jason,
Thanks a lot for the kind words, really means a lot.
I’m very happy the approach makes sense from your perspective. The whole idea was to keep it simple to deploy on top of existing WireGuard setups, without touching the kernel, while still getting the benefits of eBPF.
And also huge thanks to you for WireGuard itself. It’s honestly an amazing protocol: simple, secure, fast, and so cleanly designed that sometimes it feels like even the whole world isn’t enough for it :)
If you do find time to investigate the internals, I’d really appreciate any thoughts or feedback you might have.
Thanks again!
With best wishes,
Danila Makeev
-----Original Message-----
From: Jason A. Donenfeld <Jason@zx2c4.com>
Sent: 23 March 2026 20:44
To: sh0rch <sh0rch@iwl.dev>
Cc: wireguard@lists.zx2c4.com
Subject: Re: gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
Hi sh0rch,
This is an awesome project! It seems like doing this with eBPF and TC/XDP is exactly the right way to do this, and lets you just drop it in on top of an existing configuration. I really like this architecture.
I'll try to find some time to look at the internals in proper detail.
But I think this is basically the right direction. Thank you for implementing it!
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
2026-02-25 18:59 gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) sh0rch
2026-03-23 17:43 ` Jason A. Donenfeld
@ 2026-03-24 10:42 ` Toke Høiland-Jørgensen
[not found] ` <GVXP251MB07901AF0DC973F21B13077F88349A@GVXP251MB0790.EURP251.PROD.OUTLOOK.COM>
1 sibling, 1 reply; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2026-03-24 10:42 UTC (permalink / raw)
To: sh0rch, wireguard@lists.zx2c4.com
> Would appreciate any feedback - especially on the BPF approach,
Cool project! A couple of comments on the BPF side:
- It looks like you're using libbpf_rs to load the BPF programs. Have
you considered using the (pure rust) Aya library instead
(https://github.com/aya-rs/aya)? If so, what was the reason for
choosing the libbpf wrapper instead?
- From a quick look at the architecture doc, I don't understand why you
need the veth pair? You're just rewriting packet contents, this could
just as well be done in the TC hook (egress and ingress) of the
physical NIC, and from the wireguard PoV it would just look like wg
itself is speaking directly to the other tunnel peer?
-Toke
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches)
[not found] ` <GVXP251MB07901AF0DC973F21B13077F88349A@GVXP251MB0790.EURP251.PROD.OUTLOOK.COM>
@ 2026-03-26 16:30 ` Toke Høiland-Jørgensen
0 siblings, 0 replies; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2026-03-26 16:30 UTC (permalink / raw)
To: sh0rch, wireguard@lists.zx2c4.com
sh0rch <sh0rch@iwl.dev> writes:
> Hi Toke,
>
> Thanks a lot for taking a look, really appreciate it!
>
> I actually started with Aya, but ended up losing some hair fighting
> the verifier :) libbpf_rs just worked for me in the end.
Yeah, writing the BPF code in Rust is hard, still, but you could still
use Aya to load, and avoid the extra dependency on libbpf? Not sure how
much of a difference that makes in practice (I just noted you were
chasing small binaries, so maybe that would help?)
> About the veth. I’m trying to keep things compatible with stock
> WireGuard and also need proper routing through a relay/gateway. Inside
> my perimeter I can use plain WG, but to get traffic out I rely on a
> gateway, so I need packets to go through the normal networking stack.
> If everything happens in eBPF, it won’t even reach netfilter. That’s
> why I went with veth, also gives a bit more flexibility than tun/tap.
Hmm, not sure I undestrand what you mean by "rely on a gateway"? What
breaks if it's run only on TC, exactly?
In any case, if you need the extra step you could still have the BPF
programs run on the other side of the veth device, but still just as a
pair of TC ingress/egress programs? That would still simplify the BPF
side of things, and make the usage of veth devices optional.
> Ideally this would all live in AF_XDP + userspace, but that’s hard to
> rely on in VPS environments where AF_XDP support is still limited.
Don't think you'd get very good performance doing that, AF_XDP has a
pretty severe performance penalty if you want to re-inject packets into
the kernel. So unless you're actually creating an obfuscating middlebox,
going with BPF like you did here seems like a better solution :)
-Toke
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-26 16:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-25 18:59 gutd — WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) sh0rch
2026-03-23 17:43 ` Jason A. Donenfeld
2026-03-23 22:41 ` sh0rch
2026-03-24 10:42 ` Toke Høiland-Jørgensen
[not found] ` <GVXP251MB07901AF0DC973F21B13077F88349A@GVXP251MB0790.EURP251.PROD.OUTLOOK.COM>
2026-03-26 16:30 ` Toke Høiland-Jørgensen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox