|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
# @push.rocks/smartmta
|
|
|
|
|
|
|
|
|
|
A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration — no nodemailer, no shortcuts.
|
|
|
|
|
A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with a Rust-powered SMTP engine — no nodemailer, no shortcuts. 🚀
|
|
|
|
|
|
|
|
|
|
## Issue Reporting and Security
|
|
|
|
|
|
|
|
|
|
@@ -14,68 +14,83 @@ pnpm install @push.rocks/smartmta
|
|
|
|
|
npm install @push.rocks/smartmta
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
After installation, run `pnpm build` to compile the Rust binary (`mailer-bin`). The Rust binary is **required** — `smartmta` will not start without it.
|
|
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
|
|
|
|
|
`@push.rocks/smartmta` is a **complete mail server solution** — SMTP server, SMTP client, email security, content scanning, and delivery management — all built with a custom SMTP implementation. No wrappers around nodemailer. No half-measures.
|
|
|
|
|
`@push.rocks/smartmta` is a **complete mail server solution** — SMTP server, SMTP client, email security, content scanning, and delivery management — all built with a custom SMTP implementation. The SMTP server itself runs as a Rust binary for maximum performance, communicating with the TypeScript orchestration layer via IPC.
|
|
|
|
|
|
|
|
|
|
### What's Inside
|
|
|
|
|
### ⚡ What's Inside
|
|
|
|
|
|
|
|
|
|
| Module | What It Does |
|
|
|
|
|
|---|---|
|
|
|
|
|
| **SMTP Server** | RFC 5321-compliant server with TLS/STARTTLS, authentication, pipelining |
|
|
|
|
|
| **Rust SMTP Server** | High-performance SMTP engine written in Rust — TCP/TLS listener, STARTTLS, AUTH, pipelining, per-connection rate limiting |
|
|
|
|
|
| **SMTP Client** | Outbound delivery with connection pooling, retry logic, TLS negotiation |
|
|
|
|
|
| **DKIM** | Key generation, signing, and verification — per domain |
|
|
|
|
|
| **SPF** | Full SPF record validation |
|
|
|
|
|
| **DKIM** | Key generation, signing, and verification — per domain, with automatic rotation |
|
|
|
|
|
| **SPF** | Full SPF record validation via Rust |
|
|
|
|
|
| **DMARC** | Policy enforcement and verification |
|
|
|
|
|
| **Email Router** | Pattern-based routing with priority, forward/deliver/reject/process actions |
|
|
|
|
|
| **Bounce Manager** | Automatic bounce detection, classification (hard/soft), and tracking |
|
|
|
|
|
| **Content Scanner** | Spam, phishing, malware, XSS, and suspicious link detection |
|
|
|
|
|
| **IP Reputation** | DNSBL checks, proxy/TOR/VPN detection, risk scoring |
|
|
|
|
|
| **Bounce Manager** | Automatic bounce detection via Rust, classification (hard/soft), and suppression tracking |
|
|
|
|
|
| **Content Scanner** | Spam, phishing, malware, XSS, and suspicious link detection — powered by Rust |
|
|
|
|
|
| **IP Reputation** | DNSBL checks, proxy/TOR/VPN detection, risk scoring via Rust |
|
|
|
|
|
| **Rate Limiter** | Hierarchical rate limiting (global, per-domain, per-IP) |
|
|
|
|
|
| **Delivery Queue** | Persistent queue with exponential backoff retry |
|
|
|
|
|
| **Template Engine** | Email templates with variable substitution |
|
|
|
|
|
| **Domain Registry** | Multi-domain management with per-domain configuration |
|
|
|
|
|
| **DNS Manager** | Automatic DNS record management with Cloudflare API integration |
|
|
|
|
|
| **Rust Accelerator** | Performance-critical operations (DKIM, MIME, validation) in Rust via IPC |
|
|
|
|
|
| **Rust Security Bridge** | Compound email security verification (DKIM+SPF+DMARC) via Rust binary |
|
|
|
|
|
| **Rust Security Bridge** | All security ops (DKIM+SPF+DMARC+DNSBL+content scanning) run in Rust via IPC |
|
|
|
|
|
|
|
|
|
|
### Architecture
|
|
|
|
|
### 🏗️ Architecture
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌─────────────────────────────────────────────────────────┐
|
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ UnifiedEmailServer │
|
|
|
|
|
│ (orchestrates all components, emits events) │
|
|
|
|
|
├──────────┬──────────┬────────────┬──────────────────────┤
|
|
|
|
|
│ SMTP │ Email │ Security │ Delivery │
|
|
|
|
|
│ Server │ Router │ Stack │ System │
|
|
|
|
|
│ ┌─────┐ │ ┌─────┐ │ ┌───────┐ │ ┌────────────────┐ │
|
|
|
|
|
│ │ TLS │ │ │Match│ │ │ DKIM │ │ │ Queue │ │
|
|
|
|
|
│ │ Auth│ │ │Route│ │ │ SPF │ │ │ Rate Limit │ │
|
|
|
|
|
│ │ Cmd │ │ │ Act │ │ │ DMARC │ │ │ SMTP Client │ │
|
|
|
|
|
│ │ Data│ │ │ │ │ │ IPRep │ │ │ Retry Logic │ │
|
|
|
|
|
│ └─────┘ │ └─────┘ │ │ Scan │ │ └────────────────┘ │
|
|
|
|
|
│ │ │ └───────┘ │ │
|
|
|
|
|
├──────────┴──────────┴────────────┴──────────────────────┤
|
|
|
|
|
│ Rust Security Bridge │
|
|
|
|
|
│ (RustSecurityBridge singleton via smartrust IPC) │
|
|
|
|
|
├─────────────────────────────────────────────────────────┤
|
|
|
|
|
├───────────┬───────────┬──────────────┬───────────────────────┤
|
|
|
|
|
│ Email │ Security │ Delivery │ Configuration │
|
|
|
|
|
│ Router │ Stack │ System │ │
|
|
|
|
|
│ ┌──────┐ │ ┌───────┐ │ ┌──────────┐ │ ┌────────────────┐ │
|
|
|
|
|
│ │Match │ │ │ DKIM │ │ │ Queue │ │ │ DomainRegistry │ │
|
|
|
|
|
│ │Route │ │ │ SPF │ │ │ Rate Lim │ │ │ DnsManager │ │
|
|
|
|
|
│ │ Act │ │ │ DMARC │ │ │ SMTP Cli │ │ │ DKIMCreator │ │
|
|
|
|
|
│ └──────┘ │ │ IPRep │ │ │ Retry │ │ │ Templates │ │
|
|
|
|
|
│ │ │ Scan │ │ └──────────┘ │ └────────────────┘ │
|
|
|
|
|
│ │ └───────┘ │ │ │
|
|
|
|
|
├───────────┴───────────┴──────────────┴───────────────────────┤
|
|
|
|
|
│ Rust Security Bridge (smartrust IPC) │
|
|
|
|
|
├──────────────────────────────────────────────────────────────┤
|
|
|
|
|
│ Rust Acceleration Layer │
|
|
|
|
|
│ (mailer-core, mailer-security, mailer-bin) │
|
|
|
|
|
└─────────────────────────────────────────────────────────┘
|
|
|
|
|
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────────┐ │
|
|
|
|
|
│ │ mailer-smtp │ │mailer-security│ │ mailer-core │ │
|
|
|
|
|
│ │ SMTP Server │ │DKIM/SPF/DMARC │ │ Types/Validation │ │
|
|
|
|
|
│ │ TLS/AUTH │ │IP Rep/Content │ │ MIME/Bounce │ │
|
|
|
|
|
│ └──────────────┘ └───────────────┘ └──────────────────┘ │
|
|
|
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Data flow for inbound mail:**
|
|
|
|
|
|
|
|
|
|
1. Rust SMTP server accepts the connection and handles the SMTP protocol
|
|
|
|
|
2. On `DATA` completion, Rust emits an `emailReceived` event via IPC
|
|
|
|
|
3. TypeScript processes the email (routing, scanning, delivery decisions)
|
|
|
|
|
4. TypeScript sends the processing result back to Rust via IPC
|
|
|
|
|
5. Rust sends the final SMTP response to the client
|
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
### Setting Up the Email Server
|
|
|
|
|
### 🚀 Setting Up the Email Server
|
|
|
|
|
|
|
|
|
|
The central entry point is `UnifiedEmailServer`, which orchestrates SMTP, routing, security, and delivery:
|
|
|
|
|
The central entry point is `UnifiedEmailServer`, which orchestrates the Rust SMTP server, routing, security, and delivery:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { UnifiedEmailServer } from '@push.rocks/smartmta';
|
|
|
|
|
|
|
|
|
|
const emailServer = new UnifiedEmailServer(dcRouterRef, {
|
|
|
|
|
// Ports to listen on (465 = implicit TLS, 25/587 = STARTTLS)
|
|
|
|
|
ports: [25, 587, 465],
|
|
|
|
|
hostname: 'mail.example.com',
|
|
|
|
|
|
|
|
|
|
// Multi-domain configuration
|
|
|
|
|
domains: [
|
|
|
|
|
{
|
|
|
|
|
domain: 'example.com',
|
|
|
|
|
@@ -87,11 +102,13 @@ const emailServer = new UnifiedEmailServer(dcRouterRef, {
|
|
|
|
|
rotationInterval: 90,
|
|
|
|
|
},
|
|
|
|
|
rateLimits: {
|
|
|
|
|
maxMessagesPerMinute: 100,
|
|
|
|
|
maxRecipientsPerMessage: 50,
|
|
|
|
|
outbound: { messagesPerMinute: 100 },
|
|
|
|
|
inbound: { messagesPerMinute: 200, connectionsPerIp: 20 },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// Routing rules (evaluated by priority, highest first)
|
|
|
|
|
routes: [
|
|
|
|
|
{
|
|
|
|
|
name: 'catch-all-forward',
|
|
|
|
|
@@ -122,31 +139,39 @@ const emailServer = new UnifiedEmailServer(dcRouterRef, {
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// Authentication settings for the SMTP server
|
|
|
|
|
auth: {
|
|
|
|
|
required: false,
|
|
|
|
|
methods: ['PLAIN', 'LOGIN'],
|
|
|
|
|
users: [{ username: 'outbound', password: 'secret' }],
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// TLS certificates
|
|
|
|
|
tls: {
|
|
|
|
|
certPath: '/etc/ssl/mail.crt',
|
|
|
|
|
keyPath: '/etc/ssl/mail.key',
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
maxMessageSize: 25 * 1024 * 1024, // 25 MB
|
|
|
|
|
maxClients: 500,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// start() boots the Rust SMTP server, security bridge, DNS records, and delivery queue
|
|
|
|
|
await emailServer.start();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Sending Emails with the SMTP Client
|
|
|
|
|
> 🔒 **Note:** `start()` will throw if the Rust binary is not compiled. Run `pnpm build` first.
|
|
|
|
|
|
|
|
|
|
### 📧 Sending Emails with the SMTP Client
|
|
|
|
|
|
|
|
|
|
Create and send emails using the built-in SMTP client with connection pooling:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { Email, createSmtpClient } from '@push.rocks/smartmta';
|
|
|
|
|
import { Email, Delivery } from '@push.rocks/smartmta';
|
|
|
|
|
|
|
|
|
|
// Create a client with connection pooling
|
|
|
|
|
const client = createSmtpClient({
|
|
|
|
|
const client = Delivery.smtpClientMod.createSmtpClient({
|
|
|
|
|
host: 'smtp.example.com',
|
|
|
|
|
port: 587,
|
|
|
|
|
secure: false, // will upgrade via STARTTLS
|
|
|
|
|
@@ -181,9 +206,22 @@ const result = await client.sendMail(email);
|
|
|
|
|
console.log(`Message sent: ${result.messageId}`);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### DKIM Signing
|
|
|
|
|
Additional client factories are available:
|
|
|
|
|
|
|
|
|
|
DKIM key management is handled by `DKIMCreator`, which generates, stores, and rotates keys per domain. Signing is performed automatically by `UnifiedEmailServer` during outbound delivery — there is no standalone `signEmail()` call:
|
|
|
|
|
```typescript
|
|
|
|
|
// Pooled client for high-throughput scenarios
|
|
|
|
|
const pooled = Delivery.smtpClientMod.createPooledSmtpClient({ /* ... */ });
|
|
|
|
|
|
|
|
|
|
// Optimized for bulk sending
|
|
|
|
|
const bulk = Delivery.smtpClientMod.createBulkSmtpClient({ /* ... */ });
|
|
|
|
|
|
|
|
|
|
// Optimized for transactional emails
|
|
|
|
|
const transactional = Delivery.smtpClientMod.createTransactionalSmtpClient({ /* ... */ });
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 🔑 DKIM Signing
|
|
|
|
|
|
|
|
|
|
DKIM key management is handled by `DKIMCreator`, which generates, stores, and rotates keys per domain. Signing is performed automatically by `UnifiedEmailServer` during outbound delivery:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { DKIMCreator } from '@push.rocks/smartmta';
|
|
|
|
|
@@ -206,11 +244,11 @@ if (needsRotation) {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When `UnifiedEmailServer.start()` is called, DKIM signing is applied to all outbound mail automatically using the keys managed by `DKIMCreator`. The `RustSecurityBridge` can also perform DKIM signing via its `signDkim()` method for high-performance scenarios.
|
|
|
|
|
When `UnifiedEmailServer.start()` is called, DKIM signing is applied to all outbound mail automatically using the Rust security bridge's `signDkim()` method for maximum performance.
|
|
|
|
|
|
|
|
|
|
### Email Authentication (SPF, DKIM, DMARC)
|
|
|
|
|
### 🛡️ Email Authentication (SPF, DKIM, DMARC)
|
|
|
|
|
|
|
|
|
|
Verify incoming emails against all three authentication standards. Note that the first argument to `SpfVerifier.verify()` and `DmarcVerifier.verify()` is an `Email` object:
|
|
|
|
|
Verify incoming emails against all three authentication standards. All verification is powered by the Rust binary:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { DKIMVerifier, SpfVerifier, DmarcVerifier } from '@push.rocks/smartmta';
|
|
|
|
|
@@ -221,7 +259,7 @@ const spfResult = await spfVerifier.verify(email, senderIP, heloDomain);
|
|
|
|
|
// -> { result: 'pass' | 'fail' | 'softfail' | 'neutral' | 'none' | 'temperror' | 'permerror',
|
|
|
|
|
// domain: string, ip: string }
|
|
|
|
|
|
|
|
|
|
// DKIM verification
|
|
|
|
|
// DKIM verification — takes raw email content
|
|
|
|
|
const dkimVerifier = new DKIMVerifier();
|
|
|
|
|
const dkimResult = await dkimVerifier.verify(rawEmailContent);
|
|
|
|
|
|
|
|
|
|
@@ -232,9 +270,9 @@ const dmarcResult = await dmarcVerifier.verify(email, spfResult, dkimResult);
|
|
|
|
|
// spfDomainAligned: boolean, dkimDomainAligned: boolean, ... }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Email Routing
|
|
|
|
|
### 🔀 Email Routing
|
|
|
|
|
|
|
|
|
|
Pattern-based routing engine with priority ordering and flexible match criteria. Routes are evaluated by priority (highest first) using `evaluateRoutes()`:
|
|
|
|
|
Pattern-based routing engine with priority ordering and flexible match criteria. Routes are evaluated by priority (highest first):
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { EmailRouter } from '@push.rocks/smartmta';
|
|
|
|
|
@@ -288,9 +326,22 @@ const router = new EmailRouter([
|
|
|
|
|
const matchedRoute = await router.evaluateRoutes(emailContext);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Content Scanning
|
|
|
|
|
**Match criteria available:**
|
|
|
|
|
|
|
|
|
|
Built-in content scanner for detecting spam, phishing, malware, and other threats. Use the `scanEmail()` method:
|
|
|
|
|
| Criterion | Description |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `recipients` | Glob patterns for recipient addresses (`*@example.com`) |
|
|
|
|
|
| `senders` | Glob patterns for sender addresses |
|
|
|
|
|
| `clientIp` | IP addresses or CIDR ranges |
|
|
|
|
|
| `authenticated` | Require authentication status |
|
|
|
|
|
| `headers` | Match specific headers (string or RegExp) |
|
|
|
|
|
| `sizeRange` | Message size constraints (`{ min?, max? }`) |
|
|
|
|
|
| `subject` | Subject line pattern (string or RegExp) |
|
|
|
|
|
| `hasAttachments` | Filter by attachment presence |
|
|
|
|
|
|
|
|
|
|
### 🔍 Content Scanning
|
|
|
|
|
|
|
|
|
|
Built-in content scanner for detecting spam, phishing, malware, and other threats. Text pattern scanning runs in Rust for performance; binary attachment scanning (PE headers, VBA macros) runs in TypeScript:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { ContentScanner } from '@push.rocks/smartmta';
|
|
|
|
|
@@ -317,14 +368,14 @@ const result = await scanner.scanEmail(email);
|
|
|
|
|
// -> { isClean: false, threatScore: 85, threatType: 'phishing', scannedElements: [...] }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### IP Reputation Checking
|
|
|
|
|
### 🌐 IP Reputation Checking
|
|
|
|
|
|
|
|
|
|
Check sender IP addresses against DNSBL blacklists and classify IP types:
|
|
|
|
|
Check sender IP addresses against DNSBL blacklists and classify IP types. DNSBL lookups run in Rust:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { IPReputationChecker } from '@push.rocks/smartmta';
|
|
|
|
|
|
|
|
|
|
const ipChecker = new IPReputationChecker({
|
|
|
|
|
const ipChecker = IPReputationChecker.getInstance({
|
|
|
|
|
enableDNSBL: true,
|
|
|
|
|
dnsblServers: ['zen.spamhaus.org', 'bl.spamcop.net'],
|
|
|
|
|
cacheTTL: 24 * 60 * 60 * 1000, // 24 hours
|
|
|
|
|
@@ -334,14 +385,13 @@ const reputation = await ipChecker.checkReputation('192.168.1.1');
|
|
|
|
|
// -> { score: 85, isSpam: false, isProxy: false, isTor: false, blacklists: [] }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When the `RustSecurityBridge` is running, `IPReputationChecker` automatically delegates DNSBL lookups to the Rust binary for improved performance.
|
|
|
|
|
### ⏱️ Rate Limiting
|
|
|
|
|
|
|
|
|
|
### Rate Limiting
|
|
|
|
|
|
|
|
|
|
Hierarchical rate limiting to protect your server and maintain deliverability. Configuration uses `maxMessagesPerMinute` and organizes domain-level limits under the `domains` key:
|
|
|
|
|
Hierarchical rate limiting to protect your server and maintain deliverability:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { UnifiedRateLimiter } from '@push.rocks/smartmta';
|
|
|
|
|
import { Delivery } from '@push.rocks/smartmta';
|
|
|
|
|
const { UnifiedRateLimiter } = Delivery;
|
|
|
|
|
|
|
|
|
|
const rateLimiter = new UnifiedRateLimiter({
|
|
|
|
|
global: {
|
|
|
|
|
@@ -374,12 +424,13 @@ if (!allowed.allowed) {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Bounce Management
|
|
|
|
|
### 📬 Bounce Management
|
|
|
|
|
|
|
|
|
|
Automatic bounce detection, classification, and suppression tracking. Use `isEmailSuppressed()` to check if an address should be suppressed:
|
|
|
|
|
Automatic bounce detection (via Rust), classification, and suppression tracking:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { BounceManager } from '@push.rocks/smartmta';
|
|
|
|
|
import { Core } from '@push.rocks/smartmta';
|
|
|
|
|
const { BounceManager } = Core;
|
|
|
|
|
|
|
|
|
|
const bounceManager = new BounceManager();
|
|
|
|
|
|
|
|
|
|
@@ -399,16 +450,17 @@ bounceManager.addToSuppressionList('bad@example.com', 'repeated hard bounces');
|
|
|
|
|
bounceManager.removeFromSuppressionList('recovered@example.com');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Email Templates
|
|
|
|
|
### 📝 Email Templates
|
|
|
|
|
|
|
|
|
|
Template engine with variable substitution for transactional and notification emails. Use `createEmail()` to produce a ready-to-send `Email` from a registered template:
|
|
|
|
|
Template engine with variable substitution for transactional and notification emails:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { TemplateManager } from '@push.rocks/smartmta';
|
|
|
|
|
import { Core } from '@push.rocks/smartmta';
|
|
|
|
|
const { TemplateManager } = Core;
|
|
|
|
|
|
|
|
|
|
const templates = new TemplateManager({
|
|
|
|
|
from: 'noreply@example.com',
|
|
|
|
|
footerHtml: '<p>2026 Example Corp</p>',
|
|
|
|
|
footerHtml: '<p>© 2026 Example Corp</p>',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Register a template
|
|
|
|
|
@@ -430,19 +482,11 @@ const email = await templates.createEmail('welcome', {
|
|
|
|
|
});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### DNS Management
|
|
|
|
|
### 🌍 DNS Management
|
|
|
|
|
|
|
|
|
|
DNS record management for email authentication is handled internally by `UnifiedEmailServer`. The `DnsManager` is not instantiated directly — it receives its configuration from the `dcRouter` reference and automatically ensures MX, SPF, DKIM, and DMARC records are in place for all configured domains:
|
|
|
|
|
DNS record management for email authentication is handled automatically by `UnifiedEmailServer`. When the server starts, it ensures MX, SPF, DKIM, and DMARC records are in place for all configured domains via the Cloudflare API:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// DNS management is automatic when using UnifiedEmailServer.
|
|
|
|
|
// When the server starts, it calls ensureDnsRecords() internally
|
|
|
|
|
// for all configured domains, setting up:
|
|
|
|
|
// - MX records pointing to your mail server
|
|
|
|
|
// - SPF TXT records authorizing your server IP
|
|
|
|
|
// - DKIM TXT records with public keys from DKIMCreator
|
|
|
|
|
// - DMARC TXT records with your policy
|
|
|
|
|
|
|
|
|
|
const emailServer = new UnifiedEmailServer(dcRouterRef, {
|
|
|
|
|
hostname: 'mail.example.com',
|
|
|
|
|
domains: [
|
|
|
|
|
@@ -454,47 +498,17 @@ const emailServer = new UnifiedEmailServer(dcRouterRef, {
|
|
|
|
|
// ... other config
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// DNS records are set up automatically on start
|
|
|
|
|
// DNS records are set up automatically on start:
|
|
|
|
|
// - MX records pointing to your mail server
|
|
|
|
|
// - SPF TXT records authorizing your server IP
|
|
|
|
|
// - DKIM TXT records with public keys from DKIMCreator
|
|
|
|
|
// - DMARC TXT records with your policy
|
|
|
|
|
await emailServer.start();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For DNS lookups and record verification outside of the server lifecycle, the `DNSManager` class (note the capital N) can be used directly:
|
|
|
|
|
### 🦀 RustSecurityBridge
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { DNSManager, DKIMCreator } from '@push.rocks/smartmta';
|
|
|
|
|
|
|
|
|
|
const dkimCreator = new DKIMCreator('/path/to/keys');
|
|
|
|
|
const dnsManager = new DNSManager(dkimCreator);
|
|
|
|
|
|
|
|
|
|
// Verify all email authentication records for a domain
|
|
|
|
|
const results = await dnsManager.verifyEmailAuthRecords('example.com', 'default');
|
|
|
|
|
console.log(results.spf); // { valid: boolean, record: string, ... }
|
|
|
|
|
console.log(results.dkim); // { valid: boolean, record: string, ... }
|
|
|
|
|
console.log(results.dmarc); // { valid: boolean, record: string, ... }
|
|
|
|
|
|
|
|
|
|
// Generate recommended DNS records
|
|
|
|
|
const records = await dnsManager.generateAllRecommendedRecords('example.com');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Rust Acceleration
|
|
|
|
|
|
|
|
|
|
Performance-critical operations are implemented in Rust and communicate with the TypeScript runtime via `@push.rocks/smartrust` (JSON-over-stdin/stdout IPC).
|
|
|
|
|
|
|
|
|
|
### Rust Crates
|
|
|
|
|
|
|
|
|
|
The Rust workspace is at `rust/` with five crates:
|
|
|
|
|
|
|
|
|
|
| Crate | Status | Purpose |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `mailer-core` | Complete (26 tests) | Email types, validation, MIME building, bounce detection |
|
|
|
|
|
| `mailer-security` | Complete (12 tests) | DKIM signing/verification, SPF checks, DMARC policy, IP reputation/DNSBL |
|
|
|
|
|
| `mailer-bin` | Complete | CLI + smartrust IPC bridge (handles `verifyEmail` compound method) |
|
|
|
|
|
| `mailer-smtp` | Planned (Phase 3) | SMTP protocol in Rust |
|
|
|
|
|
| `mailer-napi` | Planned (Phase 3) | Native Node.js addon |
|
|
|
|
|
|
|
|
|
|
### RustSecurityBridge
|
|
|
|
|
|
|
|
|
|
The `RustSecurityBridge` is a singleton that manages the Rust binary process and provides high-performance security verification. It is automatically started and stopped with `UnifiedEmailServer`:
|
|
|
|
|
The `RustSecurityBridge` is the singleton that manages the Rust binary process. It handles security verification, content scanning, bounce detection, and the SMTP server lifecycle — all via `@push.rocks/smartrust` IPC:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { RustSecurityBridge } from '@push.rocks/smartmta';
|
|
|
|
|
@@ -511,7 +525,7 @@ const securityResult = await bridge.verifyEmail({
|
|
|
|
|
});
|
|
|
|
|
// -> { dkim: [...], spf: { result, explanation }, dmarc: { result, policy } }
|
|
|
|
|
|
|
|
|
|
// Individual operations
|
|
|
|
|
// Individual security operations
|
|
|
|
|
const dkimResults = await bridge.verifyDkim(rawEmailString);
|
|
|
|
|
const spfResult = await bridge.checkSpf({
|
|
|
|
|
ip: '203.0.113.10',
|
|
|
|
|
@@ -520,10 +534,61 @@ const spfResult = await bridge.checkSpf({
|
|
|
|
|
});
|
|
|
|
|
const reputationResult = await bridge.checkIpReputation('203.0.113.10');
|
|
|
|
|
|
|
|
|
|
// DKIM signing
|
|
|
|
|
const signed = await bridge.signDkim({
|
|
|
|
|
email: rawEmailString,
|
|
|
|
|
domain: 'example.com',
|
|
|
|
|
selector: 'default',
|
|
|
|
|
privateKeyPem: privateKey,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Content scanning
|
|
|
|
|
const scanResult = await bridge.scanContent({
|
|
|
|
|
subject: 'Win a free iPhone!!!',
|
|
|
|
|
body: '<a href="http://phishing.example.com">Click here</a>',
|
|
|
|
|
from: 'scammer@evil.com',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Bounce detection
|
|
|
|
|
const bounceResult = await bridge.detectBounce({
|
|
|
|
|
subject: 'Delivery Status Notification (Failure)',
|
|
|
|
|
body: '550 5.1.1 User unknown',
|
|
|
|
|
from: 'mailer-daemon@example.com',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await bridge.stop();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When the bridge is running, the TypeScript security components (`SpfVerifier`, `DKIMVerifier`, `IPReputationChecker`) automatically delegate to the Rust binary. If the binary is unavailable, the system falls back gracefully to TypeScript-only verification.
|
|
|
|
|
> ⚠️ **Important:** The Rust bridge is **mandatory**. There are no TypeScript fallbacks. If the Rust binary is unavailable, `UnifiedEmailServer.start()` will throw an error.
|
|
|
|
|
|
|
|
|
|
## 🦀 Rust Acceleration Layer
|
|
|
|
|
|
|
|
|
|
Performance-critical operations are implemented in Rust and communicate with the TypeScript runtime via `@push.rocks/smartrust` (JSON-over-stdin/stdout IPC). The Rust workspace lives at `rust/` with five crates:
|
|
|
|
|
|
|
|
|
|
| Crate | Status | Purpose |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `mailer-core` | ✅ Complete (26 tests) | Email types, validation, MIME building, bounce detection |
|
|
|
|
|
| `mailer-security` | ✅ Complete (22 tests) | DKIM sign/verify, SPF, DMARC, IP reputation/DNSBL, content scanning |
|
|
|
|
|
| `mailer-smtp` | ✅ Complete (72 tests) | Full SMTP protocol engine — TCP/TLS server, STARTTLS, AUTH, pipelining, rate limiting |
|
|
|
|
|
| `mailer-bin` | ✅ Complete | CLI + smartrust IPC bridge — security, content scanning, SMTP server lifecycle |
|
|
|
|
|
| `mailer-napi` | 🔜 Planned | Native Node.js addon (N-API) |
|
|
|
|
|
|
|
|
|
|
### What Runs in Rust
|
|
|
|
|
|
|
|
|
|
| Operation | Runs In | Why |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| SMTP server (port listening, protocol, TLS) | Rust | Performance, memory safety, zero-copy parsing |
|
|
|
|
|
| DKIM signing & verification | Rust | Crypto-heavy, benefits from native speed |
|
|
|
|
|
| SPF validation | Rust | DNS lookups with async resolver |
|
|
|
|
|
| DMARC policy checking | Rust | Integrates with SPF/DKIM results |
|
|
|
|
|
| IP reputation / DNSBL | Rust | Parallel DNS queries |
|
|
|
|
|
| Content scanning (text patterns) | Rust | Regex engine performance |
|
|
|
|
|
| Bounce detection (pattern matching) | Rust | Regex engine performance |
|
|
|
|
|
| Email validation & MIME building | Rust | Parsing performance |
|
|
|
|
|
| Binary attachment scanning | TypeScript | Buffer data too large for IPC |
|
|
|
|
|
| Email routing & orchestration | TypeScript | Business logic, flexibility |
|
|
|
|
|
| Delivery queue & retry | TypeScript | State management, persistence |
|
|
|
|
|
| Template rendering | TypeScript | String interpolation |
|
|
|
|
|
|
|
|
|
|
## Project Structure
|
|
|
|
|
|
|
|
|
|
@@ -534,14 +599,20 @@ smartmta/
|
|
|
|
|
│ │ ├── core/ # Email, EmailValidator, BounceManager, TemplateManager
|
|
|
|
|
│ │ ├── delivery/ # DeliverySystem, Queue, RateLimiter
|
|
|
|
|
│ │ │ ├── smtpclient/ # SMTP client with connection pooling
|
|
|
|
|
│ │ │ └── smtpserver/ # SMTP server with TLS, auth, pipelining
|
|
|
|
|
│ │ │ └── smtpserver/ # Legacy TS SMTP server (socket-handler fallback)
|
|
|
|
|
│ │ ├── routing/ # UnifiedEmailServer, EmailRouter, DomainRegistry, DnsManager
|
|
|
|
|
│ │ └── security/ # DKIMCreator, DKIMVerifier, SpfVerifier, DmarcVerifier
|
|
|
|
|
│ └── security/ # ContentScanner, IPReputationChecker, RustSecurityBridge
|
|
|
|
|
├── rust/ # Rust workspace
|
|
|
|
|
│ └── crates/ # mailer-core, mailer-security, mailer-bin, mailer-smtp, mailer-napi
|
|
|
|
|
├── test/ # Comprehensive test suite
|
|
|
|
|
└── dist_ts/ # Compiled output
|
|
|
|
|
│ └── crates/
|
|
|
|
|
│ ├── mailer-core/ # Email types, validation, MIME, bounce detection
|
|
|
|
|
│ ├── mailer-security/ # DKIM, SPF, DMARC, IP reputation, content scanning
|
|
|
|
|
│ ├── mailer-smtp/ # Full SMTP server (TCP/TLS, state machine, rate limiting)
|
|
|
|
|
│ ├── mailer-bin/ # CLI + smartrust IPC bridge
|
|
|
|
|
│ └── mailer-napi/ # N-API addon (planned)
|
|
|
|
|
├── test/ # Test suite
|
|
|
|
|
├── dist_ts/ # Compiled TypeScript output
|
|
|
|
|
└── dist_rust/ # Compiled Rust binaries
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## License and Legal Information
|
|
|
|
|
|