feat(nftables):add nftables support for nftables
This commit is contained in:
@ -5,7 +5,8 @@
|
||||
* including helpers, validators, utilities, and patterns for working with routes.
|
||||
*/
|
||||
|
||||
// Route helpers have been consolidated in route-patterns.js
|
||||
// Export route helpers for creating route configurations
|
||||
export * from './route-helpers.js';
|
||||
|
||||
// Export route validators for validating route configurations
|
||||
export * from './route-validators.js';
|
||||
|
@ -16,6 +16,7 @@
|
||||
* - WebSocket routes (createWebSocketRoute)
|
||||
* - Port mapping routes (createPortMappingRoute, createOffsetPortMappingRoute)
|
||||
* - Dynamic routing (createDynamicRoute, createSmartLoadBalancer)
|
||||
* - NFTables routes (createNfTablesRoute, createNfTablesTerminateRoute)
|
||||
*/
|
||||
|
||||
import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget, TPortRange, IRouteContext } from '../models/route-types.js';
|
||||
@ -618,4 +619,195 @@ export function createSmartLoadBalancer(options: {
|
||||
priority: options.priority,
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an NFTables-based route for high-performance packet forwarding
|
||||
* @param nameOrDomains Name or domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional route options
|
||||
* @returns Route configuration object
|
||||
*/
|
||||
export function createNfTablesRoute(
|
||||
nameOrDomains: string | string[],
|
||||
target: { host: string; port: number | 'preserve' },
|
||||
options: {
|
||||
ports?: TPortRange;
|
||||
protocol?: 'tcp' | 'udp' | 'all';
|
||||
preserveSourceIP?: boolean;
|
||||
ipAllowList?: string[];
|
||||
ipBlockList?: string[];
|
||||
maxRate?: string;
|
||||
priority?: number;
|
||||
useTls?: boolean;
|
||||
tableName?: string;
|
||||
useIPSets?: boolean;
|
||||
useAdvancedNAT?: boolean;
|
||||
} = {}
|
||||
): IRouteConfig {
|
||||
// Determine if this is a name or domain
|
||||
let name: string;
|
||||
let domains: string | string[] | undefined;
|
||||
|
||||
if (Array.isArray(nameOrDomains) || (typeof nameOrDomains === 'string' && nameOrDomains.includes('.'))) {
|
||||
domains = nameOrDomains;
|
||||
name = Array.isArray(nameOrDomains) ? nameOrDomains[0] : nameOrDomains;
|
||||
} else {
|
||||
name = nameOrDomains;
|
||||
domains = undefined; // No domains
|
||||
}
|
||||
|
||||
// Create route match
|
||||
const match: IRouteMatch = {
|
||||
domains,
|
||||
ports: options.ports || 80
|
||||
};
|
||||
|
||||
// Create route action
|
||||
const action: IRouteAction = {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: target.host,
|
||||
port: target.port
|
||||
},
|
||||
forwardingEngine: 'nftables',
|
||||
nftables: {
|
||||
protocol: options.protocol || 'tcp',
|
||||
preserveSourceIP: options.preserveSourceIP,
|
||||
maxRate: options.maxRate,
|
||||
priority: options.priority,
|
||||
tableName: options.tableName,
|
||||
useIPSets: options.useIPSets,
|
||||
useAdvancedNAT: options.useAdvancedNAT
|
||||
}
|
||||
};
|
||||
|
||||
// Add security if allowed or blocked IPs are specified
|
||||
if (options.ipAllowList?.length || options.ipBlockList?.length) {
|
||||
action.security = {
|
||||
ipAllowList: options.ipAllowList,
|
||||
ipBlockList: options.ipBlockList
|
||||
};
|
||||
}
|
||||
|
||||
// Add TLS options if needed
|
||||
if (options.useTls) {
|
||||
action.tls = {
|
||||
mode: 'passthrough'
|
||||
};
|
||||
}
|
||||
|
||||
// Create the route config
|
||||
return {
|
||||
name,
|
||||
match,
|
||||
action
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an NFTables-based TLS termination route
|
||||
* @param nameOrDomains Name or domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional route options
|
||||
* @returns Route configuration object
|
||||
*/
|
||||
export function createNfTablesTerminateRoute(
|
||||
nameOrDomains: string | string[],
|
||||
target: { host: string; port: number | 'preserve' },
|
||||
options: {
|
||||
ports?: TPortRange;
|
||||
protocol?: 'tcp' | 'udp' | 'all';
|
||||
preserveSourceIP?: boolean;
|
||||
ipAllowList?: string[];
|
||||
ipBlockList?: string[];
|
||||
maxRate?: string;
|
||||
priority?: number;
|
||||
tableName?: string;
|
||||
useIPSets?: boolean;
|
||||
useAdvancedNAT?: boolean;
|
||||
certificate?: 'auto' | { key: string; cert: string };
|
||||
} = {}
|
||||
): IRouteConfig {
|
||||
// Create basic NFTables route
|
||||
const route = createNfTablesRoute(
|
||||
nameOrDomains,
|
||||
target,
|
||||
{
|
||||
...options,
|
||||
ports: options.ports || 443,
|
||||
useTls: false
|
||||
}
|
||||
);
|
||||
|
||||
// Set TLS termination
|
||||
route.action.tls = {
|
||||
mode: 'terminate',
|
||||
certificate: options.certificate || 'auto'
|
||||
};
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a complete NFTables-based HTTPS setup with HTTP redirect
|
||||
* @param nameOrDomains Name or domain(s) to match
|
||||
* @param target Target host and port
|
||||
* @param options Additional route options
|
||||
* @returns Array of two route configurations (HTTPS and HTTP redirect)
|
||||
*/
|
||||
export function createCompleteNfTablesHttpsServer(
|
||||
nameOrDomains: string | string[],
|
||||
target: { host: string; port: number | 'preserve' },
|
||||
options: {
|
||||
httpPort?: TPortRange;
|
||||
httpsPort?: TPortRange;
|
||||
protocol?: 'tcp' | 'udp' | 'all';
|
||||
preserveSourceIP?: boolean;
|
||||
ipAllowList?: string[];
|
||||
ipBlockList?: string[];
|
||||
maxRate?: string;
|
||||
priority?: number;
|
||||
tableName?: string;
|
||||
useIPSets?: boolean;
|
||||
useAdvancedNAT?: boolean;
|
||||
certificate?: 'auto' | { key: string; cert: string };
|
||||
} = {}
|
||||
): IRouteConfig[] {
|
||||
// Create the HTTPS route using NFTables
|
||||
const httpsRoute = createNfTablesTerminateRoute(
|
||||
nameOrDomains,
|
||||
target,
|
||||
{
|
||||
...options,
|
||||
ports: options.httpsPort || 443
|
||||
}
|
||||
);
|
||||
|
||||
// Determine the domain(s) for HTTP redirect
|
||||
const domains = typeof nameOrDomains === 'string' && !nameOrDomains.includes('.')
|
||||
? undefined
|
||||
: nameOrDomains;
|
||||
|
||||
// Extract the HTTPS port for the redirect destination
|
||||
const httpsPort = typeof options.httpsPort === 'number'
|
||||
? options.httpsPort
|
||||
: Array.isArray(options.httpsPort) && typeof options.httpsPort[0] === 'number'
|
||||
? options.httpsPort[0]
|
||||
: 443;
|
||||
|
||||
// Create the HTTP redirect route (this uses standard forwarding, not NFTables)
|
||||
const httpRedirectRoute = createHttpToHttpsRedirect(
|
||||
domains as any, // Type cast needed since domains can be undefined now
|
||||
httpsPort,
|
||||
{
|
||||
match: {
|
||||
ports: options.httpPort || 80,
|
||||
domains: domains as any // Type cast needed since domains can be undefined now
|
||||
},
|
||||
name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains || 'all domains'}`
|
||||
}
|
||||
);
|
||||
|
||||
return [httpsRoute, httpRedirectRoute];
|
||||
}
|
Reference in New Issue
Block a user