smartproxy/examples/complete-example-v19.ts

188 lines
5.1 KiB
TypeScript

/**
* 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);
});