112 lines
4.2 KiB
Markdown
112 lines
4.2 KiB
Markdown
|
# SmartProxy: Proxy Protocol and Proxy Chaining Summary
|
||
|
|
||
|
## Quick Summary
|
||
|
|
||
|
SmartProxy supports proxy chaining through the **WrappedSocket** infrastructure, which is designed to handle PROXY protocol for preserving real client IP addresses across multiple proxy layers. While the infrastructure is in place (v19.5.19+), the actual PROXY protocol parsing is not yet implemented.
|
||
|
|
||
|
## Current State
|
||
|
|
||
|
### ✅ What's Implemented
|
||
|
- **WrappedSocket class** - Foundation for proxy protocol support
|
||
|
- **Proxy IP configuration** - `proxyIPs` setting to define trusted proxies
|
||
|
- **Socket wrapping** - All incoming connections wrapped automatically
|
||
|
- **Connection tracking** - Real client IP tracking in connection records
|
||
|
- **Test infrastructure** - Tests for proxy chaining scenarios
|
||
|
|
||
|
### ❌ What's Missing
|
||
|
- **PROXY protocol v1 parsing** - Header parsing not implemented
|
||
|
- **PROXY protocol v2 support** - Binary format not supported
|
||
|
- **Automatic header generation** - Must be manually implemented
|
||
|
- **Production testing** - No HAProxy/AWS ELB compatibility tests
|
||
|
|
||
|
## Key Files
|
||
|
|
||
|
### Core Implementation
|
||
|
- `ts/core/models/wrapped-socket.ts` - WrappedSocket class
|
||
|
- `ts/core/models/socket-types.ts` - Helper functions
|
||
|
- `ts/proxies/smart-proxy/route-connection-handler.ts` - Connection handling
|
||
|
- `ts/proxies/smart-proxy/models/interfaces.ts` - Configuration interfaces
|
||
|
|
||
|
### Tests
|
||
|
- `test/test.wrapped-socket.ts` - WrappedSocket unit tests
|
||
|
- `test/test.proxy-chain-simple.node.ts` - Basic proxy chain test
|
||
|
- `test/test.proxy-chaining-accumulation.node.ts` - Connection leak tests
|
||
|
|
||
|
### Documentation
|
||
|
- `readme.proxy-protocol.md` - Detailed implementation guide
|
||
|
- `readme.proxy-protocol-example.md` - Code examples and future implementation
|
||
|
- `readme.hints.md` - Project overview with WrappedSocket notes
|
||
|
|
||
|
## Quick Configuration Example
|
||
|
|
||
|
```typescript
|
||
|
// Outer proxy (internet-facing)
|
||
|
const outerProxy = new SmartProxy({
|
||
|
sendProxyProtocol: true, // Will send PROXY protocol (when implemented)
|
||
|
routes: [{
|
||
|
name: 'forward-to-inner',
|
||
|
match: { ports: 443 },
|
||
|
action: {
|
||
|
type: 'forward',
|
||
|
target: { host: 'inner-proxy.local', port: 443 },
|
||
|
tls: { mode: 'passthrough' }
|
||
|
}
|
||
|
}]
|
||
|
});
|
||
|
|
||
|
// Inner proxy (backend-facing)
|
||
|
const innerProxy = new SmartProxy({
|
||
|
proxyIPs: ['outer-proxy.local'], // Trust the outer proxy
|
||
|
acceptProxyProtocol: true, // Will parse PROXY protocol (when implemented)
|
||
|
routes: [{
|
||
|
name: 'forward-to-backend',
|
||
|
match: { ports: 443, domains: 'api.example.com' },
|
||
|
action: {
|
||
|
type: 'forward',
|
||
|
target: { host: 'backend.local', port: 8080 },
|
||
|
tls: { mode: 'terminate' }
|
||
|
}
|
||
|
}]
|
||
|
});
|
||
|
```
|
||
|
|
||
|
## How It Works (Conceptually)
|
||
|
|
||
|
1. **Client** connects to **Outer Proxy**
|
||
|
2. **Outer Proxy** wraps socket in WrappedSocket
|
||
|
3. **Outer Proxy** forwards to **Inner Proxy**
|
||
|
- Would prepend: `PROXY TCP4 <client-ip> <proxy-ip> <client-port> <proxy-port>\r\n`
|
||
|
4. **Inner Proxy** receives connection from trusted proxy
|
||
|
5. **Inner Proxy** would parse PROXY protocol header
|
||
|
6. **Inner Proxy** updates WrappedSocket with real client IP
|
||
|
7. **Backend** receives connection with preserved client information
|
||
|
|
||
|
## Important Notes
|
||
|
|
||
|
### Connection Cleanup
|
||
|
The fix for proxy chain connection accumulation (v19.5.14+) changed the default socket behavior:
|
||
|
- **Before**: Half-open connections supported by default (caused accumulation)
|
||
|
- **After**: Both sockets close when one closes (prevents accumulation)
|
||
|
- **Override**: Set `enableHalfOpen: true` if half-open needed
|
||
|
|
||
|
### Security
|
||
|
- Only parse PROXY protocol from IPs listed in `proxyIPs`
|
||
|
- Never use `0.0.0.0/0` as a trusted proxy range
|
||
|
- Each proxy in chain must explicitly trust the previous proxy
|
||
|
|
||
|
### Testing
|
||
|
Use the test files as reference implementations:
|
||
|
- Simple chains: `test.proxy-chain-simple.node.ts`
|
||
|
- Connection leaks: `test.proxy-chaining-accumulation.node.ts`
|
||
|
- Rapid reconnects: `test.rapid-retry-cleanup.node.ts`
|
||
|
|
||
|
## Next Steps
|
||
|
|
||
|
To fully implement PROXY protocol support:
|
||
|
1. Implement the parser in `ProxyProtocolParser` class
|
||
|
2. Integrate parser into `handleConnection` method
|
||
|
3. Add header generation to `setupDirectConnection`
|
||
|
4. Test with real proxies (HAProxy, nginx, AWS ELB)
|
||
|
5. Add PROXY protocol v2 support for better performance
|
||
|
|
||
|
See `readme.proxy-protocol-example.md` for detailed implementation examples.
|