242 lines
5.9 KiB
Markdown
242 lines
5.9 KiB
Markdown
|
# SmartProxy Unified Forwarding System
|
||
|
|
||
|
This document describes the new unified forwarding system in SmartProxy.
|
||
|
|
||
|
## Overview
|
||
|
|
||
|
The forwarding system provides a clean, use-case driven approach to configuring different types of traffic forwarding. It replaces the previous disparate configuration mechanisms with a unified interface.
|
||
|
|
||
|
## Forwarding Types
|
||
|
|
||
|
The system supports four primary forwarding types:
|
||
|
|
||
|
1. **HTTP-only (`http-only`)**: Forwards HTTP traffic to a backend server.
|
||
|
2. **HTTPS Passthrough (`https-passthrough`)**: Passes through raw TLS traffic without termination (SNI forwarding).
|
||
|
3. **HTTPS Termination to HTTP (`https-terminate-to-http`)**: Terminates TLS and forwards the decrypted traffic to an HTTP backend.
|
||
|
4. **HTTPS Termination to HTTPS (`https-terminate-to-https`)**: Terminates TLS and creates a new TLS connection to an HTTPS backend.
|
||
|
|
||
|
## Configuration
|
||
|
|
||
|
### Basic Configuration
|
||
|
|
||
|
Each domain is configured with a forwarding type and target:
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['example.com'],
|
||
|
forwarding: {
|
||
|
type: 'http-only',
|
||
|
target: {
|
||
|
host: 'localhost',
|
||
|
port: 3000
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Helper Functions
|
||
|
|
||
|
Helper functions are provided for common configurations:
|
||
|
|
||
|
```typescript
|
||
|
import { helpers } from '../smartproxy/forwarding/index.js';
|
||
|
|
||
|
// HTTP-only
|
||
|
const httpConfig = helpers.httpOnly('localhost', 3000);
|
||
|
|
||
|
// HTTPS termination to HTTP
|
||
|
const terminateToHttpConfig = helpers.tlsTerminateToHttp('localhost', 3000);
|
||
|
|
||
|
// HTTPS termination to HTTPS
|
||
|
const terminateToHttpsConfig = helpers.tlsTerminateToHttps('localhost', 8443);
|
||
|
|
||
|
// HTTPS passthrough (SNI)
|
||
|
const passthroughConfig = helpers.sniPassthrough('localhost', 443);
|
||
|
```
|
||
|
|
||
|
### Advanced Configuration
|
||
|
|
||
|
For more complex scenarios, additional options can be specified:
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['api.example.com'],
|
||
|
forwarding: {
|
||
|
type: 'https-terminate-to-https',
|
||
|
target: {
|
||
|
host: ['10.0.0.10', '10.0.0.11'], // Round-robin load balancing
|
||
|
port: 8443
|
||
|
},
|
||
|
http: {
|
||
|
enabled: true,
|
||
|
redirectToHttps: true
|
||
|
},
|
||
|
https: {
|
||
|
// Custom certificate instead of ACME-provisioned
|
||
|
customCert: {
|
||
|
key: '-----BEGIN PRIVATE KEY-----\n...',
|
||
|
cert: '-----BEGIN CERTIFICATE-----\n...'
|
||
|
}
|
||
|
},
|
||
|
security: {
|
||
|
allowedIps: ['10.0.0.*', '192.168.1.*'],
|
||
|
blockedIps: ['1.2.3.4'],
|
||
|
maxConnections: 100
|
||
|
},
|
||
|
advanced: {
|
||
|
timeout: 30000,
|
||
|
headers: {
|
||
|
'X-Forwarded-For': '{clientIp}',
|
||
|
'X-Original-Host': '{sni}'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## DomainManager
|
||
|
|
||
|
The `DomainManager` class manages domains and their forwarding handlers:
|
||
|
|
||
|
```typescript
|
||
|
import { DomainManager, createDomainConfig, helpers } from '../smartproxy/forwarding/index.js';
|
||
|
|
||
|
// Create the domain manager
|
||
|
const domainManager = new DomainManager();
|
||
|
|
||
|
// Add a domain
|
||
|
await domainManager.addDomainConfig(
|
||
|
createDomainConfig('example.com', helpers.httpOnly('localhost', 3000))
|
||
|
);
|
||
|
|
||
|
// Handle a connection
|
||
|
domainManager.handleConnection('example.com', socket);
|
||
|
|
||
|
// Handle an HTTP request
|
||
|
domainManager.handleHttpRequest('example.com', req, res);
|
||
|
```
|
||
|
|
||
|
## Usage Examples
|
||
|
|
||
|
### Basic HTTP Server
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['example.com'],
|
||
|
forwarding: {
|
||
|
type: 'http-only',
|
||
|
target: {
|
||
|
host: 'localhost',
|
||
|
port: 3000
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### HTTPS Termination with HTTP Backend
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['secure.example.com'],
|
||
|
forwarding: {
|
||
|
type: 'https-terminate-to-http',
|
||
|
target: {
|
||
|
host: 'localhost',
|
||
|
port: 3000
|
||
|
},
|
||
|
acme: {
|
||
|
production: true // Use production Let's Encrypt
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### HTTPS Termination with HTTPS Backend
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['secure-backend.example.com'],
|
||
|
forwarding: {
|
||
|
type: 'https-terminate-to-https',
|
||
|
target: {
|
||
|
host: 'internal-api',
|
||
|
port: 8443
|
||
|
},
|
||
|
http: {
|
||
|
redirectToHttps: true // Redirect HTTP requests to HTTPS
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### SNI Passthrough
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['passthrough.example.com'],
|
||
|
forwarding: {
|
||
|
type: 'https-passthrough',
|
||
|
target: {
|
||
|
host: '10.0.0.5',
|
||
|
port: 443
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Load Balancing
|
||
|
|
||
|
```typescript
|
||
|
{
|
||
|
domains: ['api.example.com'],
|
||
|
forwarding: {
|
||
|
type: 'https-terminate-to-https',
|
||
|
target: {
|
||
|
host: ['10.0.0.10', '10.0.0.11', '10.0.0.12'], // Round-robin
|
||
|
port: 8443
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Integration with SmartProxy
|
||
|
|
||
|
The unified forwarding system integrates with SmartProxy by replacing the existing domain configuration mechanism. The `DomainManager` handles all domain matching and forwarding, while the individual forwarding handlers handle the connections and requests.
|
||
|
|
||
|
The system is designed to be used in SmartProxy's `ConnectionHandler` and in the `Port80Handler` for HTTP traffic.
|
||
|
|
||
|
## Testing
|
||
|
|
||
|
See the `test.forwarding.ts` file for examples of how to test the forwarding system.
|
||
|
|
||
|
## Migration
|
||
|
|
||
|
When migrating from the older configuration system, map the existing configuration to the appropriate forwarding type:
|
||
|
|
||
|
1. HTTP forwarding → `http-only`
|
||
|
2. SNI forwarding → `https-passthrough`
|
||
|
3. NetworkProxy with HTTP backend → `https-terminate-to-http`
|
||
|
4. NetworkProxy with HTTPS backend → `https-terminate-to-https`
|
||
|
|
||
|
## Extensibility
|
||
|
|
||
|
The forwarding system is designed to be extensible:
|
||
|
|
||
|
1. New forwarding types can be added by:
|
||
|
- Adding a new type to `ForwardingType`
|
||
|
- Creating a new handler class
|
||
|
- Adding the handler to `ForwardingHandlerFactory`
|
||
|
|
||
|
2. Existing types can be extended with new options by updating the interface and handler implementations.
|
||
|
|
||
|
## Implementation Details
|
||
|
|
||
|
The system uses a factory pattern to create the appropriate handler for each forwarding type. Each handler extends a base `ForwardingHandler` class that provides common functionality.
|
||
|
|
||
|
The `DomainManager` manages the domains and their handlers, and delegates connections and requests to the appropriate handler.
|
||
|
|
||
|
## Performance Considerations
|
||
|
|
||
|
- The system uses a map for fast domain lookups
|
||
|
- Wildcard domains are supported through pattern matching
|
||
|
- Handlers are reused for multiple domains with the same configuration
|