/** * Complete SmartProxy Example (v19+) * * This comprehensive example demonstrates all major features of SmartProxy v19+: * - Global ACME configuration * - Route-based configuration * - Helper functions for common patterns * - Dynamic route management * - Certificate status monitoring * - Error handling and recovery */ import { SmartProxy, createHttpRoute, createHttpsTerminateRoute, createHttpsPassthroughRoute, createHttpToHttpsRedirect, createCompleteHttpsServer, createLoadBalancerRoute, createApiRoute, createWebSocketRoute, createStaticFileRoute, createNfTablesRoute } from '../dist_ts/index.js'; async function main() { // Create SmartProxy with comprehensive configuration const proxy = new SmartProxy({ // Global ACME configuration (v19+) acme: { email: 'ssl@bleu.de', useProduction: false, // Use staging for this example port: 8080, // Non-privileged port for development autoRenew: true, renewCheckIntervalHours: 12 }, // Initial routes routes: [ // Basic HTTP service createHttpRoute('api.example.com', { host: 'localhost', port: 3000 }), // HTTPS with automatic certificates createHttpsTerminateRoute('secure.example.com', { host: 'localhost', port: 3001 }, { certificate: 'auto' } ), // Complete HTTPS server with HTTP->HTTPS redirect ...createCompleteHttpsServer('www.example.com', { host: 'localhost', port: 8080 }, { certificate: 'auto' } ), // Load balancer with multiple backends createLoadBalancerRoute( 'app.example.com', ['10.0.0.1', '10.0.0.2', '10.0.0.3'], 8080, { tls: { mode: 'terminate', certificate: 'auto' } } ), // API route with CORS createApiRoute('api.example.com', '/v1', { host: 'api-backend', port: 8081 }, { useTls: true, certificate: 'auto', addCorsHeaders: true } ), // WebSocket support createWebSocketRoute('ws.example.com', '/socket', { host: 'websocket-server', port: 8082 }, { useTls: true, certificate: 'auto' } ), // Static file server createStaticFileRoute(['cdn.example.com', 'static.example.com'], '/var/www/static', { serveOnHttps: true, certificate: 'auto' } ), // HTTPS passthrough for services that handle their own TLS createHttpsPassthroughRoute('legacy.example.com', { host: '192.168.1.100', port: 443 } ), // HTTP to HTTPS redirects createHttpToHttpsRedirect(['*.example.com', 'example.com']) ], // Enable detailed logging for debugging enableDetailedLogging: true }); // Event handlers proxy.on('connection', (event) => { console.log(`New connection: ${event.source} -> ${event.destination}`); }); proxy.on('certificate:issued', (event) => { console.log(`Certificate issued for ${event.domain}`); }); proxy.on('certificate:renewed', (event) => { console.log(`Certificate renewed for ${event.domain}`); }); proxy.on('error', (error) => { console.error('Proxy error:', error); }); // Start the proxy await proxy.start(); console.log('SmartProxy started successfully'); console.log('Listening on ports:', proxy.getListeningPorts()); // Demonstrate dynamic route management setTimeout(async () => { console.log('Adding new route dynamically...'); // Get current routes and add a new one const currentRoutes = proxy.settings.routes; const newRoutes = [ ...currentRoutes, createHttpsTerminateRoute('new-service.example.com', { host: 'localhost', port: 3003 }, { certificate: 'auto' } ) ]; // Update routes await proxy.updateRoutes(newRoutes); console.log('New route added successfully'); }, 5000); // Check certificate status periodically setInterval(async () => { const routes = proxy.settings.routes; for (const route of routes) { if (route.action.tls?.certificate === 'auto') { const status = proxy.getCertificateStatus(route.name); if (status) { console.log(`Certificate status for ${route.name}:`, status); // Renew if expiring soon if (status.status === 'expiring') { console.log(`Renewing certificate for ${route.name}...`); await proxy.renewCertificate(route.name); } } } } }, 3600000); // Check every hour // Graceful shutdown process.on('SIGINT', async () => { console.log('Shutting down gracefully...'); await proxy.stop(); process.exit(0); }); process.on('SIGTERM', async () => { console.log('Received SIGTERM, shutting down...'); await proxy.stop(); process.exit(0); }); } // Run the example main().catch((error) => { console.error('Failed to start proxy:', error); process.exit(1); });