feat(proxies): introduce nftables command executor and utilities, default certificate provider, expanded route/socket helper modules, and security improvements

This commit is contained in:
2026-01-30 04:06:32 +00:00
parent f25be4c55a
commit 9697ab3078
27 changed files with 2453 additions and 2048 deletions

View File

@@ -0,0 +1,150 @@
import * as plugins from '../../plugins.js';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import { AsyncFileSystem } from '../../core/utils/fs-utils.js';
import type { ILogger, ICertificateEntry } from './models/types.js';
/**
* Interface for default certificate data
*/
export interface IDefaultCertificates {
key: string;
cert: string;
}
/**
* Provides default SSL certificates for HttpProxy.
* This is a minimal replacement for the deprecated CertificateManager.
*
* For production certificate management, use SmartCertManager instead.
*/
export class DefaultCertificateProvider {
private defaultCertificates: IDefaultCertificates | null = null;
private certificateCache: Map<string, ICertificateEntry> = new Map();
private initialized = false;
constructor(private logger?: ILogger) {}
/**
* Load default certificates asynchronously (preferred)
*/
public async loadDefaultCertificatesAsync(): Promise<IDefaultCertificates> {
if (this.defaultCertificates) {
return this.defaultCertificates;
}
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
try {
const [key, cert] = await Promise.all([
AsyncFileSystem.readFile(path.join(certPath, 'key.pem')),
AsyncFileSystem.readFile(path.join(certPath, 'cert.pem'))
]);
this.defaultCertificates = { key, cert };
this.logger?.info?.('Loaded default certificates from filesystem');
this.initialized = true;
return this.defaultCertificates;
} catch (error) {
this.logger?.warn?.(`Failed to load default certificates: ${error}`);
this.defaultCertificates = this.generateFallbackCertificate();
this.initialized = true;
return this.defaultCertificates;
}
}
/**
* Load default certificates synchronously (for backward compatibility)
* @deprecated Use loadDefaultCertificatesAsync instead
*/
public loadDefaultCertificatesSync(): IDefaultCertificates {
if (this.defaultCertificates) {
return this.defaultCertificates;
}
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
try {
this.defaultCertificates = {
key: fs.readFileSync(path.join(certPath, 'key.pem'), 'utf8'),
cert: fs.readFileSync(path.join(certPath, 'cert.pem'), 'utf8')
};
this.logger?.info?.('Loaded default certificates from filesystem (sync)');
} catch (error) {
this.logger?.warn?.(`Failed to load default certificates: ${error}`);
this.defaultCertificates = this.generateFallbackCertificate();
}
this.initialized = true;
return this.defaultCertificates;
}
/**
* Gets the default certificates (loads synchronously if not already loaded)
*/
public getDefaultCertificates(): IDefaultCertificates {
if (!this.defaultCertificates) {
return this.loadDefaultCertificatesSync();
}
return this.defaultCertificates;
}
/**
* Updates a certificate in the cache
*/
public updateCertificate(domain: string, cert: string, key: string): void {
this.certificateCache.set(domain, {
cert,
key,
expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days
});
this.logger?.info?.(`Certificate updated for ${domain}`);
}
/**
* Gets a cached certificate
*/
public getCachedCertificate(domain: string): ICertificateEntry | null {
return this.certificateCache.get(domain) || null;
}
/**
* Gets statistics for metrics
*/
public getStats(): { cachedCertificates: number; defaultCertEnabled: boolean } {
return {
cachedCertificates: this.certificateCache.size,
defaultCertEnabled: this.defaultCertificates !== null
};
}
/**
* Generate a fallback self-signed certificate placeholder
* Note: This is just a placeholder - real apps should provide proper certificates
*/
private generateFallbackCertificate(): IDefaultCertificates {
this.logger?.warn?.('Using fallback self-signed certificate placeholder');
// Minimal self-signed certificate for fallback only
// In production, proper certificates should be provided via SmartCertManager
const selfSignedCert = `-----BEGIN CERTIFICATE-----
MIIBkTCB+wIJAKHHIgIIA0/cMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAlVT
MB4XDTE0MDEwMTAwMDAwMFoXDTI0MDEwMTAwMDAwMFowDTELMAkGA1UEBhMCVVMw
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRiH0VwnOH3jCV7c6JFZWYrvuqy
-----END CERTIFICATE-----`;
const selfSignedKey = `-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRiH0VwnOH3jCV7
c6JFZWYrvuqyALCLXj0pcr1iqNdHjegNXnkl5zjdaUjq4edNOKl7M1AlFiYjG2xk
-----END PRIVATE KEY-----`;
return {
key: selfSignedKey,
cert: selfSignedCert
};
}
}