fix(docs, tests, acme): fix: update changelog, documentation, examples and tests for v19.4.0 release. Adjust global ACME configuration to use ssl@bleu.de and add non-privileged port examples.
This commit is contained in:
parent
5c6437c5b3
commit
4b381915e1
22
changelog.md
22
changelog.md
@ -1,5 +1,27 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-05-19 - 19.3.4 - fix(docs, tests, acme)
|
||||||
|
fix: update changelog, documentation, examples and tests for v19.4.0 release. Adjust global ACME configuration to use ssl@bleu.de and add non-privileged port examples.
|
||||||
|
|
||||||
|
- Updated changelog with new v19.4.0 entry detailing fixes in tests and docs
|
||||||
|
- Revised README and certificate-management.md to demonstrate global ACME settings (using ssl@bleu.de, non-privileged port support, auto-renewal configuration, and renewCheckIntervalHours)
|
||||||
|
- Added new examples (certificate-management-v19.ts and complete-example-v19.ts) and updated existing examples (dynamic port management, NFTables integration) to reflect v19.4.0 features
|
||||||
|
- Fixed test exports and port mapping issues in several test files (acme-state-manager, port80-management, race-conditions, etc.)
|
||||||
|
- Updated readme.plan.md to reflect completed refactoring and breaking changes from v19.3.3
|
||||||
|
|
||||||
|
## 2025-05-19 - 19.4.0 - fix(tests) & docs
|
||||||
|
Fix failing tests and update documentation for v19+ features
|
||||||
|
|
||||||
|
- Fix ForwardingHandlerFactory.applyDefaults to set port and socket properties correctly
|
||||||
|
- Fix route finding logic in forwarding tests to properly identify redirect routes
|
||||||
|
- Fix test exports in acme-state-manager.node.ts, port80-management.node.ts, and race-conditions.node.ts
|
||||||
|
- Update ACME email configuration to use ssl@bleu.de instead of test domains
|
||||||
|
- Update README with v19.4.0 features including global ACME configuration
|
||||||
|
- Update certificate-management.md documentation to reflect v19+ changes
|
||||||
|
- Add new examples: certificate-management-v19.ts and complete-example-v19.ts
|
||||||
|
- Update existing examples to demonstrate global ACME configuration
|
||||||
|
- Update readme.plan.md to reflect completed refactoring
|
||||||
|
|
||||||
## 2025-05-19 - 19.3.3 - fix(core)
|
## 2025-05-19 - 19.3.3 - fix(core)
|
||||||
No changes detected – project structure and documentation remain unchanged.
|
No changes detected – project structure and documentation remain unchanged.
|
||||||
|
|
||||||
|
@ -208,11 +208,18 @@ const smartproxy = new SmartProxy({
|
|||||||
// Certificate provisioning was automatic or via certProvisionFunction
|
// Certificate provisioning was automatic or via certProvisionFunction
|
||||||
```
|
```
|
||||||
|
|
||||||
### After (v18+)
|
### After (v19+)
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// New approach with route-based configuration
|
// New approach with global ACME configuration
|
||||||
const smartproxy = new SmartProxy({
|
const smartproxy = new SmartProxy({
|
||||||
|
// Global ACME defaults (v19+)
|
||||||
|
acme: {
|
||||||
|
email: 'ssl@bleu.de',
|
||||||
|
useProduction: true,
|
||||||
|
port: 80 // Or 8080 for non-privileged
|
||||||
|
},
|
||||||
|
|
||||||
routes: [{
|
routes: [{
|
||||||
match: { ports: 443, domains: 'example.com' },
|
match: { ports: 443, domains: 'example.com' },
|
||||||
action: {
|
action: {
|
||||||
@ -220,11 +227,7 @@ const smartproxy = new SmartProxy({
|
|||||||
target: { host: 'localhost', port: 8080 },
|
target: { host: 'localhost', port: 8080 },
|
||||||
tls: {
|
tls: {
|
||||||
mode: 'terminate',
|
mode: 'terminate',
|
||||||
certificate: 'auto',
|
certificate: 'auto' // Uses global ACME settings
|
||||||
acme: {
|
|
||||||
email: 'admin@example.com',
|
|
||||||
useProduction: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
@ -235,9 +238,38 @@ const smartproxy = new SmartProxy({
|
|||||||
|
|
||||||
### Common Issues
|
### Common Issues
|
||||||
|
|
||||||
1. **Certificate not provisioning**: Ensure port 80 is accessible for ACME challenges
|
1. **Certificate not provisioning**: Ensure the ACME challenge port (80 or configured port) is accessible
|
||||||
2. **ACME rate limits**: Use staging environment for testing
|
2. **ACME rate limits**: Use staging environment for testing (`useProduction: false`)
|
||||||
3. **Permission errors**: Ensure the certificate directory is writable
|
3. **Permission errors**: Ensure the certificate directory is writable
|
||||||
|
4. **Invalid email domain**: ACME servers may reject certain email domains (e.g., example.com). Use a real email domain
|
||||||
|
5. **Port binding errors**: Use higher ports (e.g., 8080) if running without root privileges
|
||||||
|
|
||||||
|
### Using Non-Privileged Ports
|
||||||
|
|
||||||
|
For development or non-root environments:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const proxy = new SmartProxy({
|
||||||
|
acme: {
|
||||||
|
email: 'ssl@bleu.de',
|
||||||
|
port: 8080, // Use 8080 instead of 80
|
||||||
|
useProduction: false
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
match: { ports: 8443, domains: 'example.com' },
|
||||||
|
action: {
|
||||||
|
type: 'forward',
|
||||||
|
target: { host: 'localhost', port: 3000 },
|
||||||
|
tls: {
|
||||||
|
mode: 'terminate',
|
||||||
|
certificate: 'auto'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### Debug Mode
|
### Debug Mode
|
||||||
|
|
||||||
|
119
examples/certificate-management-v19.ts
Normal file
119
examples/certificate-management-v19.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* Certificate Management Example (v19+)
|
||||||
|
*
|
||||||
|
* This example demonstrates the new global ACME configuration introduced in v19+
|
||||||
|
* along with route-level overrides for specific domains.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
SmartProxy,
|
||||||
|
createHttpRoute,
|
||||||
|
createHttpsTerminateRoute,
|
||||||
|
createCompleteHttpsServer
|
||||||
|
} from '../dist_ts/index.js';
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Create a SmartProxy instance with global ACME configuration
|
||||||
|
const proxy = new SmartProxy({
|
||||||
|
// Global ACME configuration (v19+)
|
||||||
|
// These settings apply to all routes with certificate: 'auto'
|
||||||
|
acme: {
|
||||||
|
email: 'ssl@bleu.de', // Global contact email
|
||||||
|
useProduction: false, // Use staging by default
|
||||||
|
port: 8080, // Use non-privileged port
|
||||||
|
renewThresholdDays: 30, // Renew 30 days before expiry
|
||||||
|
autoRenew: true, // Enable automatic renewal
|
||||||
|
renewCheckIntervalHours: 12 // Check twice daily
|
||||||
|
},
|
||||||
|
|
||||||
|
routes: [
|
||||||
|
// Route that uses global ACME settings
|
||||||
|
createHttpsTerminateRoute('app.example.com',
|
||||||
|
{ host: 'localhost', port: 3000 },
|
||||||
|
{ certificate: 'auto' } // Uses global ACME configuration
|
||||||
|
),
|
||||||
|
|
||||||
|
// Route with route-level ACME override
|
||||||
|
{
|
||||||
|
name: 'production-api',
|
||||||
|
match: { ports: 443, domains: 'api.example.com' },
|
||||||
|
action: {
|
||||||
|
type: 'forward',
|
||||||
|
target: { host: 'localhost', port: 3001 },
|
||||||
|
tls: {
|
||||||
|
mode: 'terminate',
|
||||||
|
certificate: 'auto',
|
||||||
|
acme: {
|
||||||
|
email: 'api-certs@example.com', // Override email
|
||||||
|
useProduction: true, // Use production for API
|
||||||
|
renewThresholdDays: 60 // Earlier renewal for critical API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Complete HTTPS server with automatic redirects
|
||||||
|
...createCompleteHttpsServer('website.example.com',
|
||||||
|
{ host: 'localhost', port: 8080 },
|
||||||
|
{ certificate: 'auto' }
|
||||||
|
),
|
||||||
|
|
||||||
|
// Static certificate (not using ACME)
|
||||||
|
{
|
||||||
|
name: 'internal-service',
|
||||||
|
match: { ports: 8443, domains: 'internal.local' },
|
||||||
|
action: {
|
||||||
|
type: 'forward',
|
||||||
|
target: { host: 'localhost', port: 3002 },
|
||||||
|
tls: {
|
||||||
|
mode: 'terminate',
|
||||||
|
certificate: {
|
||||||
|
cert: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
|
||||||
|
key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Monitor certificate events
|
||||||
|
proxy.on('certificate:issued', (event) => {
|
||||||
|
console.log(`Certificate issued for ${event.domain}`);
|
||||||
|
console.log(`Expires: ${event.expiryDate}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
proxy.on('certificate:renewed', (event) => {
|
||||||
|
console.log(`Certificate renewed for ${event.domain}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
proxy.on('certificate:error', (event) => {
|
||||||
|
console.error(`Certificate error for ${event.domain}: ${event.error}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start the proxy
|
||||||
|
await proxy.start();
|
||||||
|
console.log('SmartProxy started with global ACME configuration');
|
||||||
|
|
||||||
|
// Check certificate status programmatically
|
||||||
|
setTimeout(async () => {
|
||||||
|
// Get status for a specific route
|
||||||
|
const status = proxy.getCertificateStatus('app-route');
|
||||||
|
console.log('Certificate status:', status);
|
||||||
|
|
||||||
|
// Manually trigger renewal if needed
|
||||||
|
if (status && status.status === 'expiring') {
|
||||||
|
await proxy.renewCertificate('app-route');
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
|
// Handle shutdown gracefully
|
||||||
|
process.on('SIGINT', async () => {
|
||||||
|
console.log('Shutting down proxy...');
|
||||||
|
await proxy.stop();
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the example
|
||||||
|
main().catch(console.error);
|
188
examples/complete-example-v19.ts
Normal file
188
examples/complete-example-v19.ts
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
});
|
@ -3,27 +3,25 @@
|
|||||||
*
|
*
|
||||||
* This example demonstrates how to dynamically add and remove ports
|
* This example demonstrates how to dynamically add and remove ports
|
||||||
* while SmartProxy is running, without requiring a restart.
|
* while SmartProxy is running, without requiring a restart.
|
||||||
|
* Also shows the new v19+ global ACME configuration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SmartProxy } from '../dist_ts/index.js';
|
import { SmartProxy, createHttpRoute, createHttpsTerminateRoute } from '../dist_ts/index.js';
|
||||||
import type { IRouteConfig } from '../dist_ts/index.js';
|
import type { IRouteConfig } from '../dist_ts/index.js';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// Create a SmartProxy instance with initial routes
|
// Create a SmartProxy instance with initial routes and global ACME config
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
|
// Global ACME configuration (v19+)
|
||||||
|
acme: {
|
||||||
|
email: 'ssl@bleu.de',
|
||||||
|
useProduction: false,
|
||||||
|
port: 8080 // Using non-privileged port for ACME challenges
|
||||||
|
},
|
||||||
|
|
||||||
routes: [
|
routes: [
|
||||||
// Initial route on port 8080
|
// Initial route on port 8080
|
||||||
{
|
createHttpRoute(['example.com', '*.example.com'], { host: 'localhost', port: 3000 })
|
||||||
match: {
|
|
||||||
ports: 8080,
|
|
||||||
domains: ['example.com', '*.example.com']
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: 'forward',
|
|
||||||
target: { host: 'localhost', port: 3000 }
|
|
||||||
},
|
|
||||||
name: 'Initial HTTP Route'
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* for high-performance network routing that operates at the kernel level.
|
* for high-performance network routing that operates at the kernel level.
|
||||||
*
|
*
|
||||||
* NOTE: This requires elevated privileges to run (sudo) as it interacts with nftables.
|
* NOTE: This requires elevated privileges to run (sudo) as it interacts with nftables.
|
||||||
|
* Also shows the new v19+ global ACME configuration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
|
import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
|
||||||
@ -50,15 +51,22 @@ async function simpleForwardingExample() {
|
|||||||
async function httpsTerminationExample() {
|
async function httpsTerminationExample() {
|
||||||
console.log('Starting HTTPS termination with NFTables example...');
|
console.log('Starting HTTPS termination with NFTables example...');
|
||||||
|
|
||||||
// Create a SmartProxy instance with an HTTPS termination route using NFTables
|
// Create a SmartProxy instance with global ACME and NFTables HTTPS termination
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
|
// Global ACME configuration (v19+)
|
||||||
|
acme: {
|
||||||
|
email: 'ssl@bleu.de',
|
||||||
|
useProduction: false,
|
||||||
|
port: 80 // NFTables needs root, so we can use port 80
|
||||||
|
},
|
||||||
|
|
||||||
routes: [
|
routes: [
|
||||||
createNfTablesTerminateRoute('secure.example.com', {
|
createNfTablesTerminateRoute('secure.example.com', {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 8443
|
port: 8443
|
||||||
}, {
|
}, {
|
||||||
ports: 443,
|
ports: 443,
|
||||||
certificate: 'auto', // Automatic certificate provisioning
|
certificate: 'auto', // Uses global ACME configuration
|
||||||
tableName: 'smartproxy_https'
|
tableName: 'smartproxy_https'
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
29
readme.md
29
readme.md
@ -113,7 +113,7 @@ npm install @push.rocks/smartproxy
|
|||||||
|
|
||||||
## Quick Start with SmartProxy
|
## Quick Start with SmartProxy
|
||||||
|
|
||||||
SmartProxy v18.0.0 continues the evolution of the unified route-based configuration system making your proxy setup more flexible and intuitive with improved helper functions and NFTables integration for high-performance kernel-level routing.
|
SmartProxy v19.4.0 provides a unified route-based configuration system with enhanced certificate management, NFTables integration for high-performance kernel-level routing, and improved helper functions for common proxy setups.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import {
|
import {
|
||||||
@ -136,10 +136,12 @@ import {
|
|||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
// Global ACME settings for all routes with certificate: 'auto'
|
// Global ACME settings for all routes with certificate: 'auto'
|
||||||
acme: {
|
acme: {
|
||||||
email: 'ssl@example.com', // Required for Let's Encrypt
|
email: 'ssl@bleu.de', // Required for Let's Encrypt
|
||||||
useProduction: false, // Use staging by default
|
useProduction: false, // Use staging by default
|
||||||
renewThresholdDays: 30, // Renew 30 days before expiry
|
renewThresholdDays: 30, // Renew 30 days before expiry
|
||||||
port: 80 // Port for HTTP-01 challenges
|
port: 80, // Port for HTTP-01 challenges (use 8080 for non-privileged)
|
||||||
|
autoRenew: true, // Enable automatic renewal
|
||||||
|
renewCheckIntervalHours: 24 // Check for renewals daily
|
||||||
},
|
},
|
||||||
|
|
||||||
// Define all your routing rules in a single array
|
// Define all your routing rules in a single array
|
||||||
@ -216,26 +218,7 @@ const proxy = new SmartProxy({
|
|||||||
certificate: 'auto',
|
certificate: 'auto',
|
||||||
maxRate: '100mbps'
|
maxRate: '100mbps'
|
||||||
})
|
})
|
||||||
],
|
]
|
||||||
|
|
||||||
// Global settings that apply to all routes
|
|
||||||
defaults: {
|
|
||||||
security: {
|
|
||||||
maxConnections: 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Automatic Let's Encrypt integration
|
|
||||||
acme: {
|
|
||||||
enabled: true,
|
|
||||||
contactEmail: 'admin@example.com',
|
|
||||||
useProduction: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for certificate events
|
|
||||||
proxy.on('certificate', evt => {
|
|
||||||
console.log(`Certificate for ${evt.domain} ready, expires: ${evt.expiryDate}`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start the proxy
|
// Start the proxy
|
||||||
|
@ -1,22 +1,15 @@
|
|||||||
# SmartProxy Architecture Refactoring Plan
|
# SmartProxy v19.4.0 - Completed Refactoring
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Refactor the proxy architecture to provide clearer separation of concerns between HTTP/HTTPS traffic handling and low-level connection routing.
|
SmartProxy has been successfully refactored with clearer separation of concerns between HTTP/HTTPS traffic handling and low-level connection routing. Version 19.4.0 introduces global ACME configuration and enhanced route management.
|
||||||
|
|
||||||
## Current Architecture Problems
|
## Current Architecture (v19.4.0)
|
||||||
|
|
||||||
1. NetworkProxy name doesn't clearly indicate it handles HTTP/HTTPS
|
### HttpProxy (formerly NetworkProxy)
|
||||||
2. HTTP parsing logic is duplicated in RouteConnectionHandler
|
|
||||||
3. Redirect and static route handling is embedded in SmartProxy
|
|
||||||
4. Unclear separation between TCP routing and HTTP processing
|
|
||||||
|
|
||||||
## Proposed Architecture
|
|
||||||
|
|
||||||
### HttpProxy (renamed from NetworkProxy)
|
|
||||||
**Purpose**: Handle all HTTP/HTTPS traffic with TLS termination
|
**Purpose**: Handle all HTTP/HTTPS traffic with TLS termination
|
||||||
|
|
||||||
**Responsibilities**:
|
**Current Responsibilities**:
|
||||||
- TLS termination for HTTPS
|
- TLS termination for HTTPS
|
||||||
- HTTP/1.1 and HTTP/2 protocol handling
|
- HTTP/1.1 and HTTP/2 protocol handling
|
||||||
- HTTP request/response parsing
|
- HTTP request/response parsing
|
||||||
@ -25,29 +18,33 @@ Refactor the proxy architecture to provide clearer separation of concerns betwee
|
|||||||
- Static route handlers
|
- Static route handlers
|
||||||
- WebSocket protocol upgrades
|
- WebSocket protocol upgrades
|
||||||
- Connection pooling for backend servers
|
- Connection pooling for backend servers
|
||||||
- Certificate management (ACME and static)
|
- Certificate management integration
|
||||||
|
|
||||||
### SmartProxy
|
### SmartProxy
|
||||||
**Purpose**: Low-level connection router and port manager
|
**Purpose**: Central API for all proxy needs with route-based configuration
|
||||||
|
|
||||||
**Responsibilities**:
|
**Current Responsibilities**:
|
||||||
- Port management (listen on multiple ports)
|
- Port management (listen on multiple ports)
|
||||||
- Route-based connection routing
|
- Route-based connection routing
|
||||||
- TLS passthrough (SNI-based routing)
|
- TLS passthrough (SNI-based routing)
|
||||||
- NFTables integration
|
- NFTables integration
|
||||||
- Delegate HTTP/HTTPS connections to HttpProxy
|
- Certificate management via SmartCertManager
|
||||||
- Raw TCP proxying
|
- Raw TCP proxying
|
||||||
- Connection lifecycle management
|
- Connection lifecycle management
|
||||||
|
- Global ACME configuration (v19+)
|
||||||
|
|
||||||
## Implementation Plan
|
## Completed Implementation
|
||||||
|
|
||||||
### Phase 1: Rename and Reorganize NetworkProxy ✅
|
### Phase 1: Rename and Reorganize ✅
|
||||||
|
- NetworkProxy renamed to HttpProxy
|
||||||
|
- Directory structure reorganized
|
||||||
|
- All imports and references updated
|
||||||
|
|
||||||
1. **Rename NetworkProxy to HttpProxy**
|
### Phase 2: Certificate Management ✅
|
||||||
- Renamed directory from `network-proxy` to `http-proxy`
|
- Unified certificate management in SmartCertManager
|
||||||
- Updated all imports and references
|
- Global ACME configuration support (v19+)
|
||||||
|
- Route-level certificate overrides
|
||||||
2. **Update class and file names**
|
- Automatic renewal system
|
||||||
- Renamed `network-proxy.ts` to `http-proxy.ts`
|
- Renamed `network-proxy.ts` to `http-proxy.ts`
|
||||||
- Updated `NetworkProxy` class to `HttpProxy` class
|
- Updated `NetworkProxy` class to `HttpProxy` class
|
||||||
- Updated all type definitions and interfaces
|
- Updated all type definitions and interfaces
|
||||||
@ -157,16 +154,26 @@ After this refactoring, we can more easily add:
|
|||||||
4. Protocol-specific optimizations
|
4. Protocol-specific optimizations
|
||||||
5. Better HTTP/2 multiplexing
|
5. Better HTTP/2 multiplexing
|
||||||
|
|
||||||
## Breaking Changes
|
## Breaking Changes from v18 to v19
|
||||||
|
|
||||||
1. `NetworkProxy` class renamed to `HttpProxy`
|
1. `NetworkProxy` class renamed to `HttpProxy`
|
||||||
2. Import paths change from `network-proxy` to `http-proxy`
|
2. Import paths change from `network-proxy` to `http-proxy`
|
||||||
3. Some type names may change for consistency
|
3. Global ACME configuration now available at the top level
|
||||||
|
4. Certificate management unified under SmartCertManager
|
||||||
|
|
||||||
## Rollback Plan
|
## Future Enhancements
|
||||||
|
|
||||||
If issues arise:
|
1. HTTP/3 (QUIC) support in HttpProxy
|
||||||
1. Git revert to previous commit
|
2. Advanced HTTP features (compression, caching)
|
||||||
2. Re-deploy previous version
|
3. HTTP middleware system
|
||||||
3. Document lessons learned
|
4. Protocol-specific optimizations
|
||||||
4. Plan incremental changes
|
5. Better HTTP/2 multiplexing
|
||||||
|
6. Enhanced monitoring and metrics
|
||||||
|
|
||||||
|
## Key Features in v19.4.0
|
||||||
|
|
||||||
|
1. **Global ACME Configuration**: Default settings for all routes with `certificate: 'auto'`
|
||||||
|
2. **Enhanced Route Management**: Better separation between routing and certificate management
|
||||||
|
3. **Improved Test Coverage**: Fixed test exports and port bindings
|
||||||
|
4. **Better Error Messages**: Clear guidance for ACME configuration issues
|
||||||
|
5. **Non-Privileged Port Support**: Examples for development environments
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartproxy',
|
name: '@push.rocks/smartproxy',
|
||||||
version: '19.3.3',
|
version: '19.3.4',
|
||||||
description: 'A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.'
|
description: 'A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.'
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user