This page documents the WireGuard proxy implementation (wgproxy), which provides WireGuard-as-a-proxy functionality with an embedded gVisor network stack. The implementation allows WireGuard to function as a transparent proxy within the larger Firestack system, supporting configuration updates, proxy chaining, health monitoring, and optional UDP GRO/GSO offloading.
For information about the overall proxy management system and proxy selection, see Proxy Architecture and Orchestration. For information about proxy health monitoring and automatic selection logic, see Auto Proxy and Health Monitoring.
The WireGuard proxy consists of three tightly integrated layers: the proxy interface (wgproxy), the network stack abstraction (wgtun), and the WireGuard protocol implementation (device.Device from wireguard-go). These components work together to provide a complete WireGuard-based proxy.
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L94-L102" min=94 max=102 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L104-L170" min=104 max=170 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L182-L186" min=182 max=186 file-path="intra/ipn/wgproxy.go">Hii</FileRef>
The wgproxy type implements the full Proxy interface while embedding both the network stack (wgtun) and WireGuard device:
| Type | Purpose | Key Fields |
|---|---|---|
wgproxy | Main proxy implementation | *wgtun, *device.Device, wgep <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L182-L186" min=182 max=186 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
wgtun | gVisor-based TUN abstraction | stack, ep, ingress, rt <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L104-L170" min=104 max=170 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
wgifopts | Parsed configuration | ifaddrs, peers, dns, eps, amnezia <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L94-L102" min=94 max=102 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
wgconn | Endpoint/bind interface | conn.Bind, RemoteAddr(), Pause(), Resume() <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L172-L178" min=172 max=178 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L94-L102" min=94 max=102 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L104-L170" min=104 max=170 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L172-L178" min=172 max=178 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L182-L186" min=182 max=186 file-path="intra/ipn/wgproxy.go">Hii</FileRef>
The WireGuard proxy accepts configuration in WireGuard UAPI format with extensions for Amnezia WireGuard and Cloudflare WARP. Configuration parsing is a two-pass process that separates interface configuration from peer configuration.
The parsing logic extracts interface-level settings (Address, DNS, MTU) and peer-level settings (PublicKey, AllowedIPs, Endpoint).
| Configuration Key | Target | Purpose |
|---|---|---|
address | Interface | Interface IP addresses <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L112-L112" min=112 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
dns | Interface | DNS server addresses <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L140-L140" min=140 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
mtu | Interface | Interface MTU <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L135-L136" min=135 max=136 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
jc, jmin, jmax | Amnezia | Junk packet parameters <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L40-L40" min=40 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef> |
s1, s2 | Amnezia | Init packet obfuscation <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L42-L42" min=42 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef> |
h1, h2, h3, h4 | Amnezia/WARP | Packet type header obfuscation <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L43-L43" min=43 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef> |
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L94-L102" min=94 max=102 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L37-L44" min=37 max=44 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef>
The wgtun component implements the tun.Device interface required by WireGuard-go while embedding a complete gVisor network stack. This dual-interface design allows the WireGuard device to read/write packets while the gVisor stack handles TCP/UDP/ICMP protocol processing.
wgtun implements DialContext, DialTCPAddrPort, and DialUDPAddrPort by translating standard Go net addresses to gVisor tcpip.FullAddress types.
| Method | Implementation |
|---|---|
DialContext | Orchestrates DNS lookup and protocol selection <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgnet.go#L83-L85" min=83 max=85 file-path="intra/ipn/wgnet.go">Hii</FileRef> |
LookupContextHost | Resolves hostnames using Firestack's internal DNS dialers <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgnet.go#L53-L77" min=53 max=77 file-path="intra/ipn/wgnet.go">Hii</FileRef> |
fullAddrFrom | Translates netip.AddrPort to tcpip.FullAddress <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgnet.go#L179-L199" min=179 max=199 file-path="intra/ipn/wgnet.go">Hii</FileRef> |
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgnet.go#L53-L212" min=53 max=212 file-path="intra/ipn/wgnet.go">Hii</FileRef>
The wgconn interface abstracts WireGuard's endpoint and bind mechanisms, providing implementations for standard and optimized UDP paths.
StdNetBind2 provides high-performance packet I/O using batching and offloading techniques.
| Feature | Implementation |
|---|---|
| Batching | Uses ReadBatch and WriteBatch for multiple datagrams per syscall <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/wgconn2.go#L83-L89" min=83 max=89 file-path="intra/ipn/wg/wgconn2.go">Hii</FileRef> |
| GSO Offload | Sets UDP_SEGMENT in control messages for transmit offload <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/gso.go#L64-L80" min=64 max=80 file-path="intra/ipn/wg/gso.go">Hii</FileRef> |
| GRO Offload | Parses UDP_GRO from control messages for receive offload <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/gso.go#L39-L60" min=39 max=60 file-path="intra/ipn/wg/gso.go">Hii</FileRef> |
| Detection | supportsUDPOffload checks kernel support via GetsockoptInt <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/gso.go#L83-L113" min=83 max=113 file-path="intra/ipn/wg/gso.go">Hii</FileRef> |
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/wgconn2.go#L39-L112" min=39 max=112 file-path="intra/ipn/wg/wgconn2.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/gso.go#L31-L138" min=31 max=138 file-path="intra/ipn/wg/gso.go">Hii</FileRef>
Peer endpoints are managed via MH (Multihost) and MHMap structures, which handle DNS resolution and address rotation for WireGuard peers.
<FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/multihost/multihost.go#L55-L63" min=55 max=63 file-path="intra/ipn/multihost/multihost.go">Hii</FileRef>.<FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/multihost/multihost.go#L169-L219" min=169 max=219 file-path="intra/ipn/multihost/multihost.go">Hii</FileRef>.<FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/multihost/map.go#L21-L27" min=21 max=27 file-path="intra/ipn/multihost/map.go">Hii</FileRef>.Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/multihost/multihost.go#L55-L219" min=55 max=219 file-path="intra/ipn/multihost/multihost.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/multihost/map.go#L21-L78" min=21 max=78 file-path="intra/ipn/multihost/map.go">Hii</FileRef>
Amnezia extensions provide packet obfuscation to evade deep packet inspection (DPI).
The Amnezia structure handles packet transformation for both sending and receiving:
<FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L146-L202" min=146 max=202 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef>.<FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L204-L236" min=204 max=236 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef>.Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/amnezia.go#L37-L236" min=37 max=236 file-path="intra/ipn/wg/amnezia.go">Hii</FileRef>
The wgtun structure tracks a variety of health metrics and timestamps to inform the proxy selection logic. Statistics are periodically read from the WireGuard device via UAPI.
| Field | Purpose |
|---|---|
status | Current state (TOK, TNT, etc.) <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L152-L152" min=152 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
latestGoodRx/Tx | Last successful packet flow <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L164-L165" min=164 max=165 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
errRx/Tx | Cumulative error counts <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L168-L169" min=168 max=169 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
latestRefresh | Last time configuration or DNS was refreshed <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L155-L155" min=155 file-path="intra/ipn/wgproxy.go">Hii</FileRef> |
The following diagram maps the logical flow of a network request through the WireGuard proxy code entities.
Sources: <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgproxy.go#L104-L186" min=104 max=186 file-path="intra/ipn/wgproxy.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wgnet.go#L209-L212" min=209 max=212 file-path="intra/ipn/wgnet.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/wgconn2.go#L121-L123" min=121 max=123 file-path="intra/ipn/wg/wgconn2.go">Hii</FileRef>, <FileRef file-url="https://github.com/celzero/firestack/blob/7132dd2b/intra/ipn/wg/gso.go#L64-L80" min=64 max=80 file-path="intra/ipn/wg/gso.go">Hii</FileRef>
Refresh this wiki