Files
alknet/docs/architecture/decisions/005-socks5-before-tun.md
glm-5.1 dad8224686 Add architecture specification for wraith SSH tunnel tool
Docs:
- README.md: index with doc table, ADR table, lifecycle definitions
- overview.md: purpose, exports, dependencies, constraints
- transport.md: Transport trait, TCP/TLS/iroh implementations, stream join
- client.md: SOCKS5 server, port forwarding, channel manager, reconnection
- server.md: auth, channel handling, stealth mode, outbound proxy
- tun-shim.md: separate privileged process, virtual DNS, --unshare mode
- napi-and-pubsub.md: NAPI wrapper, pubsub event target adapter

ADRs:
- 001: Pluggable transport via AsyncRead+AsyncWrite trait
- 002: TUN shim as separate process
- 003: iroh stream via tokio::io::join
- 004: SSH runs over transport, not alongside
- 005: SOCKS5 as primary interface, TUN as add-on
- 006(007): NAPI exposes single duplex stream

Open questions: 11 items covering TLS certs, iroh relay defaults,
Windows TUN, auth expansion, NAPI surface, TCP reconstruction
2026-06-01 15:01:45 +00:00

1.9 KiB

ADR-005: SOCKS5 as Primary Interface, TUN as Add-on

Status

Accepted

Context

A "VPN-like" tool needs to route traffic. There are three approaches:

  1. TUN only: Create a TUN interface, route all OS traffic through it. Full VPN experience but requires root.
  2. SOCKS5 only: Local SOCKS5 proxy. Applications configure proxy settings. No root needed but application support varies.
  3. SOCKS5 primary, TUN add-on: SOCKS5 is the core interface. TUN forwards to SOCKS5.

Decision

SOCKS5 is the primary interface. TUN is a separate process that forwards to SOCKS5 (Option 3).

SOCKS5 is the core because:

  • It requires no privileges
  • curl --socks5-hostname works everywhere
  • Browsers, most CLI tools, and many applications support SOCKS5
  • SOCKS5h prevents DNS leaks by resolving names server-side
  • It's the interface that the NAPI wrapper and pubsub adapter build on
  • TUN is only needed for "route all traffic" use cases, which are a subset of users

TUN forwards to SOCKS5 rather than directly to SSH because:

  • The SOCKS5 code already handles TCP connection establishment and bidirectional proxying
  • TUN's job is just IP packet → SOCKS5 connection, not IP packet → SSH channel
  • The wraith-tun binary stays minimal (~200-500 lines)
  • No root code in the core binary

Consequences

  • Positive: Core binary is root-free. TUN is optional and separate.
  • Positive: SOCKS5 is testable without TUN — just curl against it.
  • Positive: TUN implementation is simplified — it's a thin wrapper around tun2proxy's pattern pointed at localhost:1080.
  • Negative: TUN adds one network hop (TUN → localhost SOCKS5 → SSH). The latency impact is negligible (localhost).
  • Negative: SOCKS5 doesn't capture UDP (except DNS via SOCKS5h). TUN mode would handle non-DNS UDP via the SOCKS5 UDP association or drop it.

References