dndx / phantun

Transforms UDP stream into (fake) TCP streams that can go through Layer 3 & Layer 4 (NAPT) firewalls/NATs.
Apache License 2.0
1.58k stars 128 forks source link

[Feature Request] make phantun tunnel transparent #112

Closed Popwax closed 1 year ago

Popwax commented 1 year ago

Thanks for creating this project, phantun works like a charm along with WireGuard, especially in place where WireGuard was blocked/filtered.

However, it certainly has some limitation. I think, by making phantun totally transparent, it could bring a lot of improvements.

Here is how it could be done.

  1. Assign no IP address to tun0 interface.
  2. Instead of listening on UDP socket, routing outgoing UDP packet directly to tun0 interface, and it will generate fake-TCP outgoing packet. Likewise, incoming fake-TCP packet will be routed to tun0 as well, and it will be translated back to incoming UDP packet.
  3. Actual routing could be handled with Linux policy based routing, for example:
    # ip route add 0.0.0.0/0 dev tun0 table phantun
    # ip rule add to REMOTE_IP ipproto udp dpost REMOTE_PORT table phantun # outgoing UDP packet
    # ip rule add fwmark FWMARK table phantun # WireGuard UDP packet can also be handled with fwmark
    # ip rule add from REMOTE_IP ipproto tcp sport REMOTE_PORT table phantun #incoming fake-TCP packet

Compare to current method, I think it will bring improvements over a number of places:

  1. Totally transparent. No change to UDP protocol is required (like changing destination ip to 127.0.0.1). phantun can even run on a router and handle UDP requests for all devices in the home network.
  2. Easier to configure. Only phantun config and associated ip rule routing rules ares required.
  3. There are no differences between phantun client and server, only single binary is enough. When both endpoints have public-facing TCP port to bind, both endpoints could initiate new fake-TCP connection.
  4. No NAT translation. Potentially better performance. For WireGuard, it also means consistent peer endpoints address, and possibly better roaming (depends on how ISP firewalls handle fake-TCP packet from the new roaming address).
  5. Multiple server ports are possible for single tunnel, even multiple server/client addresses. So it's possible to split UDP packet streams into multiple fakeTCP sessions and make phantun less noisy.
Popwax commented 1 year ago

I thought this through today and find this approach is actually quite complex. It requires rpfilter=0 and possibly another SNAT to redirect incoming fake-TCP packets. Maybe it just doesn't worth it.

For transparent support, UDP socket with TPROXY redirection is probably the best approach.