Transparent Proxy Matrix: Mullvad over obfs4 Tor Transport

Posted by AdTrue2526@reddit | linux | View on Reddit | 5 comments

Hey Everyone, I know the main forum is not for support, but this feels out of place in the beginner sections. I am stuck on a networking issue while setting up a transparent proxy for some offensive research. The goal is straightforward: force the Mullvad daemon to route WireGuard tunnels through Tor using obfs4 bridges.

### -- Section --

Instead, the daemon just hangs. Tor bootstraps fine over obfs4, but the VPN stalls in a Connecting state and WireGuard handshakes time out.

### -- Section --

**Architecture**

* OS: Ubuntu 24.04.3

* VPN: Custom compiled Mullvad Rust daemon

* Tor: Configured with obfs4 to obscure the transport from the ISP

* Proxy: iptables NAT REDIRECT grabbing daemon traffic and sending it to 127.0.0.1:9040 (Tor TransPort) and 5353 (Tor DNS)

### -- Section --

**Roadblocks Cleared**

I have spent a few hours modifying the Rust source to fix some glaring kernel space conflicts.

* API Rejections: The remote API drops requests from Tor exit nodes. This causes the daemon to panic and attempt wrapping WireGuard inside Shadowsocks inside Tor. That encapsulation breaks maximum transmission unit limits, especially with obfs4 padding. I patched the source to inject a custom fwmark at the mangle layer, isolating API requests from the proxy NAT.

* Policy Routing: The routing daemon was dropping bypassed payloads. I unified the connection tracking and routing marks so the kernel routing table and netfilter evaluate the same state machine.

* Systemd Variables: Systemd strips custom environment variables, leaving the daemon blind to the proxy ports and dropping loopback traffic. I removed the dynamic lookups and statically defined the translation ports in the LazyLock initializers.

I also killed all extraneous listening service to rule out local interference. The socket state is entirely clean.

### -- Section --

**Current State**

The proxy translation is active. Tor hits 100 percent bootstrap via obfs4. The hardware isolation for the API works.

But when the daemon attempts to negotiate the WireGuard stream, it hangs. The logs show constant WireGuard peer timeouts.

### -- Section --

I rely on Path MTU Discovery across the routing table, so segment sizing adapts to protocol overhead dynamically. Because the network should be shaping the MTU on the fly, I doubt packet fragmentation is the issue. Although I may be wrong here.

Could a protocol mismatch be happening silently? It makes sense that the API requests survive if they operate over a standard stream protocol, since tor handles that. But what exactly happens the moment the daemon attempts to establish the actual secure tunnel using a datagram protocol? Am I on the right track thinking the network filter is redirecting those handshakes to the local Tor socket, just for the onion proxy to silently drop them as unsupported payloads?

I usually double check things pretty thoroughly before asking for eyes, so I could use a sanity check from anyone who has built something similar.