A high-speed covert tunnel that disguises TCP traffic as SMTP email communication to bypass Deep Packet Inspection (DPI) firewalls.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ Application │─────▶│ Client │─────▶│ Server │─────▶│ Internet │
│ (Browser) │ TCP │ SOCKS5:1080 │ SMTP │ Port 587 │ TCP │ │
│ │◀─────│ │◀─────│ │◀─────│ │
└─────────────┘ └─────────────┘ └─────────────┘ └──────────────┘
│ │
│ Looks like │
│ Email Traffic │
▼ ▼
┌────────────────────────────────┐
│ DPI Firewall │
│ ✅ Sees: Normal SMTP Session │
│ ❌ Cannot see: Tunnel Data │
└────────────────────────────────┘
🎯 Features
| Feature | Description |
|---|---|
| 🔒 TLS Encryption | All traffic encrypted with TLS 1.2+ after STARTTLS |
| 🎭 DPI Evasion | Initial handshake mimics real SMTP servers (Postfix) |
| ⚡ High Speed | Binary streaming protocol after handshake - minimal overhead |
| 👥 Multi-User | Per-user secrets, IP whitelists, and logging settings |
| 🔑 Authentication | Per-user pre-shared keys with HMAC-SHA256 |
| 🌐 SOCKS5 Proxy | Standard proxy interface - works with any application |
| 📡 Multiplexing | Multiple connections over single tunnel |
| 🛡️ IP Whitelist | Per-user access control by IP address/CIDR |
| 📦 Easy Install | One-liner server installation with systemd service |
| 🎁 Client Packages | Auto-generated ZIP files for each user |
| 🔄 Auto-Reconnect | Client automatically reconnects on connection loss |
📚 For in-depth technical details, protocol specifications, and security analysis, see TECHNICAL.md.
⚡ Quick Start
📋 Prerequisites
- Server: Linux VPS with Python 3.8+, port 587 open
- Client: Windows/macOS/Linux with Python 3.8+
- Domain name: Required for TLS certificate verification (free options: DuckDNS, No-IP, FreeDNS)
🚀 Server Setup (VPS)
Step 1️⃣: Get a Domain Name
Get a free domain pointing to your VPS:
- 🦆 DuckDNS - Recommended, simple and free
- 🌐 No-IP - Free tier available
- 🆓 FreeDNS - Many domain options
Example: myserver.duckdns.org → 203.0.113.50 (your VPS IP)
Step 2️⃣: Run the Installer
curl -sSL https://raw.githubusercontent.com/x011/smtp-tunnel-proxy/main/install.sh | sudo bashThe installer will:
- 📥 Download and install everything
- ❓ Ask for your domain name
- 🔐 Generate TLS certificates automatically
- 👤 Offer to create your first user
- 🔥 Configure firewall
- 🚀 Start the service
That's it! Your server is ready.
➕ Add More Users Later
smtp-tunnel-adduser bob # Add user + generate client ZIP smtp-tunnel-listusers # List all users smtp-tunnel-deluser bob # Remove a user
🔄 Update Server
smtp-tunnel-update # Updates code, preserves config/certs/users💻 Client Setup
Option A: Easy Way (Recommended)
- Get your
username.zipfile from the server admin - Extract the ZIP file
- Run the launcher:
| Platform | How to Run |
|---|---|
| 🪟 Windows | Double-click start.bat |
| 🐧 Linux | Run ./start.sh |
| 🍎 macOS | Run ./start.sh |
The launcher will automatically install dependencies and start the client.
✅ You should see:
SMTP Tunnel Proxy Client
User: alice
[INFO] Starting SMTP Tunnel...
[INFO] SOCKS5 proxy will be available at 127.0.0.1:1080
Connecting to myserver.duckdns.org:587
Connected - binary mode active
SOCKS5 proxy on 127.0.0.1:1080
Option B: Manual Way
cd alice
pip install -r requirements.txt
python client.pyOption C: Custom Configuration
# Download files scp root@myserver.duckdns.org:/etc/smtp-tunnel/ca.crt . # Create config.yaml: cat > config.yaml << EOF client: server_host: "myserver.duckdns.org" server_port: 587 socks_port: 1080 username: "alice" secret: "your-secret-from-admin" ca_cert: "ca.crt" EOF # Run client python client.py -c config.yaml
📖 Usage
🌐 Configure Your Applications
Set SOCKS5 proxy to: 127.0.0.1:1080
🦊 Firefox
- Settings → Network Settings → Settings
- Manual proxy configuration
- SOCKS Host:
127.0.0.1, Port:1080 - Select SOCKS v5
- ✅ Check "Proxy DNS when using SOCKS v5"
🌐 Chrome
- Install "Proxy SwitchyOmega" extension
- Create profile with SOCKS5:
127.0.0.1:1080
🪟 Windows (System-wide)
Settings → Network & Internet → Proxy → Manual setup → socks=127.0.0.1:1080
🍎 macOS (System-wide)
System Preferences → Network → Advanced → Proxies → SOCKS Proxy → 127.0.0.1:1080
🐧 Linux (System-wide)
export ALL_PROXY=socks5://127.0.0.1:1080💻 Command Line
# curl curl -x socks5h://127.0.0.1:1080 https://ifconfig.me # git git config --global http.proxy socks5://127.0.0.1:1080 # Environment variable export ALL_PROXY=socks5://127.0.0.1:1080
✅ Test Connection
# Should show your VPS IP
curl -x socks5://127.0.0.1:1080 https://ifconfig.me⚙️ Configuration Reference
🖥️ Server Options (config.yaml)
| Option | Description | Default |
|---|---|---|
host |
Listen interface | 0.0.0.0 |
port |
Listen port | 587 |
hostname |
SMTP hostname (must match certificate) | mail.example.com |
cert_file |
TLS certificate path | server.crt |
key_file |
TLS private key path | server.key |
users_file |
Path to users configuration | users.yaml |
log_users |
Global logging setting | true |
👥 User Options (users.yaml)
Each user can have individual settings:
users: alice: secret: "auto-generated-secret" # whitelist: # Optional: restrict to specific IPs # - "192.168.1.100" # - "10.0.0.0/8" # CIDR notation supported # logging: true # Optional: disable to stop logging this user bob: secret: "another-secret" whitelist: - "203.0.113.50" # Bob can only connect from this IP logging: false # Don't log Bob's activity
| Option | Description | Default |
|---|---|---|
secret |
User's authentication secret | Required |
whitelist |
Allowed IPs for this user (CIDR supported) | All IPs |
logging |
Enable activity logging for this user | true |
💻 Client Options
| Option | Description | Default |
|---|---|---|
server_host |
Server domain name | Required |
server_port |
Server port | 587 |
socks_port |
Local SOCKS5 port | 1080 |
socks_host |
Local SOCKS5 interface | 127.0.0.1 |
username |
Your username | Required |
secret |
Your authentication secret | Required |
ca_cert |
CA certificate for verification | Recommended |
📋 Service Management
# Check status sudo systemctl status smtp-tunnel # Restart after config changes sudo systemctl restart smtp-tunnel # View logs sudo journalctl -u smtp-tunnel -n 100 # Uninstall sudo /opt/smtp-tunnel/uninstall.sh
🔧 Command Line Options
🖥️ Server
python server.py [-c CONFIG] [-d] -c, --config Config file (default: config.yaml) -d, --debug Enable debug logging
💻 Client
python client.py [-c CONFIG] [--server HOST] [--server-port PORT]
[-p SOCKS_PORT] [-u USERNAME] [-s SECRET] [--ca-cert FILE] [-d]
-c, --config Config file (default: config.yaml)
--server Override server domain
--server-port Override server port
-p, --socks-port Override local SOCKS port
-u, --username Your username
-s, --secret Override secret
--ca-cert CA certificate path
-d, --debug Enable debug logging👥 User Management
smtp-tunnel-adduser <username> [-u USERS_FILE] [-c CONFIG] [--no-zip] Add a new user and generate client package smtp-tunnel-deluser <username> [-u USERS_FILE] [-f] Remove a user (use -f to skip confirmation) smtp-tunnel-listusers [-u USERS_FILE] [-v] List all users (use -v for detailed info) smtp-tunnel-update Update server to latest version (preserves config/certs/users)
📁 File Structure
smtp_proxy/
├── 📄 server.py # Server (runs on VPS)
├── 📄 client.py # Client (runs locally)
├── 📄 common.py # Shared utilities
├── 📄 generate_certs.py # Certificate generator
├── 📄 config.yaml # Server/client configuration
├── 📄 users.yaml # User database
├── 📄 requirements.txt # Python dependencies
├── 📄 install.sh # One-liner server installer
├── 📄 smtp-tunnel.service # Systemd unit file
├── 🔧 smtp-tunnel-adduser # Add user script
├── 🔧 smtp-tunnel-deluser # Remove user script
├── 🔧 smtp-tunnel-listusers # List users script
├── 🔧 smtp-tunnel-update # Update server script
├── 📄 README.md # This file
└── 📄 TECHNICAL.md # Technical documentation
📦 Installation Paths (after install.sh)
/opt/smtp-tunnel/ # Application files
/etc/smtp-tunnel/ # Configuration files
├── config.yaml
├── users.yaml
├── server.crt
├── server.key
└── ca.crt
/usr/local/bin/ # Management commands
├── smtp-tunnel-adduser
├── smtp-tunnel-deluser
├── smtp-tunnel-listusers
└── smtp-tunnel-update
🔧 Troubleshooting
❌ "Connection refused"
- Check server is running:
systemctl status smtp-tunnelorps aux | grep server.py - Check port is open:
netstat -tlnp | grep 587 - Check firewall:
ufw status
❌ "Auth failed"
- Verify
usernameandsecretmatch in users.yaml - Check server time is accurate (within 5 minutes)
- Run
smtp-tunnel-listusers -vto verify user exists
❌ "IP not whitelisted"
- Check user's whitelist in users.yaml
- Your current IP must match a whitelist entry
- CIDR notation is supported (e.g.,
10.0.0.0/8)
❌ "Certificate verify failed"
- Ensure you're using a domain name, not IP address
- Verify
server_hostmatches the certificate hostname - Ensure you have the correct
ca.crtfrom the server
🐛 Debug Mode
# Enable detailed logging python server.py -d python client.py -d # View systemd logs journalctl -u smtp-tunnel -f
🔐 Security Notes
- ✅ Always use a domain name for proper TLS verification
- ✅ Always use
ca_certto prevent man-in-the-middle attacks - ✅ Use
smtp-tunnel-adduserto generate strong secrets automatically - ✅ Use per-user IP whitelists if you know client IPs
- ✅ Protect
users.yaml- contains all user secrets (chmod 600) - ✅ Disable logging for sensitive users with
logging: false
📚 For detailed security analysis and threat model, see TECHNICAL.md.
📄 License
This project is provided for educational and authorized use only. Use responsibly and in accordance with applicable laws.
⚠️ Disclaimer
This tool is designed for legitimate privacy and censorship circumvention purposes. Users are responsible for ensuring their use complies with applicable laws and regulations.
Made with ❤️ for internet freedom