188 lines
5.1 KiB
TypeScript
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);
|
|
}); |