A high-performance, production-ready SMTP receive-only server powering Cybertemp's temporary and private email infrastructure. Built with Rust for speed, reliability, and concurrency.
💬 Discord
·
📜 ChangeLog
·
- About
- Architecture
- Features
- Prerequisites
- Installation
- Configuration
- Database Setup
- Running the Server
- How It Works
- Important Notes
- Troubleshooting
- Development Status
- ChangeLog
THIS README IS ENTIRLY GENERATED BY AI I DID NOT WRITE THIS SHIT
This is the actual SMTP server currently powering Cybertemp - a temporary email service handling thousands of emails daily. The codebase is functional and battle-tested in production, with recent major performance optimizations achieving 20x faster email processing (v0.5.0).
This server is designed as a high-performance receive-only SMTP server that:
- Accepts incoming emails on port 25 (or custom port) with <1ms SMTP response times
- Processes emails asynchronously in the background for maximum throughput
- Stores temporary emails in PostgreSQL with intelligent batch inserts (50 emails @ 10-15ms)
- Manages inboxes with optimized upsert queries (no redundant SELECT)
- Supports private email accounts (optional feature used by Cybertemp)
- Implements domain whitelisting and email/domain banning (optional Supabase integration)
- Handles concurrent connections efficiently with Tokio async runtime (50 concurrent, 2000 queue)
- Maintains 100-connection PostgreSQL pool with persistent min connections for zero-latency queries
┌─────────────────┐
│ Incoming SMTP │
│ Port 25/2525 │
└────────┬────────┘
│
▼
┌──────────────────────────────────────────┐
│ Rust SMTP Server (Tokio Async) │
│ ├─ Instant SMTP replies (<1ms) │
│ ├─ Background email processing (async) │
│ ├─ Concurrent connection handler (50) │
│ ├─ Fast inline email parsing │
│ ├─ Domain whitelist checking │
│ └─ Ban list filtering │
└────────┬─────────────────────────────────┘
│
├────────────────┬──────────────┬────────────────┐
▼ ▼ ▼ ▼
┌─────────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ Batch Queue │ │ PostgreSQL │ │ Heartbeat │
│ (Email Pool) │ │ (1000 buffer)│ │ (Inboxes) │ │ Monitoring │
│ 100 Connection │ │ 25-100ms flush│ │ ON CONFLICT │ │ Optional │
└─────────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
Performance Characteristics:
- SMTP Response: <1ms (instant acceptance, background processing)
- Email Parsing: 1-3ms (inline, no thread pool overhead)
- Inbox Creation: 0-5ms (upsert, no SELECT query)
- Batch Insert: 10-15ms for 50 emails (97% faster than individual inserts)
- Total Per-Email: 5-15ms end-to-end
- ✅ Production-Ready: Currently handling Cybertemp's email traffic
- ✅ Ultra-High Performance: Async Rust with Tokio - 20x faster than previous version
- ✅ Async Email Processing: Background processing with instant SMTP replies (<1ms response time)
- ✅ Intelligent Batching: Low-latency batch inserts (25-100ms timeouts, 50-email batches)
- ✅ Optimized Database: Upsert-based inbox creation, 100-connection pool with persistent connections
- ✅ Dual Email System: Supports both temporary and private emails
- ✅ Domain Whitelisting: Accept emails only for configured domains
- ✅ Ban System: Block emails from specific senders/domains
- ✅ MIME Parsing: Fast inline parsing without thread pool overhead
- ✅ PostgreSQL Storage: Reliable email storage with optimized indexing
- ✅ Self-hosted Inboxes: Automatic inbox management with ON CONFLICT handling
- ✅ Advanced Connection Pooling: Min/max connections, idle timeout, connection lifetime management
- ✅ Queue Management: Prevents server overload with request limits (50 concurrent, 2000 queue)
- ✅ Heartbeat Monitoring: Optional uptime monitoring endpoint
- ✅ Real-time Domain Updates: Polls for domain/ban updates every 60-120s
- ✅ Graceful Error Handling: Detailed logging with tracing
- Rust 1.70+ (for compilation)
- PostgreSQL 12+ (for email storage and inbox management)
- Linux/Windows/macOS (any platform supporting Rust)
- Port 25 Access (or alternative SMTP port - requires root/admin on Linux for port 25)
⚠️ Note: The JavaScript version is NOT MAINTAINED. Use the Rust implementation in therust/directory.
-
Install Rust (if not already installed):
# Linux/macOS curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Windows # Download from https://rustup.rs/
-
Clone the repository:
git clone https://github.com/sexfrance/smtp-server.git cd smtp-server/rust -
Build the project:
# Development build cargo build # Production build (optimized) cargo build --release
Create a .env file in the rust/ directory with the following variables:
# PostgreSQL Database (REQUIRED)
DATABASE_URL=postgresql://username:password@localhost:5432/cybertemp
# SMTP Server Settings (OPTIONAL)
SMTP_RECEIVE_PORT=25 # Default: 25 (use 2525 for non-root testing)
# Heartbeat Monitoring (OPTIONAL)
HEARTBEAT_URL=https://your-monitoring-service.com/ping| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
✅ Yes | - | PostgreSQL connection string for storing emails |
SMTP_RECEIVE_PORT |
❌ No | 25 | SMTP port (default: 25) |
HEARTBEAT_URL |
❌ No | - | Uptime monitoring ping URL |
USE_SUPABASE_BANS |
❌ No | true | Enable/disable Supabase ban system |
USE_SUPABASE_DOMAINS |
❌ No | true | Enable/disable Supabase domain whitelist |
Run the SQL schema located in rust/SQL/schema.sql:
psql -U your_user -d cybertemp -f rust/SQL/schema.sqlThis creates:
emailstable - stores all temporary emailsinboxtable - stores inbox information (self-hosted)private_emailtable - optional private email accounts (see below)- Necessary indexes for performance
If you want to use domain whitelisting and ban management, create these tables in Supabase:
CREATE TABLE domains (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
domain TEXT NOT NULL UNIQUE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Add your domains
INSERT INTO domains (domain) VALUES
('cybertemp.xyz'),
('temp-mail.xyz'),
('*.example.com'); -- Wildcard supportCREATE TABLE bans (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
scope TEXT NOT NULL, -- 'email' or 'domain'
value TEXT NOT NULL, -- email address or domain
match_type TEXT DEFAULT 'exact', -- 'exact' or 'contains'
status TEXT DEFAULT 'active', -- 'active' or 'inactive'
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Example bans
INSERT INTO bans (scope, value, match_type, status) VALUES
('email', '[email protected]', 'exact', 'active'),
('email', 'spam', 'contains', 'active'), -- Blocks any email containing "spam"
('domain', 'spammer.com', 'exact', 'active');Note: If you don't create these Supabase tables, set USE_SUPABASE_BANS=false and USE_SUPABASE_DOMAINS=false in your .env file. The server will accept all domains and have no bans by default.
cd rust
cargo runcd rust
cargo build --release
./target/release/cybertemp_smtpPort 25 requires root privileges:
# Option 1: Run as root
sudo ./target/release/cybertemp_smtp
# Option 2: Grant port binding capability (recommended)
sudo setcap CAP_NET_BIND_SERVICE=+eip ./target/release/cybertemp_smtp
./target/release/cybertemp_smtpCreate /etc/systemd/system/cybertemp-smtp.service:
[Unit]
Description=Cybertemp SMTP Server
After=network.target postgresql.service
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/smtp-server/rust
EnvironmentFile=/path/to/smtp-server/rust/.env
ExecStart=/path/to/smtp-server/rust/target/release/cybertemp_smtp
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable cybertemp-smtp
sudo systemctl start cybertemp-smtp
sudo systemctl status cybertemp-smtp- Connection: External SMTP server connects to port 25
- SMTP Handshake: Server responds with
220 Cybertemp Mail Receiver - Domain Check: Recipient domain is validated against whitelist
- Ban Check: Sender and domain are checked against ban list
- Email Receipt: Server accepts email data until
.terminator - Instant Reply: Server immediately responds with
250 Ok: Message accepted(<1ms) - Background Processing: Email processing spawned as async task (non-blocking)
- Email is parsed inline using
mailparsecrate (1-3ms, no thread pool) - Inbox created via upsert (ON CONFLICT, no SELECT query needed)
- Storage decision made (private vs temp email)
- Email is parsed inline using
- Batch Queueing: Email is queued to batch processor via channel (mpsc, 1000 buffer)
- Smart Batching: Adaptive flush based on load:
- 1-4 emails: 25ms timeout
- 5-9 emails: 50ms timeout
- 10-19 emails: 75ms timeout
- 20+ emails: 100ms timeout
- 50 emails: immediate flush
- Batch Insert: All queued emails inserted in single multi-row transaction (10-15ms for 50 emails)
- Connection Close: SMTP session ends while processing continues in background
Performance: SMTP connection completes in ~200-500ms (sender-paced), actual server processing <1ms. Database operations happen asynchronously after reply.
The server only accepts emails for domains listed in the configured domain source (Supabase domains table if enabled, otherwise accepts all domains). This prevents abuse and unauthorized usage.
Wildcard support:
example.com- matches exactlyexample.com*.example.com- matchesmail.example.com,temp.example.com, etc.
Automatic updates: Domain list is refreshed every 60 seconds.
Protects against spam and abuse:
- Email bans: Block specific sender addresses
exactmatch: Must match exactlycontainsmatch: Blocks if sender contains substring
- Domain bans: Block entire sending domains
- Real-time updates: Ban list refreshes every 60 seconds
private_email table is ONLY used by Cybertemp for paid features and is NOT required for basic SMTP functionality.
What it does:
- Allows specific email addresses to have persistent storage
- Adds an extra layer of security with passwords
- Used for Cybertemp's paid private email accounts
- Completely optional for self-hosted deployments
How to remove it:
- Delete or ignore
rust/SQL/privatemail.sql - Remove the private email check in
main.rs(lines ~409-447):// Remove this entire block: match sqlx::query("SELECT id FROM private_email WHERE email = $1 LIMIT 1") .bind(&recipient_email) .fetch_optional(postgres_pool) .await { // ... entire private email handling logic }
- Long functions that should be split up
- Some error handling could be more elegant
- Duplicate code in fallback paths
- Comment clutter from debugging sessions
But it works reliably and handles thousands of emails daily for Cybertemp. Refactoring PRs welcome! 😄
javascript/ folder is NOT MAINTAINED - it was an early prototype. Use the Rust version for all deployments.
Problem: Environment variable not being unwrapped properly.
Solution: Make sure .env file exists and contains required variables. The error occurs when env::var() fails.
// Fix by adding .expect() or ?
let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set in .env file");Check:
- PostgreSQL is running:
systemctl status postgresql - Database exists:
psql -l | grep cybertemp - Credentials are correct in
DATABASE_URL - Schema is initialized:
psql -d cybertemp -c "\dt"
Check:
- Supabase URL is correct (https://your-project.supabase.co)
- Service role key is correct (NOT anon key)
domainstable exists in Supabase- Network connectivity to Supabase
Solution:
# Option 1: Run as root
sudo ./target/release/cybertemp_smtp
# Option 2: Grant capability (Linux only)
sudo setcap CAP_NET_BIND_SERVICE=+eip ./target/release/cybertemp_smtp
# Option 3: Use alternative port
SMTP_RECEIVE_PORT=2525 ./target/release/cybertemp_smtpCheck logs for:
- Domain whitelist rejections
- Ban list rejections
- Database insertion errors
- Parsing errors
Enable debug logging:
RUST_LOG=debug ./target/release/cybertemp_smtp| Component | Status | Notes |
|---|---|---|
| Rust Implementation | ✅ Active | Production-ready, actively maintained |
| JavaScript Implementation | ❌ Abandoned | Not maintained, use Rust version |
| PostgreSQL Storage | ✅ Production | Stable and tested |
| Self-hosted Inboxes | ✅ Production | No external dependencies |
| Supabase Integration | For advanced features only | |
| Private Email Feature | Cybertemp-specific, not required | |
| Performance | ✅ Optimized | 20x faster (v0.5.0) |
| Code Quality | ✅ Improved | Recent refactoring & optimization |
| Documentation | ✅ Complete | You're reading it! |
v0.5.0 ⋮ 02/11/2026
! MAJOR PERFORMANCE OVERHAUL - 20x faster email processing
+ Async email processing: SMTP replies instantly, processing in background
+ Removed spawn_blocking overhead (20-30ms saved per email)
+ Inbox upsert: Single ON CONFLICT query instead of SELECT+INSERT (50-90ms saved)
+ Enhanced connection pool: 100 max, 10 min persistent connections
+ Low-latency batching: 25-100ms timeouts instead of 50-2000ms
+ Optimized batch sizes: 50-email batches for throughput/latency balance
+ Total improvement: 125-290ms → 5-15ms per email
v0.4.0 ⋮ 02/02/2025
+ Batch insert optimization with multi-row INSERT statements
+ Channel-based email buffering (mpsc) for SMTP-DB decoupling
+ TCP_NODELAY enabled for faster socket communication
+ Reduced polling intervals (domain: 120s, bans: 60s)
+ QueryBuilder for efficient bulk inserts with transactions
+ Performance optimized for 1 vCore servers
v0.3.0 ⋮ 11/01/2025
+ Comprehensive documentation rewrite
+ Clarified private email feature is optional
+ Added extensive troubleshooting guide
+ Documented Supabase table schemas
+ Added systemd service configuration
v0.2.0 ⋮ 09/2024
+ Ban system implementation (email/domain blocking)
+ Real-time domain whitelist updates
+ Improved MIME parsing with fallbacks
+ Connection queue management
+ Heartbeat monitoring support
v0.1.0 ⋮ 06/2024
! Initial production deployment for Cybertemp
+ PostgreSQL storage implementation
+ Supabase integration
+ Domain whitelisting
+ Private email support
+ Async Tokio runtime- Discord: discord.cyberious.xyz
- Email: [email protected]
- Issues: GitHub Issues
MIT License - See LICENSE file for details
- Built with ❤️ for the Cybertemp community
- Powered by Rust 🦀, Tokio, and PostgreSQL
- Optional Supabase integration for advanced features
Currently powering Cybertemp's email infrastructure 🚀