Skip to content

sexfrance/SMTP-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 Cybertemp SMTP Server

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 · ⚠️ Report Bug · 💡 Request Feature


📖 Table of Contents


📚 About

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

🏗️ Architecture

┌─────────────────┐
│  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

🔥 Features

  • 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

📋 Prerequisites

  • 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)

⚙️ Installation

Using Rust (Recommended - Active Development)

⚠️ Note: The JavaScript version is NOT MAINTAINED. Use the Rust implementation in the rust/ directory.

  1. 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/
  2. Clone the repository:

    git clone https://github.com/sexfrance/smtp-server.git
    cd smtp-server/rust
  3. Build the project:

    # Development build
    cargo build
    
    # Production build (optimized)
    cargo build --release

🔧 Configuration

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

Environment Variables Explained

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

💾 Database Setup

PostgreSQL Schema

Run the SQL schema located in rust/SQL/schema.sql:

psql -U your_user -d cybertemp -f rust/SQL/schema.sql

This creates:

  • emails table - stores all temporary emails
  • inbox table - stores inbox information (self-hosted)
  • private_email table - optional private email accounts (see below)
  • Necessary indexes for performance

Optional Supabase Tables (for advanced features)

If you want to use domain whitelisting and ban management, create these tables in Supabase:

1. domains table (Domain Whitelist - Optional)

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 support

2. bans table (Email/Domain Blocking - Optional)

CREATE 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.


🚀 Running the Server

Development Mode

cd rust
cargo run

Production Mode

cd rust
cargo build --release
./target/release/cybertemp_smtp

Running on Port 25 (Linux)

Port 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_smtp

Running as a Service (Systemd)

Create /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.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable cybertemp-smtp
sudo systemctl start cybertemp-smtp
sudo systemctl status cybertemp-smtp

🔍 How It Works

Email Flow

  1. Connection: External SMTP server connects to port 25
  2. SMTP Handshake: Server responds with 220 Cybertemp Mail Receiver
  3. Domain Check: Recipient domain is validated against whitelist
  4. Ban Check: Sender and domain are checked against ban list
  5. Email Receipt: Server accepts email data until . terminator
  6. Instant Reply: Server immediately responds with 250 Ok: Message accepted (<1ms)
  7. Background Processing: Email processing spawned as async task (non-blocking)
    • Email is parsed inline using mailparse crate (1-3ms, no thread pool)
    • Inbox created via upsert (ON CONFLICT, no SELECT query needed)
    • Storage decision made (private vs temp email)
  8. Batch Queueing: Email is queued to batch processor via channel (mpsc, 1000 buffer)
  9. 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
  10. Batch Insert: All queued emails inserted in single multi-row transaction (10-15ms for 50 emails)
  11. 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.

Domain Whitelisting

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 exactly example.com
  • *.example.com - matches mail.example.com, temp.example.com, etc.

Automatic updates: Domain list is refreshed every 60 seconds.

Ban System

Protects against spam and abuse:

  • Email bans: Block specific sender addresses
    • exact match: Must match exactly
    • contains match: Blocks if sender contains substring
  • Domain bans: Block entire sending domains
  • Real-time updates: Ban list refreshes every 60 seconds

⚠️ Important Notes

About Private Emails (privatemail.sql)

⚠️ The 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:

  1. Delete or ignore rust/SQL/privatemail.sql
  2. 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
    }

Code Quality Disclaimer

⚠️ This codebase is functional but not prettily written. It's a working production system that evolved organically. Known issues:

  • 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 Version

⚠️ The javascript/ folder is NOT MAINTAINED - it was an early prototype. Use the Rust version for all deployments.


🛠️ Troubleshooting

Common Issues

1. "mismatched types - expected &str, found &Result<String, VarError>"

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");

2. "Failed to connect to PostgreSQL"

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"

3. "Failed to load domains from Supabase" (if using Supabase features)

Check:

  • Supabase URL is correct (https://your-project.supabase.co)
  • Service role key is correct (NOT anon key)
  • domains table exists in Supabase
  • Network connectivity to Supabase

4. "Permission denied" binding to port 25

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_smtp

5. Emails not appearing in database

Check logs for:

  • Domain whitelist rejections
  • Ban list rejections
  • Database insertion errors
  • Parsing errors

Enable debug logging:

RUST_LOG=debug ./target/release/cybertemp_smtp

📊 Development Status

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 ⚠️ Optional For advanced features only
Private Email Feature ⚠️ Optional Cybertemp-specific, not required
Performance Optimized 20x faster (v0.5.0)
Code Quality ✅ Improved Recent refactoring & optimization
Documentation ✅ Complete You're reading it!

📜 ChangeLog

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

📞 Support


📄 License

MIT License - See LICENSE file for details


🙏 Acknowledgments

  • Built with ❤️ for the Cybertemp community
  • Powered by Rust 🦀, Tokio, and PostgreSQL
  • Optional Supabase integration for advanced features

⭐ Star this repo if you found it helpful!
Currently powering Cybertemp's email infrastructure 🚀

About

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.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors