feat(proxies): introduce nftables command executor and utilities, default certificate provider, expanded route/socket helper modules, and security improvements
This commit is contained in:
163
ts/proxies/smart-proxy/utils/route-helpers/https-helpers.ts
Normal file
163
ts/proxies/smart-proxy/utils/route-helpers/https-helpers.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* HTTPS Route Helper Functions
|
||||
*
|
||||
* This module provides utility functions for creating HTTPS route configurations
|
||||
* including TLS termination and passthrough routes.
|
||||
*/
|
||||
|
||||
import type { IRouteConfig, IRouteMatch, IRouteAction } from '../../models/route-types.js';
|
||||
import { SocketHandlers } from './socket-handlers.js';
|
||||
|
||||
/**
|
||||
* Create an HTTPS route with TLS termination
|
||||
* @param domains Domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional route options
|
||||
* @returns Route configuration object
|
||||
*/
|
||||
export function createHttpsTerminateRoute(
|
||||
domains: string | string[],
|
||||
target: { host: string | string[]; port: number },
|
||||
options: {
|
||||
certificate?: 'auto' | { key: string; cert: string };
|
||||
httpPort?: number | number[];
|
||||
httpsPort?: number | number[];
|
||||
reencrypt?: boolean;
|
||||
name?: string;
|
||||
[key: string]: any;
|
||||
} = {}
|
||||
): IRouteConfig {
|
||||
// Create route match
|
||||
const match: IRouteMatch = {
|
||||
ports: options.httpsPort || 443,
|
||||
domains
|
||||
};
|
||||
|
||||
// Create route action
|
||||
const action: IRouteAction = {
|
||||
type: 'forward',
|
||||
targets: [target],
|
||||
tls: {
|
||||
mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
|
||||
certificate: options.certificate || 'auto'
|
||||
}
|
||||
};
|
||||
|
||||
// Create the route config
|
||||
return {
|
||||
match,
|
||||
action,
|
||||
name: options.name || `HTTPS Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTP to HTTPS redirect route
|
||||
* @param domains Domain(s) to match
|
||||
* @param httpsPort HTTPS port to redirect to (default: 443)
|
||||
* @param options Additional route options
|
||||
* @returns Route configuration object
|
||||
*/
|
||||
export function createHttpToHttpsRedirect(
|
||||
domains: string | string[],
|
||||
httpsPort: number = 443,
|
||||
options: Partial<IRouteConfig> = {}
|
||||
): IRouteConfig {
|
||||
// Create route match
|
||||
const match: IRouteMatch = {
|
||||
ports: options.match?.ports || 80,
|
||||
domains
|
||||
};
|
||||
|
||||
// Create route action
|
||||
const action: IRouteAction = {
|
||||
type: 'socket-handler',
|
||||
socketHandler: SocketHandlers.httpRedirect(`https://{domain}:${httpsPort}{path}`, 301)
|
||||
};
|
||||
|
||||
// Create the route config
|
||||
return {
|
||||
match,
|
||||
action,
|
||||
name: options.name || `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTPS passthrough route (SNI-based forwarding without TLS termination)
|
||||
* @param domains Domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional route options
|
||||
* @returns Route configuration object
|
||||
*/
|
||||
export function createHttpsPassthroughRoute(
|
||||
domains: string | string[],
|
||||
target: { host: string | string[]; port: number },
|
||||
options: Partial<IRouteConfig> = {}
|
||||
): IRouteConfig {
|
||||
// Create route match
|
||||
const match: IRouteMatch = {
|
||||
ports: options.match?.ports || 443,
|
||||
domains
|
||||
};
|
||||
|
||||
// Create route action
|
||||
const action: IRouteAction = {
|
||||
type: 'forward',
|
||||
targets: [target],
|
||||
tls: {
|
||||
mode: 'passthrough'
|
||||
}
|
||||
};
|
||||
|
||||
// Create the route config
|
||||
return {
|
||||
match,
|
||||
action,
|
||||
name: options.name || `HTTPS Passthrough for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a complete HTTPS server with HTTP to HTTPS redirects
|
||||
* @param domains Domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional configuration options
|
||||
* @returns Array of two route configurations (HTTPS and HTTP redirect)
|
||||
*/
|
||||
export function createCompleteHttpsServer(
|
||||
domains: string | string[],
|
||||
target: { host: string | string[]; port: number },
|
||||
options: {
|
||||
certificate?: 'auto' | { key: string; cert: string };
|
||||
httpPort?: number | number[];
|
||||
httpsPort?: number | number[];
|
||||
reencrypt?: boolean;
|
||||
name?: string;
|
||||
[key: string]: any;
|
||||
} = {}
|
||||
): IRouteConfig[] {
|
||||
// Create the HTTPS route
|
||||
const httpsRoute = createHttpsTerminateRoute(domains, target, options);
|
||||
|
||||
// Create the HTTP redirect route
|
||||
const httpRedirectRoute = createHttpToHttpsRedirect(
|
||||
domains,
|
||||
// Extract the HTTPS port from the HTTPS route - ensure it's a number
|
||||
typeof options.httpsPort === 'number' ? options.httpsPort :
|
||||
Array.isArray(options.httpsPort) ? options.httpsPort[0] : 443,
|
||||
{
|
||||
// Set the HTTP port
|
||||
match: {
|
||||
ports: options.httpPort || 80,
|
||||
domains
|
||||
},
|
||||
name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`
|
||||
}
|
||||
);
|
||||
|
||||
return [httpsRoute, httpRedirectRoute];
|
||||
}
|
||||
Reference in New Issue
Block a user