WireGuard VPN Tunnels
Create encrypted Layer 3 VPN tunnels between any two machines — no root, no kernel modules, no port forwarding. Access entire remote LANs through a single command.
How It Works
NFLTR's WireGuard integration creates a userspace VPN tunnel between two machines using the nfltr server as an encrypted relay. The server never sees your traffic — it forwards opaque WireGuard packets (Curve25519 + ChaCha20-Poly1305).
Machine A
nfltr wg serve
Advertises LAN, gets CGNAT IP100.64.0.2
WireGuard packets
over gRPC relay
Machine B
nfltr wg socks5
SOCKS5 proxy on :1080
routes through tunnel
Key exchange
Machine A sends its Curve25519 public key to the server via gRPC metadata. The server allocates a CGNAT IP and responds with the server's public key.
Tunnel creation
Both sides create userspace WireGuard devices backed by gvisor netstack — no root or kernel module needed.
Encrypted relay
WireGuard UDP packets are relayed through the existing gRPC stream. The server sees only opaque encrypted bytes.
LAN forwarding
The agent's forwarder accepts connections from the tunnel and dials real LAN hosts, optionally restricted to specific subnets.
WireGuard traffic is encrypted with ChaCha20-Poly1305. The nfltr server relays opaque ciphertext — it never holds session keys and cannot decrypt your traffic. This is E2EE by default, no --e2ee flag needed.
Quick Start
1. Start the WireGuard agent (remote machine)
On the machine whose LAN you want to reach:
nfltr wg serve --name home-server
Output:
nfltr v1.0.140 starting WireGuard agent
agent-id: alice.home-server
server: grpc.nfltr.xyz:443 (tls=true)
allowed: all (default route)
Connected — WireGuard agent active
The agent-id line shows the scoped name (API key prefix + your --name). Use this name from the other machine.
2. Connect from another machine
Option A: SOCKS5 proxy (recommended)
Works everywhere — containers, restricted systems, no root required:
# Start the SOCKS5 proxy
nfltr wg socks5 alice.home-server --listen :1080
# Access services on the remote LAN
curl --proxy socks5://localhost:1080 http://192.168.1.10:8080
curl --proxy socks5://localhost:1080 http://192.168.1.10:3000
Option B: Full tunnel
Creates a virtual network interface — remote services are directly routable:
nfltr wg connect alice.home-server
# Services are now directly accessible
ssh [email protected]
curl http://192.168.1.10:3000
Real-World Scenarios
🏠 Access Home Lab
Reach your home network from anywhere — NAS, Raspberry Pi, smart home dashboard.
# Home machine
nfltr wg serve --name homelab
# Laptop (coffee shop, office)
nfltr wg socks5 alice.homelab --listen :1080
curl --proxy socks5://localhost:1080 \
http://192.168.1.50:8123
🏢 Remote Office Access
Connect to office resources without a corporate VPN client or IT ticket.
# Office machine (behind firewall)
nfltr wg serve --name office \
--allowed-ips 10.0.0.0/24
# Remote worker
nfltr wg socks5 alice.office --listen :1080
# Access internal wiki, Jira, etc.
🗄️ Database Access
Reach any database on a remote network — PostgreSQL, MySQL, Redis, MongoDB.
# Server with database access
nfltr wg serve --name db-net \
--allowed-ips 10.0.1.0/24
# Developer laptop
nfltr wg socks5 alice.db-net --listen :1080
# Then use pgAdmin, DBeaver, etc.
# with SOCKS5 proxy configured
🔧 Multi-Service Debugging
Access multiple microservices on a remote dev/staging environment through a single tunnel.
# Staging server
nfltr wg serve --name staging
# Developer
nfltr wg socks5 alice.staging --listen :1080
# Access frontend :3000, API :8080,
# Redis :6379 — all through one proxy
SSH Through the Tunnel
Route SSH connections through a WireGuard SOCKS5 proxy using ProxyCommand:
# One-off SSH connection
ssh -o ProxyCommand='nc -x localhost:1080 %h %p' [email protected]
# Add to ~/.ssh/config for convenience
Host home-*
ProxyCommand nc -x localhost:1080 %h %p
User admin
# Now just:
ssh home-192.168.1.10
ssh home-192.168.1.20
SSH through a WireGuard tunnel is doubly encrypted — SSH's own encryption runs inside the WireGuard tunnel. This is fine for security; the overhead is negligible.
Browser Configuration
Configure your browser to use the SOCKS5 proxy for full web access to remote LANs:
Firefox
Settings → Network Settings → Manual proxy configuration:
- SOCKS Host:
localhost - Port:
1080 - Select SOCKS v5
- Check Proxy DNS when using SOCKS v5 (for internal hostnames)
Chrome / Chromium
# Launch with proxy flag
google-chrome --proxy-server="socks5://localhost:1080"
# Or use a proxy extension like SwitchyOmega
macOS system proxy
# Enable SOCKS proxy system-wide
networksetup -setsocksfirewallproxy "Wi-Fi" localhost 1080
# Disable when done
networksetup -setsocksfirewallproxystate "Wi-Fi" off
Restricting Access
By default, wg serve forwards to all LAN destinations. Restrict to specific subnets with --allowed-ips:
# Only allow access to the 192.168.1.0/24 subnet
nfltr wg serve --name home --allowed-ips 192.168.1.0/24
# Multiple subnets
nfltr wg serve --name office --allowed-ips 10.0.0.0/24,10.0.1.0/24
# Single host only
nfltr wg serve --name db-only --allowed-ips 10.0.1.50/32
Without --allowed-ips, the agent forwards to any IP reachable from the machine. In shared/production environments, always specify the subnets you intend to expose.
Persistent Keys
By default, WireGuard keys are ephemeral — generated fresh on each wg serve. For a stable identity across restarts, generate and save a key pair:
# Generate a key pair
nfltr wg keygen
# Private Key: yAnlP3Eqj1...==
# Public Key: xBzR5K7aw2...==
# Save the private key
nfltr wg keygen | head -1 | awk '{print $3}' > ~/.nfltr-wg-key
# Use it
nfltr wg serve --name home --private-key "$(cat ~/.nfltr-wg-key)"
The client side can also use persistent keys:
nfltr wg socks5 alice.home --private-key "$(cat ~/.nfltr-wg-key-client)"
Self-Hosted Server
WireGuard tunnels work with self-hosted nfltr servers — no nfltr.xyz account needed:
# Agent side (--tls=false for local/non-TLS server)
nfltr wg serve --name home \
--server my-server.local:9090 \
--tls=false
# Client side
nfltr wg socks5 alice.home --listen :1080 \
--server my-server.local:9090 \
--tls=false
Command Reference
nfltr wg serve
Run as a WireGuard agent — advertise this machine's LAN to the tunnel.
| Flag | Default | Description |
|---|---|---|
| --name | hostname | Agent identity name |
| --api-key | — | API key for authentication |
| --server | grpc.nfltr.xyz:443 | Server address |
| --tls | true | Enable TLS for server connection |
| --private-key | (ephemeral) | WireGuard private key (base64) |
| --allowed-ips | all | LAN CIDRs to forward (e.g. 192.168.1.0/24) |
| --labels | — | Fleet labels (key=value,...) |
| --duration | 0 | Max runtime in seconds (0 = unlimited) |
| --verbose | false | Verbose WireGuard logging |
nfltr wg socks5
Start a local SOCKS5 proxy that routes traffic through the WireGuard tunnel.
| Flag | Default | Description |
|---|---|---|
| --listen | :1080 | Local SOCKS5 listen address |
| --api-key | (config) | API key for authentication |
| --server | nfltr.xyz:443 | Server address |
| --tls | true | Enable TLS |
| --private-key | (ephemeral) | WireGuard private key (base64) |
nfltr wg connect
Create a full WireGuard tunnel with a virtual network interface (userspace TUN).
| Flag | Default | Description |
|---|---|---|
| --api-key | (config) | API key for authentication |
| --server | nfltr.xyz:443 | Server address |
| --tls | true | Enable TLS |
| --private-key | (ephemeral) | WireGuard private key (base64) |
| --allowed-ips | 0.0.0.0/0, ::/0 | CIDRs to route through tunnel |
| --dns | — | DNS server through the tunnel |
nfltr wg keygen
Generate a new Curve25519 key pair for WireGuard.
nfltr wg keygen
# Private Key: yAnlP3Eqj1...==
# Public Key: xBzR5K7aw2...==
When to Use WireGuard vs Other Tunnels
| Scenario | Best Command | Why |
|---|---|---|
| Expose a single web app | nfltr http 8080 | Simpler — one port, gets share URL |
| Connect to a single remote port | nfltr tcp + tcp-connect | Lighter — no VPN overhead |
| Access multiple services on a remote LAN | nfltr wg serve + wg socks5 | One tunnel, full LAN access |
| Route all traffic through a remote network | nfltr wg serve + wg connect | Creates a virtual interface, all traffic routed |
| Transfer files between machines | nfltr p2p send / recv | Direct P2P — faster, E2EE |
Rule of thumb: Use nfltr tcp for a single port. Use nfltr wg when you need to reach multiple services on a remote LAN through one encrypted tunnel.
Troubleshooting
Connection times out
- Verify the agent name is correct — use the scoped name shown in the agent output (e.g.
alice.home-server, not justhome-server). - Both machines must use valid API keys. The
wg serveside and thewg socks5side can use different API keys. - Add
--verbosetowg serveto see WireGuard handshake details.
SOCKS5 proxy connection refused
- Check the proxy is running:
lsof -i :1080 - Try a different port:
--listen :9050
Can't reach specific hosts
- The agent must be able to reach the host directly (i.e. it's on the same network or route exists).
- If
--allowed-ipsis set on the agent, the target host must be within the allowed CIDRs.
High latency
WireGuard adds minimal overhead (~2ms). If latency is high, it's likely the underlying network path between your machine and the nfltr server, or between the server and the agent. Try a server closer to both machines if self-hosting.
Next Steps
- E2EE Whitepaper — deep dive into WireGuard's crypto and the relay architecture
- DevOps & Remote Access — SSH, log streaming, and database tunnels
- TCP/SSH Tunneling — single-port tunnels as an alternative to WireGuard
- CLI Reference — full flag reference for all commands