7.2 KiB
TCP/UDP Proxying Implementation Summary
Overview
This implementation adds transparent TCP and UDP connection proxying to newt's netstack2 package, inspired by tun2socks. Traffic entering through the WireGuard tunnel is terminated in netstack and automatically proxied to the actual target addresses.
Key Changes
1. New File: netstack2/handlers.go
Purpose: Contains TCP and UDP handler implementations that proxy connections.
Key Components:
-
TCPHandler: Manages TCP connection forwarding- Installs TCP forwarder on netstack
- Performs TCP three-way handshake with clients
- Dials actual target addresses
- Bidirectionally copies data with proper half-close handling
-
UDPHandler: Manages UDP packet forwarding- Installs UDP forwarder on netstack
- Creates UDP endpoints for clients
- Forwards packets to actual targets
- Handles session timeouts
Features:
- Configurable timeouts (5s TCP connect, 60s TCP half-close, 60s UDP session)
- TCP keepalive support (60s idle, 30s interval, 9 probes)
- Optimized buffer sizes (32KB for TCP, 64KB for UDP)
- Proper error handling and connection cleanup
2. Modified File: netstack2/tun.go
Changes:
- Added
tcpHandlerandudpHandlerfields tonetTunstruct - Added
NetTunOptionsstruct for configuration:type NetTunOptions struct { EnableTCPProxy bool EnableUDPProxy bool } - Added
CreateNetTUNWithOptions()function for explicit proxying control - Modified existing
CreateNetTUN()to callCreateNetTUNWithOptions()with proxying disabled (backward compatible) - Added
EnableTCPProxy()andEnableUDPProxy()methods on*Netfor runtime activation
3. Documentation: netstack2/README.md
Comprehensive documentation covering:
- Architecture overview
- Usage examples (3 different approaches)
- Configuration parameters
- Performance considerations
- Limitations and debugging tips
4. Example: examples/netstack-proxying/main.go
Runnable examples demonstrating:
- Creating netstack with proxying enabled
- Enabling proxying after creation
- Standard netstack usage (no proxying)
Usage Patterns
Pattern 1: Enable During Creation
tun, tnet, err := netstack2.CreateNetTUNWithOptions(
localAddresses, dnsServers, mtu,
netstack2.NetTunOptions{
EnableTCPProxy: true,
EnableUDPProxy: true,
},
)
Pattern 2: Enable After Creation
tun, tnet, err := netstack2.CreateNetTUN(localAddresses, dnsServers, mtu)
tnet.EnableTCPProxy()
tnet.EnableUDPProxy()
Pattern 3: No Proxying (Backward Compatible)
tun, tnet, err := netstack2.CreateNetTUN(localAddresses, dnsServers, mtu)
// Use standard tnet.DialTCP(), tnet.DialUDP() methods
How It Works
TCP Flow:
- Client sends TCP SYN to target address through WireGuard tunnel
- Packet arrives at netstack
- TCP forwarder intercepts and completes three-way handshake
- Handler dials actual target address
- Data copied bidirectionally until connection closes
- Proper TCP half-close and FIN handling
UDP Flow:
- Client sends UDP packet to target address through WireGuard tunnel
- Packet arrives at netstack
- UDP forwarder creates endpoint for client
- Handler creates UDP connection to actual target
- Packets forwarded bidirectionally
- Session closes after 60s timeout or explicit close
Key Differences from tun2socks
| Aspect | tun2socks | newt |
|---|---|---|
| Target | SOCKS proxy | Direct target addresses |
| Use Case | Route to proxy | Direct network access |
| Architecture | Proxy adapter | Direct dial |
| Complexity | Higher (SOCKS protocol) | Lower (direct TCP/UDP) |
Integration with WireGuard
The handlers integrate seamlessly with existing WireGuard code:
// In wgnetstack.go:
func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
// Create netstack with proxying
s.tun, s.tnet, err = netstack2.CreateNetTUNWithOptions(
[]netip.Addr{tunnelIP},
s.dns,
s.mtu,
netstack2.NetTunOptions{
EnableTCPProxy: true,
EnableUDPProxy: true,
},
)
// Rest of WireGuard setup...
}
Performance Characteristics
- Memory: ~64KB per active connection (buffer space)
- Goroutines: 2 per connection (bidirectional copying)
- Latency: Minimal overhead (single netstack hop + direct dial)
- Throughput: Limited by buffer size and network bandwidth
Testing
To test the implementation:
-
Build the example:
cd /home/owen/fossorial/newt go build -o /tmp/netstack-example examples/netstack-proxying/main.go -
Run the example:
/tmp/netstack-example -
Integration test with WireGuard:
- Enable proxying in wgnetstack
- Send TCP/UDP traffic through tunnel
- Verify connections reach actual targets
Error Handling
- TCP: Failed connections result in RST packets to client
- UDP: Failed sends are silently dropped (standard UDP behavior)
- Timeouts: Configurable per protocol
- Resources: Proper cleanup on connection close
Security Considerations
- No Filtering: All connections are proxied (no allow-list)
- Direct Access: Assumes network access to all targets
- Resource Limits: No per-connection rate limiting
- Logging: No built-in connection logging (can be added)
Future Enhancements
Potential improvements:
- Connection filtering/allow-listing
- Per-connection rate limiting
- Connection statistics and monitoring
- Dynamic timeout configuration
- Connection pooling
- Logging and metrics
- Connection replay prevention
Backward Compatibility
✅ Fully backward compatible: Existing code using CreateNetTUN() continues to work without any changes. Proxying is opt-in via CreateNetTUNWithOptions() or EnableTCPProxy()/EnableUDPProxy().
Files Modified/Created
Created:
netstack2/handlers.go(286 lines)netstack2/README.md(documentation)examples/netstack-proxying/main.go(example code)IMPLEMENTATION.md(this file)
Modified:
netstack2/tun.go(added 40 lines)- Added handler fields to
netTunstruct - Added
NetTunOptionstype - Added
CreateNetTUNWithOptions()function - Added
EnableTCPProxy()andEnableUDPProxy()methods - Modified
CreateNetTUN()to call new function with disabled options
- Added handler fields to
Build Verification
cd /home/owen/fossorial/newt
go build ./netstack2/
# Success - no compilation errors
Next Steps
To use this in newt:
- Test in isolation: Run the example program to verify basic functionality
- Integrate with WireGuard: Modify
wgnetstack.goto useCreateNetTUNWithOptions() - Add configuration: Make proxying configurable via newt's config file
- Add logging: Integrate with newt's logger for connection tracking
- Monitor performance: Add metrics for connection count, throughput, errors
- Add tests: Create unit and integration tests
References
- tun2socks: https://github.com/xjasonlyu/tun2socks
- Referenced files:
core/tcp.go,core/udp.go,tunnel/tcp.go,tunnel/udp.go
- Referenced files:
- gVisor netstack: https://gvisor.dev/docs/user_guide/networking/
- WireGuard: https://www.wireguard.com/