2025-05-09 21:21:28 +00:00
|
|
|
import * as plugins from '../../plugins.js';
|
|
|
|
import { NetworkProxy } from '../network-proxy/index.js';
|
2025-05-10 00:49:39 +00:00
|
|
|
import type { IConnectionRecord, ISmartProxyOptions } from './models/interfaces.js';
|
|
|
|
import type { IRouteConfig } from './models/route-types.js';
|
2025-03-14 09:53:25 +00:00
|
|
|
|
|
|
|
export class NetworkProxyBridge {
|
|
|
|
private networkProxy: NetworkProxy | null = null;
|
2025-05-09 21:21:28 +00:00
|
|
|
|
2025-05-09 22:46:53 +00:00
|
|
|
constructor(private settings: ISmartProxyOptions) {}
|
2025-03-14 09:53:25 +00:00
|
|
|
|
2025-03-25 22:30:57 +00:00
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Get the NetworkProxy instance
|
2025-03-25 22:30:57 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public getNetworkProxy(): NetworkProxy | null {
|
|
|
|
return this.networkProxy;
|
2025-03-25 22:30:57 +00:00
|
|
|
}
|
|
|
|
|
2025-03-14 09:53:25 +00:00
|
|
|
/**
|
|
|
|
* Initialize NetworkProxy instance
|
|
|
|
*/
|
|
|
|
public async initialize(): Promise<void> {
|
|
|
|
if (!this.networkProxy && this.settings.useNetworkProxy && this.settings.useNetworkProxy.length > 0) {
|
|
|
|
const networkProxyOptions: any = {
|
|
|
|
port: this.settings.networkProxyPort!,
|
|
|
|
portProxyIntegration: true,
|
2025-05-18 15:38:07 +00:00
|
|
|
logLevel: this.settings.enableDetailedLogging ? 'debug' : 'info'
|
2025-03-14 09:53:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
this.networkProxy = new NetworkProxy(networkProxyOptions);
|
|
|
|
console.log(`Initialized NetworkProxy on port ${this.settings.networkProxyPort}`);
|
|
|
|
|
2025-05-10 00:49:39 +00:00
|
|
|
// Apply route configurations to NetworkProxy
|
|
|
|
await this.syncRoutesToNetworkProxy(this.settings.routes || []);
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-03-25 22:30:57 +00:00
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Sync routes to NetworkProxy
|
2025-03-25 22:30:57 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public async syncRoutesToNetworkProxy(routes: IRouteConfig[]): Promise<void> {
|
2025-03-25 22:30:57 +00:00
|
|
|
if (!this.networkProxy) return;
|
2025-05-13 12:48:41 +00:00
|
|
|
|
2025-05-18 15:38:07 +00:00
|
|
|
// Convert routes to NetworkProxy format
|
|
|
|
const networkProxyConfigs = routes
|
|
|
|
.filter(route => {
|
|
|
|
// Check if this route matches any of the specified network proxy ports
|
|
|
|
const routePorts = Array.isArray(route.match.ports)
|
|
|
|
? route.match.ports
|
|
|
|
: [route.match.ports];
|
|
|
|
|
|
|
|
return routePorts.some(port =>
|
|
|
|
this.settings.useNetworkProxy?.includes(port)
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.map(route => this.routeToNetworkProxyConfig(route));
|
|
|
|
|
|
|
|
// Apply configurations to NetworkProxy
|
|
|
|
await this.networkProxy.updateRouteConfigs(networkProxyConfigs);
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Convert route to NetworkProxy configuration
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
private routeToNetworkProxyConfig(route: IRouteConfig): any {
|
|
|
|
// Convert route to NetworkProxy domain config format
|
|
|
|
return {
|
|
|
|
domain: route.match.domains?.[0] || '*',
|
|
|
|
target: route.action.target,
|
|
|
|
tls: route.action.tls,
|
|
|
|
security: route.action.security
|
|
|
|
};
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Check if connection should use NetworkProxy
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public shouldUseNetworkProxy(connection: IConnectionRecord, routeMatch: any): boolean {
|
|
|
|
// Only use NetworkProxy for TLS termination
|
|
|
|
return (
|
|
|
|
routeMatch.route.action.tls?.mode === 'terminate' ||
|
|
|
|
routeMatch.route.action.tls?.mode === 'terminate-and-reencrypt'
|
|
|
|
) && this.networkProxy !== null;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Forward connection to NetworkProxy
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public async forwardToNetworkProxy(
|
2025-03-14 09:53:25 +00:00
|
|
|
connectionId: string,
|
|
|
|
socket: plugins.net.Socket,
|
2025-05-09 22:46:53 +00:00
|
|
|
record: IConnectionRecord,
|
2025-05-18 15:38:07 +00:00
|
|
|
initialChunk: Buffer,
|
|
|
|
networkProxyPort: number,
|
|
|
|
cleanupCallback: (reason: string) => void
|
|
|
|
): Promise<void> {
|
2025-03-14 09:53:25 +00:00
|
|
|
if (!this.networkProxy) {
|
2025-05-18 15:38:07 +00:00
|
|
|
throw new Error('NetworkProxy not initialized');
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
2025-05-18 15:38:07 +00:00
|
|
|
|
|
|
|
const proxySocket = new plugins.net.Socket();
|
|
|
|
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
|
|
proxySocket.connect(networkProxyPort, 'localhost', () => {
|
|
|
|
console.log(`[${connectionId}] Connected to NetworkProxy for termination`);
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
|
|
|
|
proxySocket.on('error', reject);
|
2025-03-14 09:53:25 +00:00
|
|
|
});
|
2025-05-18 15:38:07 +00:00
|
|
|
|
|
|
|
// Send initial chunk if present
|
|
|
|
if (initialChunk) {
|
|
|
|
proxySocket.write(initialChunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pipe the sockets together
|
|
|
|
socket.pipe(proxySocket);
|
|
|
|
proxySocket.pipe(socket);
|
|
|
|
|
|
|
|
// Handle cleanup
|
|
|
|
const cleanup = (reason: string) => {
|
|
|
|
socket.unpipe(proxySocket);
|
|
|
|
proxySocket.unpipe(socket);
|
|
|
|
proxySocket.destroy();
|
|
|
|
cleanupCallback(reason);
|
|
|
|
};
|
|
|
|
|
|
|
|
socket.on('end', () => cleanup('socket_end'));
|
|
|
|
socket.on('error', () => cleanup('socket_error'));
|
|
|
|
proxySocket.on('end', () => cleanup('proxy_end'));
|
|
|
|
proxySocket.on('error', () => cleanup('proxy_error'));
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Start NetworkProxy
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public async start(): Promise<void> {
|
|
|
|
if (this.networkProxy) {
|
|
|
|
await this.networkProxy.start();
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2025-05-18 15:38:07 +00:00
|
|
|
* Stop NetworkProxy
|
2025-03-14 09:53:25 +00:00
|
|
|
*/
|
2025-05-18 15:38:07 +00:00
|
|
|
public async stop(): Promise<void> {
|
|
|
|
if (this.networkProxy) {
|
|
|
|
await this.networkProxy.stop();
|
|
|
|
this.networkProxy = null;
|
2025-03-14 09:53:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|