fog is a privacy-preserving SMTP relay that uses Sphinx mixnet routing to provide sender anonymity, forward secrecy, and resistance to traffic analysis. Perfect for anonymous email delivery, Usenet posting, and secure communications.
- 🔐 Sphinx Mixnet Routing: 3-hop onion routing with per-hop encryption
- ⏱️ Timing Attack Resistance: Configurable message delays (1-24h) with multiple strategies
- 🎭 Exit Node Anonymization: Automatic header sanitization removes all identifying information
- 🔄 Forward Secrecy: Each message uses ephemeral keys, past messages remain secure if node compromised
- 🚫 No Logs: Zero persistent metadata retention
- 🔀 Batch Mixing: Messages are batched and shuffled before forwarding
- ♻️ Replay Protection: Message-ID cache prevents replay attacks
- 📦 Persistent Queue: SQLite-backed delay pool survives restarts
- 🎲 Multiple Delay Strategies: Exponential (default), Constant, Poisson distributions
- 🏥 Health Checking: Automatic node monitoring and path selection
- 🔍 Debug Mode: Detailed logging for troubleshooting
- 🐧 Linux Optimized: Systemd integration with security hardening
| Threat | Protection |
|---|---|
| Traffic Analysis | Padding + cover traffic |
| Timing Attacks | Randomized delays (1-24h) + constant-time operations |
| Replay Attacks | Message-ID cache with TTL expiration |
| Node Compromise | Forward secrecy protects older messages |
| Size Correlation | Fixed 64KB packet size prevents size analysis |
| Partial Network Observation | Mixnet architecture breaks linkability |
| Global Adversary | Multi-hop routing + batch mixing breaks end-to-end correlation |
| Metadata Analysis | Exit node header sanitization + no persistent metadata |
# Install dependencies
sudo apt update
sudo apt install -y golang-go tor git build-essential
# Verify Go version (1.21+ required)
go version# Clone repository
git clone https://github.com/yourusername/fog.git
cd fog
# Build
go mod tidy
go build -tags="sqlite_omit_load_extension" -ldflags="-s -w" -trimpath -o fog fog.go
# Install binary
sudo mkdir -p /var/lib/fog
sudo cp fog /var/lib/fog/
sudo chmod +x /var/lib/fog/fog# Create fog user
sudo useradd -r -s /bin/false fog
# Create directories
sudo mkdir -p /var/lib/fog/data
sudo chown -R fog:fog /var/lib/fog
sudo chmod 700 /var/lib/fog/data# Generate your node keys
cd /var/lib/fog
sudo -u fog ./fog -name your-onion-address.onion -short-name yourname -export-node-info
# This creates nodes.json with your public key
cat nodes.jsonConfigure Tor Hidden Service
Edit /etc/tor/torrc:
HiddenServiceDir /var/lib/tor/fog/
HiddenServicePort 9999 127.0.0.1:9999
HiddenServicePort 2525 127.0.0.1:2525
Restart Tor and get your address:
sudo systemctl restart tor
sudo cat /var/lib/tor/fog/hostname
# Example output: abc123xyz456.onionJoin the existing fog network or create your own!
Contact the network operators to:
- Share your
nodes.json(contains your public key + onion address) - Receive the network
nodes.json(contains all trusted nodes) - Deploy to
/var/lib/fog/nodes.json
Start with 1 node (you), then invite others:
# Use your own nodes.json
sudo cp nodes.json /var/lib/fog/nodes.jsonCreate /etc/systemd/system/fog.service:
[Unit]
Description=fog - Anonymous SMTP Relay
After=network.target tor.service
Wants=tor.service
[Service]
Type=simple
User=fog
Group=fog
WorkingDirectory=/var/lib/fog
ExecStart=/var/lib/fog/fog \
-name YOUR_ONION.onion \
-short-name yourname \
-smtp 127.0.0.1:2525 \
-node 127.0.0.1:9999 \
-sphinx \
-delay \
-min-delay 2h \
-max-delay 24h \
-delay-strategy exponential \
-pki-file /var/lib/fog/nodes.json \
-data-dir /var/lib/fog/data \
-debug
Restart=always
RestartSec=10
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/fog/data
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
[Install]
WantedBy=multi-user.targetReplace:
YOUR_ONION.onionwith your Tor hidden service addressyournamewith your chosen node name (e.g., alice, bob, relay1)
sudo systemctl daemon-reload
sudo systemctl enable fog
sudo systemctl start fog
# Check status
sudo systemctl status fog
# Watch logs
sudo journalctl -u fog -f{
echo "EHLO client"
echo "MAIL FROM:<sender@example.com>"
echo "RCPT TO:<recipient@destination.com>"
echo "DATA"
echo "From: Anonymous User <user@example.com>"
echo "To: recipient@destination.com"
echo "Subject: Anonymous message via fog"
echo ""
echo "This message was sent through the fog network."
echo "."
echo "QUIT"
} | nc 127.0.0.1 2525{
echo "EHLO client"
echo "MAIL FROM:<poster@example.com>"
echo "RCPT TO:<mail2news@mail2news.tcpreset.net>"
echo "DATA"
echo "From: Anonymous Poster <poster@example.com>"
echo "Newsgroups: alt.test"
echo "Subject: Test post via fog"
echo ""
echo "This post was submitted anonymously through fog network."
echo "."
echo "QUIT"
} | nc 127.0.0.1 2525At the exit node, headers are automatically sanitized:
From:→Anonymous <anonymous@exitnode.fog>Message-ID:→<random_hex@exitnode.fog>- All identifying headers removed (X-Mailer, Reply-To, etc.)
| Flag | Default | Description |
|---|---|---|
-name |
required | Your .onion address |
-short-name |
required | Short node name (for logs) |
-smtp |
127.0.0.1:2525 | SMTP listen address |
-node |
127.0.0.1:9999 | Sphinx node listen address |
-pki-file |
required | Path to nodes.json |
-data-dir |
fog-data | Data directory for queue database |
-sphinx |
false | Enable Sphinx routing |
-delay |
false | Enable delay pool |
-min-delay |
1h | Minimum message delay |
-max-delay |
24h | Maximum message delay |
-delay-strategy |
exponential | Delay strategy: exponential, constant, poisson |
-debug |
false | Enable debug logging |
Exponential (Recommended):
- More short delays, fewer long delays
- Natural traffic pattern
- Best for high-volume nodes
Constant:
- Uniform random delays
- Predictable average latency
- Good for testing
Poisson:
- Models natural arrival processes
- Best for research/analysis
High Anonymity (24h delays):
-delay -min-delay 6h -max-delay 24h -delay-strategy exponentialMedium Latency (6h delays):
-delay -min-delay 1h -max-delay 6h -delay-strategy constantLow Latency (no delays):
-sphinx
# (omit -delay flag)# View queue size
sqlite3 /var/lib/fog/data/messages.db \
"SELECT COUNT(*) as total FROM message_queue;"
# View ready messages
sqlite3 /var/lib/fog/data/messages.db \
"SELECT COUNT(*) FROM message_queue WHERE send_after <= strftime('%s','now');"
# View queue details
sqlite3 /var/lib/fog/data/messages.db \
"SELECT id, from_addr, to_addr,
datetime(send_after, 'unixepoch') as send_time
FROM message_queue
ORDER BY send_after LIMIT 10;"# All fog activity
sudo journalctl -u fog -f
# Pool activity only
sudo journalctl -u fog -f | grep POOL
# Statistics only
sudo journalctl -u fog -f | grep STATS
# Header sanitization
sudo journalctl -u fog -f | grep SANITIZE[STATS] Up:2h30m R:45 S:42 F:3 | Sphinx:40 Direct:2 | Mix R:120 F:115 | Q:23 D:156 | Healthy:4
- R: Messages received
- S: Messages sent
- F: Failed deliveries
- Sphinx: Messages sent via Sphinx routing
- Direct: Messages sent directly (no Sphinx)
- Mix R/F: Mixed received/forwarded
- Q: Messages queued in delay pool
- D: Total delayed messages delivered
- Healthy: Number of healthy nodes in network
The fog network currently consists of 5 active nodes:
| Node | Status |
|---|---|
| kvara | ✅ Active |
| dries | ✅ Active |
| mct8 | ✅ Active |
| news | ✅ Active |
| pietro | ✅ Active |
Join us! Run your own node and strengthen the network's resilience.
- 3 nodes minimum for Sphinx routing (3-hop paths)
- 5+ nodes recommended for proper anonymity set
- Network diversity improves security
Error: "No such file or directory" for /var/lib/fog/data
sudo mkdir -p /var/lib/fog/data
sudo chown fog:fog /var/lib/fog/data
sudo chmod 700 /var/lib/fog/data
sudo systemctl restart fogError: "PKI file not found"
# Make sure nodes.json exists
ls -l /var/lib/fog/nodes.json
# If missing, generate or obtain from network
sudo -u fog /var/lib/fog/fog -name YOUR.onion -short-name name -export-node-info
sudo cp nodes.json /var/lib/fog/Check Tor connectivity:
# Test Tor is running
curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
# Check fog can reach other nodes
sudo journalctl -u fog | grep HEALTHCheck Sphinx routing:
# Verify enough healthy nodes
sudo journalctl -u fog | grep "nodes healthy"
# Should show: "[HEALTH] Done. 4 nodes healthy" (or more)Check scheduler:
sudo journalctl -u fog | grep "Scheduler started"
# Should show: "[POOL] Scheduler started (check every 1m0s)"Check for ready messages:
sqlite3 /var/lib/fog/data/messages.db \
"SELECT * FROM message_queue WHERE send_after <= strftime('%s','now');"The best way to contribute is to run your own fog node! Requirements:
- Debian/Ubuntu server with static IP or dynamic DNS
- Tor hidden service
- Reliable uptime (>95% recommended)
- Bandwidth: ~100GB/month for relay node
Get started: Follow the Quick Start guide above and contact us to join the network.
# Clone repository
git clone https://github.com/yourusername/fog.git
cd fog
# Run tests
go test ./...
# Build
go build -tags="sqlite_omit_load_extension" -o fog fog.go
# Run locally
./fog -name test.onion -short-name test -smtp 127.0.0.1:2525 -debugFound a bug? Have a feature request? Open an issue
Do not open public issues for security vulnerabilities.
Contact: security@fog.network (PGP key available)
- CHANGELOG.md - Version history and release notes
- ARCHITECTURE.md - Technical design and protocol specification
- SECURITY.md - Security model and threat analysis
- API.md - SMTP protocol and message format
Client → Entry Node → Middle Node → Exit Node → Destination
(Hop 1) (Hop 2) (Hop 3)
Each hop:
- Decrypts one layer of encryption
- Cannot see final destination (onion routing)
- Adds random delay before forwarding
- Batches with other messages for mixing
At exit node:
- Final decryption reveals cleartext message
- Headers are sanitized (From, Message-ID, Date randomized)
- All identifying metadata removed
- Delivered to final destination
Security properties:
- No single node knows both sender and recipient
- Forward secrecy: past messages safe if node compromised
- Timing attacks mitigated by random delays + batching
- Traffic analysis resisted by fixed packet sizes + mixing
MIT License - see LICENSE file for details.
- Sphinx Mix Network: Based on the Sphinx protocol by George Danezis and Ian Goldberg
- Tor Project: For anonymous networking infrastructure
- Go Community: For excellent cryptography libraries
- Website: https://yamn.virebent.art
- Usenet: alt.privacy.anon-server
fog is designed for legal, privacy-preserving communications. Users are responsible for compliance with applicable laws. The fog network operators do not endorse or condone illegal activity.
Exit node operators: Be aware that running an exit node means your IP/server may be associated with traffic you did not originate. Consider legal implications in your jurisdiction.