mirror of
https://github.com/fosrl/olm.git
synced 2026-03-01 08:16:56 +00:00
loser to workinr?
This commit is contained in:
186
DNS_PROXY_README.md
Normal file
186
DNS_PROXY_README.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Virtual DNS Proxy Implementation
|
||||
|
||||
## Overview
|
||||
|
||||
This implementation adds a high-performance virtual DNS proxy that intercepts DNS queries destined for `10.30.30.30:53` before they reach the WireGuard tunnel. The proxy processes DNS queries using a gvisor netstack and forwards them to upstream DNS servers, bypassing the VPN tunnel entirely.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Components
|
||||
|
||||
1. **FilteredDevice** (`olm/device_filter.go`)
|
||||
- Wraps the TUN device with packet filtering capabilities
|
||||
- Provides fast packet inspection without deep packet processing
|
||||
- Supports multiple filtering rules that can be added/removed dynamically
|
||||
- Optimized for performance - only extracts destination IP on fast path
|
||||
|
||||
2. **DNSProxy** (`olm/dns_proxy.go`)
|
||||
- Uses gvisor netstack to handle DNS protocol processing
|
||||
- Listens on `10.30.30.30:53` within its own network stack
|
||||
- Forwards queries to Google DNS (8.8.8.8, 8.8.4.4)
|
||||
- Writes responses directly back to the TUN device, bypassing WireGuard
|
||||
|
||||
### Packet Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Application │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ DNS Query to 10.30.30.30:53
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TUN Interface │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ FilteredDevice (Read) │
|
||||
│ - Fast IP extraction │
|
||||
│ - Rule matching (10.30.30.30) │
|
||||
└──────────────┬──────────────────────────────────────────────┘
|
||||
│
|
||||
┌──────────┴──────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────┐ ┌─────────────────────────┐
|
||||
│DNS Proxy│ │ WireGuard Device │
|
||||
│Netstack │ │ (other traffic) │
|
||||
└────┬────┘ └─────────────────────────┘
|
||||
│
|
||||
│ Forward to 8.8.8.8
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ Internet │
|
||||
│ (Direct) │
|
||||
└──────┬──────┘
|
||||
│ DNS Response
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ DNSProxy writes directly to TUN │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Application │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Fast Path Optimization
|
||||
|
||||
1. **Minimal Packet Inspection**
|
||||
- Only extracts destination IP (bytes 16-19 for IPv4, 24-39 for IPv6)
|
||||
- No deep packet inspection unless packet matches a rule
|
||||
- Zero-copy operations where possible
|
||||
|
||||
2. **Rule Matching**
|
||||
- Simple IP comparison (not prefix matching for rules)
|
||||
- Linear scan of rules (fast for small number of rules)
|
||||
- Read-lock only for rule access
|
||||
|
||||
3. **Packet Processing**
|
||||
- Filtered packets are removed from the slice in-place
|
||||
- Non-matching packets passed through with minimal overhead
|
||||
- No memory allocation for packets that don't match rules
|
||||
|
||||
### Memory Efficiency
|
||||
|
||||
- Packet copies are only made when absolutely necessary
|
||||
- gvisor netstack uses buffer pooling internally
|
||||
- DNS proxy uses a separate goroutine for response handling
|
||||
|
||||
## Usage
|
||||
|
||||
### Configuration
|
||||
|
||||
The DNS proxy is automatically started when the tunnel is created. By default:
|
||||
- DNS proxy IP: `10.30.30.30`
|
||||
- DNS port: `53`
|
||||
- Upstream DNS: `8.8.8.8` (primary), `8.8.4.4` (fallback)
|
||||
|
||||
### Testing
|
||||
|
||||
To test the DNS proxy, configure your DNS settings to use `10.30.30.30`:
|
||||
|
||||
```bash
|
||||
# Using dig
|
||||
dig @10.30.30.30 google.com
|
||||
|
||||
# Using nslookup
|
||||
nslookup google.com 10.30.30.30
|
||||
```
|
||||
|
||||
## Extensibility
|
||||
|
||||
The `FilteredDevice` architecture is designed to be extensible:
|
||||
|
||||
### Adding New Services
|
||||
|
||||
To add a new service (e.g., HTTP proxy on 10.30.30.31):
|
||||
|
||||
1. Create a new service similar to `DNSProxy`
|
||||
2. Register a filter rule with `filteredDev.AddRule()`
|
||||
3. Process packets in your handler
|
||||
4. Write responses back to the TUN device
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
// In your service
|
||||
func (s *MyService) handlePacket(packet []byte) bool {
|
||||
// Parse packet
|
||||
// Process request
|
||||
// Write response to TUN device
|
||||
s.tunDevice.Write([][]byte{response}, 0)
|
||||
return true // Drop from normal path
|
||||
}
|
||||
|
||||
// During initialization
|
||||
filteredDev.AddRule(myServiceIP, myService.handlePacket)
|
||||
```
|
||||
|
||||
### Adding Filtering Rules
|
||||
|
||||
Rules can be added/removed dynamically:
|
||||
|
||||
```go
|
||||
// Add a rule
|
||||
filteredDev.AddRule(netip.MustParseAddr("10.30.30.40"), handleSpecialIP)
|
||||
|
||||
// Remove a rule
|
||||
filteredDev.RemoveRule(netip.MustParseAddr("10.30.30.40"))
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Why Direct TUN Write?
|
||||
|
||||
The DNS proxy writes responses directly back to the TUN device instead of going through the filter because:
|
||||
1. Responses should go to the host, not through WireGuard
|
||||
2. Avoids infinite loops (response → filter → DNS proxy → ...)
|
||||
3. Better performance (one less layer)
|
||||
|
||||
### Thread Safety
|
||||
|
||||
- `FilteredDevice` uses RWMutex for rule access (read-heavy workload)
|
||||
- `DNSProxy` goroutines are properly synchronized
|
||||
- TUN device write operations are thread-safe
|
||||
|
||||
### Error Handling
|
||||
|
||||
- Failed DNS queries fall back to secondary DNS server
|
||||
- Malformed packets are logged but don't crash the proxy
|
||||
- Context cancellation ensures clean shutdown
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements:
|
||||
1. DNS caching to reduce upstream queries
|
||||
2. DNS-over-HTTPS (DoH) support
|
||||
3. Custom DNS filtering/blocking
|
||||
4. Metrics and monitoring
|
||||
5. IPv6 support for DNS proxy
|
||||
6. Multiple upstream DNS servers with health checking
|
||||
7. HTTP/HTTPS proxy on different IPs
|
||||
8. SOCKS5 proxy support
|
||||
Reference in New Issue
Block a user