diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 737 |
1 files changed, 176 insertions, 561 deletions
@@ -1,561 +1,176 @@ -# 🌫️ fog - Anonymous SMTP Relay Network - -**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. - -[](https://github.com/yourusername/fog) -[](LICENSE) -[](https://go.dev/) - ---- - -## 🎯 Features - -### Core Privacy Features - -- **🔐 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 - -### Technical Features - -- **📦 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 - ---- - -## 🛡️ Security Guarantees - -| 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 | - ---- - -## 🚀 Quick Start (Debian/Ubuntu) - -### Prerequisites - -```bash -# Install dependencies -sudo apt update -sudo apt install -y golang-go tor git build-essential - -# Verify Go version (1.21+ required) -go version -``` - -### Installation - -```bash -# 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 User & Directories - -```bash -# 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 Node Identity - -```bash -# 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.json -``` - -### Configure 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: - -```bash -sudo systemctl restart tor -sudo cat /var/lib/tor/fog/hostname -# Example output: abc123xyz456.onion -``` - -### Join the Network - -**Join the existing fog network or create your own!** - -#### Option 1: Join Existing Network - -Contact the network operators to: -1. Share your `nodes.json` (contains your public key + onion address) -2. Receive the network `nodes.json` (contains all trusted nodes) -3. Deploy to `/var/lib/fog/nodes.json` - -#### Option 2: Create New Network - -Start with 1 node (you), then invite others: - -```bash -# Use your own nodes.json -sudo cp nodes.json /var/lib/fog/nodes.json -``` - -### Configure Systemd Service - -Create `/etc/systemd/system/fog.service`: - -```ini -[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.target -``` - -**Replace:** -- `YOUR_ONION.onion` with your Tor hidden service address -- `yourname` with your chosen node name (e.g., alice, bob, relay1) - -### Start Service - -```bash -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 -``` - ---- - -## 📨 Usage - -### Send Anonymous Email - -```bash -{ - 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 -``` - -### Post to Usenet Anonymously - -```bash -{ - 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 2525 -``` - -**At 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.) - ---- - -## ⚙️ Configuration - -### Command Line Flags - -| 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 | - -### Delay Strategies - -**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 - -### Example Configurations - -**High Anonymity (24h delays):** -```bash --delay -min-delay 6h -max-delay 24h -delay-strategy exponential -``` - -**Medium Latency (6h delays):** -```bash --delay -min-delay 1h -max-delay 6h -delay-strategy constant -``` - -**Low Latency (no delays):** -```bash --sphinx -# (omit -delay flag) -``` - ---- - -## 🔍 Monitoring - -### Check Queue Status - -```bash -# 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;" -``` - -### Monitor Logs - -```bash -# 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 -``` - -### Statistics Output - -``` -[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 - ---- - -## 🌐 Network Information - -### Current fog 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. - -### Minimum Network Requirements - -- **3 nodes minimum** for Sphinx routing (3-hop paths) -- **5+ nodes recommended** for proper anonymity set -- **Network diversity** improves security - ---- - -## 🔧 Troubleshooting - -### Service won't start - -**Error: "No such file or directory" for /var/lib/fog/data** - -```bash -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 fog -``` - -**Error: "PKI file not found"** - -```bash -# 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/ -``` - -### Messages not being delivered - -**Check Tor connectivity:** -```bash -# 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 HEALTH -``` - -**Check Sphinx routing:** -```bash -# Verify enough healthy nodes -sudo journalctl -u fog | grep "nodes healthy" - -# Should show: "[HEALTH] Done. 4 nodes healthy" (or more) -``` - -### Queue not processing - -**Check scheduler:** -```bash -sudo journalctl -u fog | grep "Scheduler started" - -# Should show: "[POOL] Scheduler started (check every 1m0s)" -``` - -**Check for ready messages:** -```bash -sqlite3 /var/lib/fog/data/messages.db \ - "SELECT * FROM message_queue WHERE send_after <= strftime('%s','now');" -``` - ---- - -## 🤝 Contributing - -### Run a Node - -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. - -### Development - -```bash -# 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 -debug -``` - -### Submit Issues - -Found a bug? Have a feature request? [Open an issue](https://github.com/yourusername/fog/issues) - -### Security Vulnerabilities - -**Do not open public issues for security vulnerabilities.** - -Contact: security@fog.network (PGP key available) - ---- - -## 📚 Documentation - -- **[CHANGELOG.md](CHANGELOG.md)** - Version history and release notes -- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Technical design and protocol specification -- **[SECURITY.md](SECURITY.md)** - Security model and threat analysis -- **[API.md](API.md)** - SMTP protocol and message format - ---- - -## 🎓 How It Works - -### Sphinx Mixnet Overview - -``` -Client → Entry Node → Middle Node → Exit Node → Destination - (Hop 1) (Hop 2) (Hop 3) -``` - -**Each hop:** -1. Decrypts one layer of encryption -2. Cannot see final destination (onion routing) -3. Adds random delay before forwarding -4. Batches with other messages for mixing - -**At exit node:** -1. Final decryption reveals cleartext message -2. Headers are sanitized (From, Message-ID, Date randomized) -3. All identifying metadata removed -4. 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 - ---- - -## 📖 License - -MIT License - see [LICENSE](LICENSE) file for details. - ---- - -## 🙏 Acknowledgments - -- **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 - ---- - -## 📞 Contact - -- **Website**: https://yamn.virebent.art -- **Usenet**: alt.privacy.anon-server - ---- - -## ⚠️ Disclaimer - -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. - ---- - -<div align="center"> - -**🌫️ Join the fog network today and reclaim your digital privacy! 🌫️** - -[](https://github.com/yourusername/fog/releases) -[](https://fog.network/donate) - -</div> +# FOG + +Status: public design and evidence documentation + +This repository intentionally publishes documentation only. It contains no +production daemon, private deployment material, operator inventory, runtime +secret, or claim that FOG currently provides anonymity. The integrity of every +published Markdown file is committed by `merkle-tree.txt`. + +FOG will be an autonomous, modular network for asynchronous private +communication. Its initial native services will be one-way drops, anonymous +mailboxes, direct messages, and asynchronous chat. SOCKS, VPN, web proxying, +and public Internet exits are excluded from the current design. + +FOG is one coherent product, but its security roles remain separable: + +```text +offline Composer + | + | QR or FOG-SX one-way transfer + v +online blind relay + | +random temporary entry selected from signed FOG-PKI consensus + | +entry gateway + | +mix layer 1 -> mix layer 2 -> mix layer 3 + | +courier / native service + | +four or more distributed storage replicas + | +recipient blind relay + | +recipient Composer decrypts and verifies +``` + +The Composer encrypts each message for the recipient before it leaves the +offline environment. The blind relay, entry, mixes, courier, and storage never +receive plaintext. KEMSphinx protects routing through the mixnet, while Noise +protects each adjacent online connection. These layers use different keys and +do not replace one another. + +Contacts use private pairwise identities and targeted single-use vouchers, +not global usernames. The Composer persists each ratchet transition together +with its exact fixed message envelope before export. Storage then persists an +immutable box and courier request generation. Retransmission reuses those +storage bytes for deduplication but receives fresh route, KEMSphinx, entry, +rendezvous, and reply material. Authenticated message acknowledgments report +durable receiving-Composer commit, never that a human read the message. + +Each conversation direction uses a separate evolving capability stream. Two +final replicas store each pseudorandom box, while two disjoint intermediate +replicas prevent the courier from learning the final pair. At least four +independent storage replicas are required. Courier acceptance is not storage +durability; ordinary durability requires authenticated receipts from both +final replicas. Empty reads do not advance a stream, and signed tombstones +prevent data resurrection until bounded expiry. + +FOG uses one source tree and coordinated release, but each online security role +is a separate executable with its own identity, keys, writable state, account, +configuration, and network policy. The initial `fog-drop`, `fog-mailbox`, and +`fog-im` features run as Composer-side modules over one common messaging and +storage protocol, not as distinguishable public services. + +The Composer can run as a networkless microVM on an online host or as a +portable bootable USB system on a physically offline computer. High-assurance +transfer avoids USB shuttling and uses QR or `FOG-SX`, an acknowledgment-free +simplex protocol. The preferred physical FOG-SX backend is a one-way TOSLINK +fiber called `FOG Lightpipe`. FOG-SX fixes bounded padded objects and frames, +but its RaptorQ and Reed-Solomon FEC options and its QR, Lightpipe, and MIDI +physical profiles remain non-active pending implementation, hardware, and +resource review. Visible light, audio modem, and paper tape remain possible +future backends. + +Composer software boots from an authenticated read-only image and keeps +mutable secrets in a volume-encrypted, object-authenticated transactional +vault. Imports are hostile fixed bundles; exports contain only committed +opaque work. A local commitment chain is not presented as complete rollback +protection. That claim requires an independent monotonic anchor outside the +vault and host rollback domain. Identity recovery does not resume stale live +ratchets, capabilities, prekeys, or outboxes. + +An entry is never globally predefined. The blind relay randomly selects a +small temporary set from the signed consensus and rotates it by session or +epoch. It chooses only among opaque entry variants prepared by the Composer and +does not learn the first internal mix hop. The entry remains separate from the +three mix hops. Paths avoid using the same operator more than once. + +Three independent mix nodes are enough for a functional local PoC, not for +production anonymity. Six mix nodes are the minimum meaningful alpha target, +and nine mix nodes are the preferred initial network target. At least four +storage replicas and three independent directory authorities are also needed. + +FOG will use signed epoch consensus, fixed packet sizes, randomized mixing +delays, replay protection, traffic padding, decoy traffic, capability-based +mailboxes, safe retries, and privacy-minimizing logs. The current non-active +cryptographic shortlist uses SHA3-256 and mandatory ML-DSA-65 plus Ed25519 for +PKI evaluation, the exact HPQC ML-KEM-768 plus X25519 split-PRF construction +for the calculated KEMSphinx candidate, and PQXDH plus Triple Ratchet and +ML-KEM Braid for messaging. X-Wing leads the adjacent-link KEM evaluation, but +FOG has not selected an exact post-quantum Noise profile. + +`FOG-WIRE-1` protects adjacent online links with TCP and one exact +consensus-authorized Noise profile. Relay-to-entry connections authenticate +the entry without assigning the relay a stable Noise identity; all node, +authority, courier, storage, and observer links use mutual role-specific +authentication. A fixed preface and authenticated prologue bind the network, +epoch, consensus, roles, peers, keys, and adjacency. Encrypted records have one +fixed size per profile, rekey after every record, and force a fresh handshake +at bounded record, byte, time, epoch, profile, or authorization boundaries. +There is no runtime profile negotiation, 0-RTT, resumption, TLS fallback, or +generic RPC bus. + +`FOG-PKI-1` uses complete deterministic consensus documents with independent +M-of-N authority signatures. Authority roots stay offline and certify rotating +online voting keys. Consumers never merge partial directory views. Offline +Composers retain monotonic state and verify newer consensus through a +threshold-signed append-only checkpoint, archive inclusion, and a Merkle +consistency proof. The initial claim-bearing quorum is 2-of-3. + +FOG will preserve Sphinx-family application compatibility through a stable +client SDK and explicit, consensus-authorized packet profiles. Core nodes will +not auto-detect foreign Sphinx variants or negotiate packet suites. Bridges to +specific external mix networks remain isolated edge adapters with separately +documented cross-network correlation risks. + +The normative baselines are `docs/FOG-THREAT-MODEL.md`, +`docs/FOG-ARCHITECTURE.md`, `docs/FOG-PKI.md`, `docs/FOG-WIRE.md`, +`docs/FOG-SPHINX-PROFILES.md`, `docs/FOG-MESSAGING.md`, +`docs/FOG-STORAGE.md`, `docs/FOG-COMPOSER.md`, `docs/FOG-SX.md`, and +`docs/FOG-OBSERVABILITY.md`. +`docs/FOG-CRYPTO-SUITES.md` is the current non-normative selection and evidence +record. Cryptographic properties are tied to exact protocols and +implementations. All named cryptographic, messaging, and narrow +BACAP/Pigeonhole storage candidates remain non-active pending exact integration +evidence. Anonymity, unlinkability, and unobservability remain conditional on +measured traffic, cover, topology, operator independence, endpoint integrity, +and the stated adversary. The global passive observer is a simulation and +validation target, not a present guarantee. + +`docs/FOG-SIMULATION.md` records the first deterministic traffic and topology +comparison matrix. It confirms that the functional PoC and sparse traffic are +not anonymity evidence, and it selects no numeric cover, delay, polling, +topology, or degraded-mode profile. The remaining formal observer, storage, +loop, queue, behavior, churn, and trace-driven models precede any such +selection. + +`FOG-OBSERVABILITY-1` now fixes the structural operations boundary. Production +roles emit no packet or request event streams. They collect only closed typed +metrics in coarse windows, export bucketed fixed-shape aggregates after a +delay, suppress traffic-sensitive values under a minimum activity threshold, +and keep bounded local summaries. The Composer and FOG-SX roles have no +automatic observer path. A public view requires multi-reporter aggregation, +fixed grouping, delayed non-overlapping windows, low-population suppression, +and anti-differencing review. No numeric observability profile or observer +service is active. + +Development proceeds from specifications and simulation through functional +fixtures, fault injection, an independent-operator alpha, and external review +before any real anonymity claim. + +`docs/FOG-LOCAL-POC.md`, `docs/FOG-SECURITY-TEST-PLAN.md`, and +`docs/FOG-ALPHA.md` describe the functional test boundaries and the next +transition without pretending that local containers are independent +operators. A reproducible local six-mix laboratory has completed its 13 fault +families, but it remains a non-cryptographic functional fixture. No FOG +protocol daemon or public network exists. The 19 distributed-alpha evidence +gates remain open pending active profiles, real daemons, governance, +independent operators, independent reproduction, and review. + +Supporting documents cover cryptographic evaluation, simulation, local PoC +constraints, security testing, alpha readiness, and PoC preservation. The +implementation and raw test workspace are deliberately outside this +documentation-only publication. |
