feat(certs): integrate smartacme v9 for ACME certificate provisioning and add certificate management features, docs, dashboard views, API endpoints, and per-domain backoff scheduler
This commit is contained in:
102
readme.md
102
readme.md
@@ -21,6 +21,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
||||
- [Email System](#email-system)
|
||||
- [DNS Server](#dns-server)
|
||||
- [RADIUS Server](#radius-server)
|
||||
- [Certificate Management](#certificate-management)
|
||||
- [Storage & Caching](#storage--caching)
|
||||
- [Security Features](#security-features)
|
||||
- [OpsServer Dashboard](#opsserver-dashboard)
|
||||
@@ -46,7 +47,9 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
||||
- **Hierarchical rate limiting** — global, per-domain, per-sender
|
||||
|
||||
### 🔒 Enterprise Security
|
||||
- **Automatic TLS certificates** via ACME with Cloudflare DNS-01 challenges
|
||||
- **Automatic TLS certificates** via ACME (smartacme v9) with Cloudflare DNS-01 challenges
|
||||
- **Smart certificate scheduling** — per-domain deduplication, controlled parallelism, and account rate limiting handled automatically
|
||||
- **Per-domain exponential backoff** — failed provisioning attempts are tracked and backed off to avoid hammering ACME servers
|
||||
- **IP reputation checking** with caching and configurable thresholds
|
||||
- **Content scanning** for spam, viruses, and malicious attachments
|
||||
- **Security event logging** with structured audit trails
|
||||
@@ -73,7 +76,8 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
||||
### 🖥️ OpsServer Dashboard
|
||||
- **Web-based management interface** with real-time monitoring
|
||||
- **JWT authentication** with session persistence
|
||||
- **Live views** for connections, email queues, DNS queries, RADIUS sessions, and security events
|
||||
- **Live views** for connections, email queues, DNS queries, RADIUS sessions, certificates, and security events
|
||||
- **Domain-centric certificate overview** with backoff status and one-click reprovisioning
|
||||
- **Read-only configuration display** — DcRouter is configured through code
|
||||
|
||||
## Installation
|
||||
@@ -250,7 +254,7 @@ graph TB
|
||||
ES[smartmta Email Server<br/><i>TypeScript + Rust</i>]
|
||||
DS[SmartDNS Server<br/><i>Rust-powered</i>]
|
||||
RS[SmartRadius Server]
|
||||
CM[Certificate Manager]
|
||||
CM[Certificate Manager<br/><i>smartacme v9</i>]
|
||||
OS[OpsServer Dashboard]
|
||||
MM[Metrics Manager]
|
||||
SM[Storage Manager]
|
||||
@@ -297,6 +301,7 @@ graph TB
|
||||
| **SmartProxy** | `@push.rocks/smartproxy` | High-performance HTTP/HTTPS and TCP/SNI proxy with route-based config (Rust engine) |
|
||||
| **UnifiedEmailServer** | `@push.rocks/smartmta` | Full SMTP server with pattern-based routing, DKIM, queue management (TypeScript + Rust) |
|
||||
| **DNS Server** | `@push.rocks/smartdns` | Authoritative DNS with dynamic records and DKIM TXT auto-generation (Rust engine) |
|
||||
| **SmartAcme** | `@push.rocks/smartacme` | ACME certificate management with per-domain dedup, concurrency control, and rate limiting |
|
||||
| **RADIUS Server** | `@push.rocks/smartradius` | Network authentication with MAB, VLAN assignment, and accounting |
|
||||
| **OpsServer** | `@api.global/typedserver` | Web dashboard + TypedRequest API for monitoring and management |
|
||||
| **MetricsManager** | `@push.rocks/smartmetrics` | Real-time metrics collection (CPU, memory, email, DNS, security) |
|
||||
@@ -308,8 +313,8 @@ graph TB
|
||||
DcRouter acts purely as an **orchestrator** — it doesn't implement protocols itself. Instead, it wires together best-in-class packages for each protocol:
|
||||
|
||||
1. **On `start()`**: DcRouter initializes OpsServer (port 3000), then spins up SmartProxy, smartmta, SmartDNS, and SmartRadius based on which configs are provided.
|
||||
2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery.
|
||||
3. **On `stop()`**: All services are gracefully shut down in reverse order.
|
||||
2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery. SmartAcme v9 handles all certificate operations with built-in concurrency control and rate limiting.
|
||||
3. **On `stop()`**: All services are gracefully shut down in parallel, including cleanup of HTTP agents and DNS clients.
|
||||
|
||||
### Rust-Powered Architecture
|
||||
|
||||
@@ -584,15 +589,6 @@ match: { sizeRange: { min: 1000, max: 5000000 }, hasAttachments: true }
|
||||
match: { subject: /invoice|receipt/i }
|
||||
```
|
||||
|
||||
### Socket-Handler Mode 🔌
|
||||
|
||||
When `useSocketHandler: true` is set, SmartProxy passes sockets directly to the email server — no internal port binding, lower latency, and fewer open ports:
|
||||
|
||||
```
|
||||
Traditional: External Port → SmartProxy → Internal Port → Email Server
|
||||
Socket Mode: External Port → SmartProxy → (direct socket) → Email Server
|
||||
```
|
||||
|
||||
### Email Security Stack
|
||||
|
||||
- **DKIM** — Automatic key generation, signing, and rotation for all domains
|
||||
@@ -705,6 +701,73 @@ RADIUS is fully manageable at runtime via the OpsServer API:
|
||||
- Session monitoring and forced disconnects
|
||||
- Accounting summaries and statistics
|
||||
|
||||
## Certificate Management
|
||||
|
||||
DcRouter uses [`@push.rocks/smartacme`](https://code.foss.global/push.rocks/smartacme) v9 for ACME certificate provisioning. smartacme v9 brings significant improvements over previous versions:
|
||||
|
||||
### How It Works
|
||||
|
||||
When a `dnsChallenge` is configured (e.g. with a Cloudflare API key), DcRouter creates a SmartAcme instance that handles DNS-01 challenges for automatic certificate provisioning. SmartProxy calls the `certProvisionFunction` whenever a route needs a TLS certificate, and SmartAcme takes care of the rest.
|
||||
|
||||
```typescript
|
||||
const router = new DcRouter({
|
||||
smartProxyConfig: {
|
||||
routes: [
|
||||
{
|
||||
name: 'secure-app',
|
||||
match: { domains: ['app.example.com'], ports: [443] },
|
||||
action: {
|
||||
type: 'forward',
|
||||
targets: [{ host: '192.168.1.10', port: 8080 }],
|
||||
tls: { mode: 'terminate', certificate: 'auto' } // ← triggers ACME provisioning
|
||||
}
|
||||
}
|
||||
],
|
||||
acme: { email: 'admin@example.com', enabled: true, useProduction: true }
|
||||
},
|
||||
tls: { contactEmail: 'admin@example.com' },
|
||||
dnsChallenge: { cloudflareApiKey: process.env.CLOUDFLARE_API_KEY }
|
||||
});
|
||||
```
|
||||
|
||||
### smartacme v9 Features
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Per-domain deduplication** | Concurrent requests for the same domain share a single ACME operation |
|
||||
| **Global concurrency cap** | Default 5 parallel ACME operations to prevent overload |
|
||||
| **Account rate limiting** | Sliding window (250 orders / 3 hours) to stay within ACME provider limits |
|
||||
| **Structured errors** | `AcmeError` with `isRetryable`, `isRateLimited`, `retryAfter` fields |
|
||||
| **Clean shutdown** | `stop()` properly destroys HTTP agents and DNS clients |
|
||||
|
||||
### Per-Domain Backoff
|
||||
|
||||
DcRouter's `CertProvisionScheduler` adds **per-domain exponential backoff** on top of smartacme's built-in protections. If a DNS-01 challenge fails for a domain:
|
||||
|
||||
1. The failure is recorded (persisted to storage)
|
||||
2. The domain enters backoff: `min(failures² × 1 hour, 24 hours)`
|
||||
3. Subsequent requests for that domain are rejected until the backoff expires
|
||||
4. On success, the backoff is cleared
|
||||
|
||||
This prevents hammering ACME servers for domains with persistent issues (e.g. missing DNS delegation).
|
||||
|
||||
### Fallback to HTTP-01
|
||||
|
||||
If DNS-01 fails, the `certProvisionFunction` returns `'http01'` to tell SmartProxy to fall back to HTTP-01 challenge validation. This provides a safety net for domains where DNS-01 isn't viable.
|
||||
|
||||
### Certificate Storage
|
||||
|
||||
Certificates are persisted via the `StorageBackedCertManager` which uses DcRouter's `StorageManager`. This means certs survive restarts and don't need to be re-provisioned unless they expire.
|
||||
|
||||
### Dashboard
|
||||
|
||||
The OpsServer includes a **Certificates** view showing:
|
||||
- All domains with their certificate status (valid, expiring, expired, failed)
|
||||
- Certificate source (ACME, provision function, static)
|
||||
- Expiry dates and issuer information
|
||||
- Backoff status for failed domains
|
||||
- One-click reprovisioning per domain
|
||||
|
||||
## Storage & Caching
|
||||
|
||||
### StorageManager
|
||||
@@ -725,7 +788,7 @@ storage: {
|
||||
// Simply omit the storage config
|
||||
```
|
||||
|
||||
Used for: DKIM keys, email routes, bounce/suppression lists, IP reputation data, domain configs.
|
||||
Used for: TLS certificates, DKIM keys, email routes, bounce/suppression lists, IP reputation data, domain configs, cert backoff state.
|
||||
|
||||
### Cache Database
|
||||
|
||||
@@ -811,6 +874,7 @@ The OpsServer provides a web-based management interface served on port 3000. It'
|
||||
| 📊 **Overview** | Real-time server stats, CPU/memory, connection counts, email throughput |
|
||||
| 🌐 **Network** | Active connections, top IPs, throughput rates, SmartProxy metrics |
|
||||
| 📧 **Email** | Queue monitoring (queued/sent/failed), bounce records, security incidents |
|
||||
| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning |
|
||||
| 📜 **Logs** | Real-time log viewer with level filtering and search |
|
||||
| ⚙️ **Configuration** | Read-only view of current system configuration |
|
||||
| 🛡️ **Security** | IP reputation, rate limit status, blocked connections |
|
||||
@@ -838,6 +902,11 @@ All management is done via TypedRequest over HTTP POST to `/typedrequest`:
|
||||
'getBounceRecords' // Bounce records
|
||||
'removeFromSuppressionList' // Unsuppress an address
|
||||
|
||||
// Certificates
|
||||
'getCertificateOverview' // Domain-centric certificate status
|
||||
'reprovisionCertificate' // Reprovision by route name (legacy)
|
||||
'reprovisionCertificateDomain' // Reprovision by domain (preferred)
|
||||
|
||||
// Configuration (read-only)
|
||||
'getConfiguration' // Current system config
|
||||
|
||||
@@ -884,6 +953,7 @@ const router = new DcRouter(options: IDcRouterOptions);
|
||||
|----------|------|-------------|
|
||||
| `options` | `IDcRouterOptions` | Current configuration |
|
||||
| `smartProxy` | `SmartProxy` | SmartProxy instance |
|
||||
| `smartAcme` | `SmartAcme` | SmartAcme v9 certificate manager instance |
|
||||
| `emailServer` | `UnifiedEmailServer` | Email server instance (from smartmta) |
|
||||
| `dnsServer` | `DnsServer` | DNS server instance |
|
||||
| `radiusServer` | `RadiusServer` | RADIUS server instance |
|
||||
@@ -891,6 +961,8 @@ const router = new DcRouter(options: IDcRouterOptions);
|
||||
| `opsServer` | `OpsServer` | OpsServer/dashboard instance |
|
||||
| `metricsManager` | `MetricsManager` | Metrics collector |
|
||||
| `cacheDb` | `CacheDb` | Cache database instance |
|
||||
| `certProvisionScheduler` | `CertProvisionScheduler` | Per-domain backoff scheduler for cert provisioning |
|
||||
| `certificateStatusMap` | `Map<string, ...>` | Domain-keyed certificate status from SmartProxy events |
|
||||
|
||||
### Re-exported Types
|
||||
|
||||
|
||||
Reference in New Issue
Block a user