Let's talk about obfuscation again

StarBrilliant coder at poorlab.com
Fri Sep 7 10:49:38 CEST 2018

On Fri, Sep 7, 2018 at 1:20 AM Fredrik Strömberg <stromberg at mullvad.net> wrote:
> Using Pluggable Transports seem like a good solution. Simply divert
> WireGuard traffic to a local UDP port, which then sends it using a
> Pluggable Transport over the Internet to the other WireGuard peer.
> StarBrilliant: You indicated that some aspect of WireGuard ("solve the
> padding and timing problem so PT plugins can run on top of it")
> prevents Pluggable Transports from working. Please elaborate.

On Fri, Sep 7, 2018 at 2:11 AM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> This is generally what I'd recommend too, but I'm not sure I follow
> the logic of the padding and timing. Should not a proper pluggable
> transport be doing this on its own already? Adding random padding to
> all packets, and delaying statistically similar ones randomly as well?
> Especially for the padding aspect, there's little reason why a
> pluggable transport should not already be doing this.

Hello everyone,

Thank you for your attention. I will address the two questions above together.

We assume Pluggable Transport to be a universal plug-in. (I don't talk
of *a specific* Pluggable Transport program here, because as I already
knew, there aren't any PT that supports UDP yet. We will still need to
build a UDP-supported PT in the future.)

A Pluggable Transport can and should:
- Scramble the data so it looks like another protocol or random noise.
- Combine and split packets so 1 packet can be 2, 2 can be 1.
- Pad the data so the packet length is not identical to the original.
- Apply delay & jitter so packets does not follow a uniform temporal
pattern. (Sadly, experiments show reordering would terribly affect the
TCP performance in a VPN so we would not turn delay & jitter on by

But a Pluggable Transport CAN NOT:
- Identify whether the inner protocol is Wireguard or SSH or Tor.
- Have knowledge that the "Client Handshake" length=148, the "Server
Handshake" length=92, the "Keep Alive" length=32.
- Swallow any of the packet based on the inside of the packet, except
for traffic shaping & rate limiting.
- Pad the packet too long. (e.g. don't expect 32 -> 1472)
- Delay a packets for minutes long, it can only operate on milliseconds level.

We know even on an idle connection, the "Client Handshake" is sent
every X minutes, immediately followed by a "Server Handshake". And
"Keep Alive" is sent every Y minutes (configurable by the user, used
for NAT scenarios).

I hope three changes applied to Wireguard:
- For "Client Handshake", "Server Handshake" and "Keep Alive", since
they can be pad to any length without affecting compatibility, why not
pad them to any length below 1472?
- For data packets, leave them as is and let PT do the padding.
- The rekey and keep-alive are sent in random(X-D, X) time, and the
server expect a rekey in a window of range(0, X). D can be as long as
minutes or as long as 50% of X.
- Allow Wireguard to bind to only one or more specific local addresses
(e.g. only ::1). Therefore we do not need to use complicated firewall
setup to prevent WG from directly expose to the Internet.

Best regards.

More information about the WireGuard mailing list