feat(acme): Add ACME interfaces for Port80Handler and refactor ChallengeResponder to use new acme-interfaces, enhancing event subscription and certificate workflows.
This commit is contained in:
@ -1,3 +1,8 @@
|
||||
/**
|
||||
* NetworkProxy implementation
|
||||
*/
|
||||
// Re-export models
|
||||
export * from './models/index.js';
|
||||
|
||||
// Core NetworkProxy will be added later:
|
||||
// export { NetworkProxy } from './network-proxy.js';
|
||||
|
@ -1,3 +1,4 @@
|
||||
/**
|
||||
* NetworkProxy models
|
||||
*/
|
||||
export * from './types.js';
|
||||
|
130
ts/proxies/network-proxy/models/types.ts
Normal file
130
ts/proxies/network-proxy/models/types.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import * as plugins from '../../../plugins.js';
|
||||
import type { AcmeOptions } from '../../../certificate/models/certificate-types.js';
|
||||
|
||||
/**
|
||||
* Configuration options for NetworkProxy
|
||||
*/
|
||||
export interface NetworkProxyOptions {
|
||||
port: number;
|
||||
maxConnections?: number;
|
||||
keepAliveTimeout?: number;
|
||||
headersTimeout?: number;
|
||||
logLevel?: 'error' | 'warn' | 'info' | 'debug';
|
||||
cors?: {
|
||||
allowOrigin?: string;
|
||||
allowMethods?: string;
|
||||
allowHeaders?: string;
|
||||
maxAge?: number;
|
||||
};
|
||||
|
||||
// Settings for SmartProxy integration
|
||||
connectionPoolSize?: number; // Maximum connections to maintain in the pool to each backend
|
||||
portProxyIntegration?: boolean; // Flag to indicate this proxy is used by SmartProxy
|
||||
useExternalPort80Handler?: boolean; // Flag to indicate using external Port80Handler
|
||||
// Protocol to use when proxying to backends: HTTP/1.x or HTTP/2
|
||||
backendProtocol?: 'http1' | 'http2';
|
||||
|
||||
// ACME certificate management options
|
||||
acme?: AcmeOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for a certificate entry in the cache
|
||||
*/
|
||||
export interface CertificateEntry {
|
||||
key: string;
|
||||
cert: string;
|
||||
expires?: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for reverse proxy configuration
|
||||
*/
|
||||
export interface ReverseProxyConfig {
|
||||
destinationIps: string[];
|
||||
destinationPorts: number[];
|
||||
hostName: string;
|
||||
privateKey: string;
|
||||
publicKey: string;
|
||||
authentication?: {
|
||||
type: 'Basic';
|
||||
user: string;
|
||||
pass: string;
|
||||
};
|
||||
rewriteHostHeader?: boolean;
|
||||
/**
|
||||
* Protocol to use when proxying to this backend: 'http1' or 'http2'.
|
||||
* Overrides the global backendProtocol option if set.
|
||||
*/
|
||||
backendProtocol?: 'http1' | 'http2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for connection tracking in the pool
|
||||
*/
|
||||
export interface ConnectionEntry {
|
||||
socket: plugins.net.Socket;
|
||||
lastUsed: number;
|
||||
isIdle: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket with heartbeat interface
|
||||
*/
|
||||
export interface WebSocketWithHeartbeat extends plugins.wsDefault {
|
||||
lastPong: number;
|
||||
isAlive: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger interface for consistent logging across components
|
||||
*/
|
||||
export interface Logger {
|
||||
debug(message: string, data?: any): void;
|
||||
info(message: string, data?: any): void;
|
||||
warn(message: string, data?: any): void;
|
||||
error(message: string, data?: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a logger based on the specified log level
|
||||
*/
|
||||
export function createLogger(logLevel: string = 'info'): Logger {
|
||||
const logLevels = {
|
||||
error: 0,
|
||||
warn: 1,
|
||||
info: 2,
|
||||
debug: 3
|
||||
};
|
||||
|
||||
return {
|
||||
debug: (message: string, data?: any) => {
|
||||
if (logLevels[logLevel] >= logLevels.debug) {
|
||||
console.log(`[DEBUG] ${message}`, data || '');
|
||||
}
|
||||
},
|
||||
info: (message: string, data?: any) => {
|
||||
if (logLevels[logLevel] >= logLevels.info) {
|
||||
console.log(`[INFO] ${message}`, data || '');
|
||||
}
|
||||
},
|
||||
warn: (message: string, data?: any) => {
|
||||
if (logLevels[logLevel] >= logLevels.warn) {
|
||||
console.warn(`[WARN] ${message}`, data || '');
|
||||
}
|
||||
},
|
||||
error: (message: string, data?: any) => {
|
||||
if (logLevels[logLevel] >= logLevels.error) {
|
||||
console.error(`[ERROR] ${message}`, data || '');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Backward compatibility interfaces
|
||||
export interface INetworkProxyOptions extends NetworkProxyOptions {}
|
||||
export interface ICertificateEntry extends CertificateEntry {}
|
||||
export interface IReverseProxyConfig extends ReverseProxyConfig {}
|
||||
export interface IConnectionEntry extends ConnectionEntry {}
|
||||
export interface IWebSocketWithHeartbeat extends WebSocketWithHeartbeat {}
|
||||
export interface ILogger extends Logger {}
|
@ -1,3 +1,5 @@
|
||||
/**
|
||||
* NfTablesProxy implementation
|
||||
*/
|
||||
// Core NfTablesProxy will be added later:
|
||||
// export { NfTablesProxy } from './nftables-proxy.js';
|
||||
|
@ -1,3 +1,8 @@
|
||||
/**
|
||||
* SmartProxy implementation
|
||||
*/
|
||||
// Re-export models
|
||||
export * from './models/index.js';
|
||||
|
||||
// Core SmartProxy will be added later:
|
||||
// export { SmartProxy } from './smart-proxy.js';
|
||||
|
@ -1,3 +1,4 @@
|
||||
/**
|
||||
* SmartProxy models
|
||||
*/
|
||||
export * from './interfaces.js';
|
||||
|
142
ts/proxies/smart-proxy/models/interfaces.ts
Normal file
142
ts/proxies/smart-proxy/models/interfaces.ts
Normal file
@ -0,0 +1,142 @@
|
||||
import * as plugins from '../../../plugins.js';
|
||||
import type { ForwardConfig } from '../../../forwarding/config/forwarding-types.js';
|
||||
|
||||
/**
|
||||
* Provision object for static or HTTP-01 certificate
|
||||
*/
|
||||
export type SmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
|
||||
|
||||
/**
|
||||
* Domain configuration with forwarding configuration
|
||||
*/
|
||||
export interface DomainConfig {
|
||||
domains: string[]; // Glob patterns for domain(s)
|
||||
forwarding: ForwardConfig; // Unified forwarding configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options for the SmartProxy
|
||||
*/
|
||||
import type { AcmeOptions } from '../../../certificate/models/certificate-types.js';
|
||||
export interface SmartProxyOptions {
|
||||
fromPort: number;
|
||||
toPort: number;
|
||||
targetIP?: string; // Global target host to proxy to, defaults to 'localhost'
|
||||
domainConfigs: DomainConfig[];
|
||||
sniEnabled?: boolean;
|
||||
defaultAllowedIPs?: string[];
|
||||
defaultBlockedIPs?: string[];
|
||||
preserveSourceIP?: boolean;
|
||||
|
||||
// TLS options
|
||||
pfx?: Buffer;
|
||||
key?: string | Buffer | Array<Buffer | string>;
|
||||
passphrase?: string;
|
||||
cert?: string | Buffer | Array<string | Buffer>;
|
||||
ca?: string | Buffer | Array<string | Buffer>;
|
||||
ciphers?: string;
|
||||
honorCipherOrder?: boolean;
|
||||
rejectUnauthorized?: boolean;
|
||||
secureProtocol?: string;
|
||||
servername?: string;
|
||||
minVersion?: string;
|
||||
maxVersion?: string;
|
||||
|
||||
// Timeout settings
|
||||
initialDataTimeout?: number; // Timeout for initial data/SNI (ms), default: 60000 (60s)
|
||||
socketTimeout?: number; // Socket inactivity timeout (ms), default: 3600000 (1h)
|
||||
inactivityCheckInterval?: number; // How often to check for inactive connections (ms), default: 60000 (60s)
|
||||
maxConnectionLifetime?: number; // Default max connection lifetime (ms), default: 86400000 (24h)
|
||||
inactivityTimeout?: number; // Inactivity timeout (ms), default: 14400000 (4h)
|
||||
|
||||
gracefulShutdownTimeout?: number; // (ms) maximum time to wait for connections to close during shutdown
|
||||
globalPortRanges: Array<{ from: number; to: number }>; // Global allowed port ranges
|
||||
forwardAllGlobalRanges?: boolean; // When true, forwards all connections on global port ranges to the global targetIP
|
||||
|
||||
// Socket optimization settings
|
||||
noDelay?: boolean; // Disable Nagle's algorithm (default: true)
|
||||
keepAlive?: boolean; // Enable TCP keepalive (default: true)
|
||||
keepAliveInitialDelay?: number; // Initial delay before sending keepalive probes (ms)
|
||||
maxPendingDataSize?: number; // Maximum bytes to buffer during connection setup
|
||||
|
||||
// Enhanced features
|
||||
disableInactivityCheck?: boolean; // Disable inactivity checking entirely
|
||||
enableKeepAliveProbes?: boolean; // Enable TCP keep-alive probes
|
||||
enableDetailedLogging?: boolean; // Enable detailed connection logging
|
||||
enableTlsDebugLogging?: boolean; // Enable TLS handshake debug logging
|
||||
enableRandomizedTimeouts?: boolean; // Randomize timeouts slightly to prevent thundering herd
|
||||
allowSessionTicket?: boolean; // Allow TLS session ticket for reconnection (default: true)
|
||||
|
||||
// Rate limiting and security
|
||||
maxConnectionsPerIP?: number; // Maximum simultaneous connections from a single IP
|
||||
connectionRateLimitPerMinute?: number; // Max new connections per minute from a single IP
|
||||
|
||||
// Enhanced keep-alive settings
|
||||
keepAliveTreatment?: 'standard' | 'extended' | 'immortal'; // How to treat keep-alive connections
|
||||
keepAliveInactivityMultiplier?: number; // Multiplier for inactivity timeout for keep-alive connections
|
||||
extendedKeepAliveLifetime?: number; // Extended lifetime for keep-alive connections (ms)
|
||||
|
||||
// NetworkProxy integration
|
||||
useNetworkProxy?: number[]; // Array of ports to forward to NetworkProxy
|
||||
networkProxyPort?: number; // Port where NetworkProxy is listening (default: 8443)
|
||||
|
||||
// ACME configuration options for SmartProxy
|
||||
acme?: AcmeOptions;
|
||||
|
||||
/**
|
||||
* Optional certificate provider callback. Return 'http01' to use HTTP-01 challenges,
|
||||
* or a static certificate object for immediate provisioning.
|
||||
*/
|
||||
certProvisionFunction?: (domain: string) => Promise<SmartProxyCertProvisionObject>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced connection record
|
||||
*/
|
||||
export interface ConnectionRecord {
|
||||
id: string; // Unique connection identifier
|
||||
incoming: plugins.net.Socket;
|
||||
outgoing: plugins.net.Socket | null;
|
||||
incomingStartTime: number;
|
||||
outgoingStartTime?: number;
|
||||
outgoingClosedTime?: number;
|
||||
lockedDomain?: string; // Used to lock this connection to the initial SNI
|
||||
connectionClosed: boolean; // Flag to prevent multiple cleanup attempts
|
||||
cleanupTimer?: NodeJS.Timeout; // Timer for max lifetime/inactivity
|
||||
alertFallbackTimeout?: NodeJS.Timeout; // Timer for fallback after alert
|
||||
lastActivity: number; // Last activity timestamp for inactivity detection
|
||||
pendingData: Buffer[]; // Buffer to hold data during connection setup
|
||||
pendingDataSize: number; // Track total size of pending data
|
||||
|
||||
// Enhanced tracking fields
|
||||
bytesReceived: number; // Total bytes received
|
||||
bytesSent: number; // Total bytes sent
|
||||
remoteIP: string; // Remote IP (cached for logging after socket close)
|
||||
localPort: number; // Local port (cached for logging)
|
||||
isTLS: boolean; // Whether this connection is a TLS connection
|
||||
tlsHandshakeComplete: boolean; // Whether the TLS handshake is complete
|
||||
hasReceivedInitialData: boolean; // Whether initial data has been received
|
||||
domainConfig?: DomainConfig; // Associated domain config for this connection
|
||||
|
||||
// Keep-alive tracking
|
||||
hasKeepAlive: boolean; // Whether keep-alive is enabled for this connection
|
||||
inactivityWarningIssued?: boolean; // Whether an inactivity warning has been issued
|
||||
incomingTerminationReason?: string | null; // Reason for incoming termination
|
||||
outgoingTerminationReason?: string | null; // Reason for outgoing termination
|
||||
|
||||
// NetworkProxy tracking
|
||||
usingNetworkProxy?: boolean; // Whether this connection is using a NetworkProxy
|
||||
|
||||
// Renegotiation handler
|
||||
renegotiationHandler?: (chunk: Buffer) => void; // Handler for renegotiation detection
|
||||
|
||||
// Browser connection tracking
|
||||
isBrowserConnection?: boolean; // Whether this connection appears to be from a browser
|
||||
domainSwitches?: number; // Number of times the domain has been switched on this connection
|
||||
}
|
||||
|
||||
// Backward compatibility types
|
||||
export type ISmartProxyCertProvisionObject = SmartProxyCertProvisionObject;
|
||||
export interface IDomainConfig extends DomainConfig {}
|
||||
export interface ISmartProxyOptions extends SmartProxyOptions {}
|
||||
export interface IConnectionRecord extends ConnectionRecord {}
|
Reference in New Issue
Block a user