138 lines
4.4 KiB
TypeScript
138 lines
4.4 KiB
TypeScript
import * as plugins from '../plugins.js';
|
|
import * as paths from '../paths.js';
|
|
import { SzDcRouterConnector } from './classes.dcr.sz.connector.js';
|
|
|
|
import type { SzPlatformService } from '../platformservice.js';
|
|
import { type IMtaConfig, MtaService } from '../mta/classes.mta.js';
|
|
|
|
// Types are referenced via plugins.smartproxy.*
|
|
|
|
export interface IDcRouterOptions {
|
|
platformServiceInstance?: SzPlatformService;
|
|
|
|
/** SmartProxy (TCP/SNI) configuration */
|
|
smartProxyOptions?: plugins.smartproxy.ISmartProxyOptions;
|
|
/** Reverse proxy host configurations for HTTP(S) layer */
|
|
reverseProxyConfigs?: plugins.smartproxy.IReverseProxyConfig[];
|
|
/** MTA (SMTP) service configuration */
|
|
mtaConfig?: IMtaConfig;
|
|
/** DNS server configuration */
|
|
dnsServerConfig?: plugins.smartdns.IDnsServerOptions;
|
|
}
|
|
|
|
/**
|
|
* DcRouter can be run on ingress and egress to and from a datacenter site.
|
|
*/
|
|
/**
|
|
* Context passed to HTTP routing rules
|
|
*/
|
|
/**
|
|
* Context passed to port proxy (SmartProxy) routing rules
|
|
*/
|
|
export interface PortProxyRuleContext {
|
|
proxy: plugins.smartproxy.SmartProxy;
|
|
configs: plugins.smartproxy.IPortProxySettings['domainConfigs'];
|
|
}
|
|
export class DcRouter {
|
|
public szDcRouterConnector = new SzDcRouterConnector(this);
|
|
public options: IDcRouterOptions;
|
|
public smartProxy?: plugins.smartproxy.SmartProxy;
|
|
public mta?: MtaService;
|
|
public dnsServer?: plugins.smartdns.DnsServer;
|
|
/** SMTP rule engine */
|
|
public smtpRuleEngine?: plugins.smartrule.SmartRule<any>;
|
|
constructor(optionsArg: IDcRouterOptions) {
|
|
this.options = optionsArg;
|
|
}
|
|
|
|
public async start() {
|
|
|
|
// TCP/SNI proxy (SmartProxy)
|
|
if (this.options.smartProxyOptions) {
|
|
// Lets setup smartacme
|
|
let certProvisionFunction: plugins.smartproxy.ISmartProxyOptions['certProvisionFunction'];
|
|
if (true) {
|
|
const smartAcmeInstance = new plugins.smartacme.SmartAcme({
|
|
accountEmail: this.options.smartProxyOptions.acme.accountEmail,
|
|
certManager: new plugins.smartacme.certmanagers.MongoCertManager({
|
|
mongoDbUrl: await this.szDcRouterConnector.getEnvVarOnDemand('MONGO_DB_URL'),
|
|
mongoDbUser: await this.szDcRouterConnector.getEnvVarOnDemand('MONGO_DB_USER'),
|
|
mongoDbPass: await this.szDcRouterConnector.getEnvVarOnDemand('MONGO_DB_PASS'),
|
|
mongoDbName: await this.szDcRouterConnector.getEnvVarOnDemand('MONGO_DB_NAME'),
|
|
}),
|
|
environment: 'production',
|
|
accountPrivateKey: await this.szDcRouterConnector.getEnvVarOnDemand('ACME_ACCOUNT_PRIVATE_KEY'),
|
|
challengeHandlers: [
|
|
new plugins.smartacme.handlers.Dns01Handler(new plugins.cloudflare.CloudflareAccount('')) // TODO
|
|
],
|
|
|
|
});
|
|
certProvisionFunction = async (domainArg) => {
|
|
const domainSupported = await smartAcmeInstance.challengeHandlers[0].checkWetherDomainIsSupported(domainArg);
|
|
if (!domainSupported) {
|
|
return 'http01';
|
|
}
|
|
return smartAcmeInstance.getCertificateForDomain(domainArg);
|
|
};
|
|
}
|
|
|
|
this.smartProxy = new plugins.smartproxy.SmartProxy(this.options.smartProxyOptions);
|
|
// Initialize SMTP rule engine from MTA service if available
|
|
if (this.mta) {
|
|
this.smtpRuleEngine = this.mta.smtpRuleEngine;
|
|
}
|
|
}
|
|
// MTA service
|
|
if (this.options.mtaConfig) {
|
|
this.mta = new MtaService(null, this.options.mtaConfig);
|
|
}
|
|
// DNS server
|
|
if (this.options.dnsServerConfig) {
|
|
this.dnsServer = new plugins.smartdns.DnsServer(this.options.dnsServerConfig);
|
|
}
|
|
|
|
|
|
|
|
// Start SmartProxy if configured
|
|
if (this.smartProxy) {
|
|
await this.smartProxy.start();
|
|
}
|
|
// Start MTA service if configured
|
|
if (this.mta) {
|
|
await this.mta.start();
|
|
}
|
|
// Start DNS server if configured
|
|
if (this.dnsServer) {
|
|
await this.dnsServer.start();
|
|
}
|
|
}
|
|
|
|
public async stop() {
|
|
// Stop SmartProxy
|
|
if (this.smartProxy) {
|
|
await this.smartProxy.stop();
|
|
}
|
|
// Stop MTA service
|
|
if (this.mta) {
|
|
await this.mta.stop();
|
|
}
|
|
// Stop DNS server
|
|
if (this.dnsServer) {
|
|
await this.dnsServer.stop();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register an SMTP routing rule
|
|
*/
|
|
public addSmtpRule(
|
|
priority: number,
|
|
check: (email: any) => Promise<any>,
|
|
action: (email: any) => Promise<any>
|
|
): void {
|
|
this.smtpRuleEngine?.createRule(priority, check, action);
|
|
}
|
|
}
|
|
|
|
export default DcRouter;
|