A high-speed covert tunnel that disguises TCP/UDP traffic as SMTP email communication to bypass Deep Packet Inspection (DPI) firewalls.
βββββββββββββββ βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β Application βββββββΆβ Client βββββββΆβ Server βββββββΆβ Internet β
β (Browser) β TCP β SOCKS5:1080 β SMTP β Port 587 β TCP β β
β ββββββββ FWD:8080 ββββββββ ββββββββ β
βββββββββββββββ βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β β
β Looks like β
β Email Traffic β
βΌ βΌ
ββββββββββββββββββββββββββββββββββ
β DPI Firewall β
β β
Sees: Normal SMTP Session β
β β Cannot see: Tunnel Data β
ββββββββββββββββββββββββββββββββββ
| Feature | Description |
|---|---|
| π TLS Encryption | All traffic encrypted with TLS 1.2+ after SMTP STARTTLS |
| π DPI Evasion | Handshake mimics Postfix SMTP servers; supports traffic shaping |
| β‘ High Performance | Native Go implementation with binary multiplexing protocol |
| π₯ User Management | Built-in CLI for managing users, secrets, and whitelists |
| π Secure Auth | HMAC-SHA256 authenticated tokens with anti-replay protection |
| π SOCKS5 Proxy | Multiple local SOCKS5 listeners per client |
| π Port Forwarding | TCP/UDP forwarding for direct traffic redirection |
| π‘οΈ Stealth Mode | Configurable random delays, packet padding, and dummy traffic |
| π¦ Service Ready | Built-in systemd service management |
| π§ Setup Wizard | Interactive configuration generator for quick setup |
git clone https://github.com/youruser/smtptunnel.git
cd smtptunnel
make buildThis produces smtptunnel-server and smtptunnel-client.
System-wide installation (requires root):
# Via Makefile:
sudo make install
# Or via the binary itself:
sudo ./smtptunnel-server install
sudo ./smtptunnel-client installThe install command:
- Copies the binary to
/usr/local/bin/ - Creates
/etc/smtptunnel/(base configuration directory) - Creates
/etc/smtptunnel/configs/(per-instance configuration files) - Creates
/etc/smtptunnel/certs/(generated TLS certificates)
The wizard command walks you through the entire configuration process interactively:
Server:
smtptunnel-server wizardThe wizard will:
- Ask for your server hostname (e.g.,
mail.example.com) - Ask for the listen address (default:
0.0.0.0:587) - Generate TLS certificates automatically in
/etc/smtptunnel/certs/<hostname>/- Or let you select existing certificate files
- Create users with auto-generated secrets
- Configure stealth/DPI evasion settings
- Output a ready-to-use
config_<random_id>.tomlfile
Client:
smtptunnel-client wizardThe wizard will:
- Ask for the server address and credentials
- Configure TLS certificate verification
- Set up SOCKS5 proxy listeners
- Set up port forwarding rules (optional)
- Configure stealth settings
- Output a ready-to-use
config_<random_id>.tomlfile
-
Generate Certificates:
smtptunnel-server gencerts -hostname mail.example.com
Certificates are saved to
/etc/smtptunnel/certs/mail.example.com/by default. Use-output-dir <path>to specify a custom location. -
Add a User:
smtptunnel-server adduser alice -c config.toml
A secret is auto-generated and printed. Share this with the client user.
-
Start Server:
smtptunnel-server run -c config.toml
- Copy
ca.crtfrom the server's cert directory to the client machine. - Edit
config.tomlwith server address, username, and secret. - Configure SOCKS5 proxies and/or port forwarding rules.
- Connect:
smtptunnel-client run -c config.toml
The project uses a unified TOML configuration file. Below is a complete reference with all available options.
[server]
listen = "0.0.0.0:587" # Interface and port to listen on
hostname = "mail.example.com" # SMTP banner hostname (should match SSL cert)
cert_file = "/etc/smtptunnel/certs/mail.example.com/server.crt"
key_file = "/etc/smtptunnel/certs/mail.example.com/server.key"
log_level = "info" # Logging level: info, debug, warn| Field | Required | Default | Description |
|---|---|---|---|
listen |
Yes | 0.0.0.0:587 |
Address and port to bind |
hostname |
Yes | mail.example.com |
SMTP banner hostname |
cert_file |
Yes | β | Path to TLS server certificate |
key_file |
Yes | β | Path to TLS server private key |
log_level |
No | info |
Logging verbosity |
[server.tls]
min_version = "1.2" # Minimum TLS versionEach user has a username, secret, optional IP whitelist, and logging flag.
[[server.users]]
username = "alice"
secret = "generated-base64url-secret"
whitelist = ["0.0.0.0/0"] # Allow all IPs (default)
logging = true # Enable traffic logging| Field | Required | Default | Description |
|---|---|---|---|
username |
Yes | β | Unique username |
secret |
Yes | β | Shared secret (auto-generated with adduser) |
whitelist |
No | ["0.0.0.0/0"] |
Allowed client IP ranges (CIDR or single IP) |
logging |
No | true |
Whether to log this user's connections |
You can add multiple [[server.users]] blocks. Users can also be managed via CLI:
smtptunnel-server adduser <name> -c config.toml
smtptunnel-server deluser <name> -c config.toml
smtptunnel-server listusers -c config.toml [-v][client]
server = "mail.example.com:587"
username = "alice"
secret = "the-secret-from-adduser"
ca_cert = "ca.crt"
insecure_skip_verify = false
reconnect_delay = "2s"
max_reconnect_delay = "30s"| Field | Required | Default | Description |
|---|---|---|---|
server |
Yes | β | Server address (host:port) |
username |
Yes | β | Authentication username |
secret |
Yes | β | Shared authentication secret |
ca_cert |
No | β | Path to CA certificate for TLS verification |
insecure_skip_verify |
No | false |
Skip certificate validation (not recommended) |
reconnect_delay |
No | 2s |
Initial reconnection delay |
max_reconnect_delay |
No | 30s |
Maximum reconnection delay (exponential backoff) |
Define one or more local SOCKS5 proxy endpoints:
[[client.socks]]
listen = "127.0.0.1:1080"
username = "" # Optional SOCKS5 authentication
password = ""| Field | Required | Default | Description |
|---|---|---|---|
listen |
Yes | β | Local address:port to listen on |
username |
No | β | SOCKS5 auth username (empty = no auth) |
password |
No | β | SOCKS5 auth password |
Usage with applications:
# curl
curl -x socks5h://127.0.0.1:1080 https://ifconfig.me
# Firefox: Settings β Network β Manual Proxy β SOCKS Host: 127.0.0.1, Port: 1080
# SSH
ssh -o ProxyCommand='nc -x 127.0.0.1:1080 %h %p' user@remoteDefine one or more port forwarding rules for direct traffic redirection. Traffic received on the local listen address is forwarded through the tunnel to the remote forward destination.
[[client.forward]]
listen = "127.0.0.1:8080" # Local listen address
forward = "internal-server:80" # Remote destination through tunnel
protocol = "tcp" # "tcp" or "udp"| Field | Required | Default | Description |
|---|---|---|---|
listen |
Yes | β | Local address:port to listen on |
forward |
Yes | β | Remote destination host:port (resolved on server side) |
protocol |
No | tcp |
Protocol: tcp or udp |
Examples:
# Forward local port 3306 to a remote MySQL server
[[client.forward]]
listen = "127.0.0.1:3306"
forward = "db.internal:3306"
protocol = "tcp"
# Forward local port 8443 to a remote HTTPS server
[[client.forward]]
listen = "127.0.0.1:8443"
forward = "web.internal:443"
protocol = "tcp"
# Forward UDP traffic (e.g., DNS)
[[client.forward]]
listen = "127.0.0.1:5353"
forward = "8.8.8.8:53"
protocol = "udp"When to use forward vs SOCKS5:
- Use SOCKS5 when applications support SOCKS proxy (browsers, curl, etc.) and you want to access any destination dynamically.
- Use forward for applications that don't support SOCKS, or when you want a fixed local-to-remote port mapping (database connections, RDP, custom protocols, UDP traffic).
[stealth]
enabled = true
min_delay_ms = 50
max_delay_ms = 500
padding_sizes = [4096, 8192, 16384, 32768]
dummy_probability = 0.1| Field | Required | Default | Description |
|---|---|---|---|
enabled |
No | true |
Enable traffic shaping and padding |
min_delay_ms |
No | 50 |
Minimum random delay between packet groups (ms) |
max_delay_ms |
No | 500 |
Maximum random delay between packet groups (ms) |
padding_sizes |
No | [4096, ...] |
Target packet sizes for padding |
dummy_probability |
No | 0.1 |
Probability (0.0β1.0) of sending dummy packets during idle |
| Command | Description |
|---|---|
run -c <config> |
Start the tunnel server |
adduser <name> -c <config> |
Add a new user with auto-generated secret |
deluser <name> -c <config> |
Remove a user |
listusers -c <config> [-v] |
List all users (add -v for details) |
gencerts -hostname <host> |
Generate CA + server TLS certificates |
check-config -c <config> |
Validate configuration file |
install |
Install binary to /usr/local/bin/ and create directories |
wizard |
Interactive configuration generator |
service install <config> |
Register config as a systemd service |
service list |
List all registered smtptunnel services |
service remove <name> |
Stop, disable, and remove a service |
service logs <name> [-n N] |
View last N log lines (default: 50) |
service stop <name> |
Stop a running service |
service restart <name> |
Restart a service |
version |
Show version |
| Command | Description |
|---|---|
run -c <config> |
Connect and start SOCKS5/forward proxies |
ping -c <config> [-n N] |
Measure RTT latency (N pings, default: 4) |
status -c <config> |
Connection diagnostics |
check-config -c <config> |
Validate configuration file |
install |
Install binary to /usr/local/bin/ and create directories |
wizard |
Interactive configuration generator |
service install <config> |
Register config as a systemd service |
service list |
List all registered smtptunnel services |
service remove <name> |
Stop, disable, and remove a service |
service logs <name> [-n N] |
View last N log lines (default: 50) |
service stop <name> |
Stop a running service |
service restart <name> |
Restart a service |
version |
Show version |
The service command group provides full lifecycle management of systemd services.
# After generating a config (via wizard or manually):
sudo smtptunnel-server service install config_abc123.tomlThis will:
- Copy the config file to
/etc/smtptunnel/configs/config_abc123.toml - Create a systemd unit file at
/etc/systemd/system/smtptunnel-server-config_abc123.service - Run
systemctl daemon-reload - Enable and start the service immediately
# List all registered services with their status
sudo smtptunnel-server service list
# View logs (last 100 lines)
sudo smtptunnel-server service logs smtptunnel-server-config_abc123 -n 100
# Stop a service
sudo smtptunnel-server service stop smtptunnel-server-config_abc123
# Restart a service
sudo smtptunnel-server service restart smtptunnel-server-config_abc123
# Completely remove a service (stops, disables, deletes unit file)
sudo smtptunnel-server service remove smtptunnel-server-config_abc123You can run multiple tunnel instances simultaneously by registering different configs:
# Create multiple configs via wizard
smtptunnel-server wizard # -> config_aaa111.toml
smtptunnel-server wizard # -> config_bbb222.toml
# Register each as a separate service
sudo smtptunnel-server service install config_aaa111.toml
sudo smtptunnel-server service install config_bbb222.toml
# List all running instances
sudo smtptunnel-server service listThe wizard provides a guided, interactive setup experience. It is the recommended way to create configuration files.
smtptunnel-server wizardWhat it does:
- Hostname β Asks for the SMTP hostname (e.g.,
mail.example.com) - Listen address β Server bind address (default:
0.0.0.0:587) - Certificates β Checks if certs exist at
/etc/smtptunnel/certs/<hostname>/:- If yes: asks whether to reuse or regenerate
- If no: offers to generate new CA + server certificates automatically
- Or: lets you specify paths to existing certificate files
- Users β Creates one or more users with auto-generated secrets
- Stealth β Configures DPI evasion settings
- Output β Writes
config_<random_id>.tomlin the current directory
smtptunnel-client wizardWhat it does:
- Server address β Remote server
host:port - Credentials β Username and secret (from the server's
adduseroutput) - TLS β Path to CA certificate or skip for insecure mode
- SOCKS5 proxies β Add one or more local SOCKS5 listeners
- Port forwarding β Add TCP/UDP forwarding rules
- Stealth β DPI evasion settings
- Output β Writes
config_<random_id>.tomlin the current directory
The forward feature allows transparent port forwarding through the tunnel, complementing the SOCKS5 proxy. This is useful for:
- Applications that don't support SOCKS proxies
- Fixed port mappings (databases, internal APIs, RDP)
- UDP traffic forwarding (DNS, game servers, etc.)
ββββββββββββ βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββ
β App ββββββΆβ Client Forward ββββββΆβ SMTP Tunnel ββββββΆβ Destination β
β :3306 βTCP β 127.0.0.1:3306 βSMTP β Server βTCP β db.internal β
β βββββββ βββββββ βββββββ :3306 β
ββββββββββββ βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββ
- Client listens on the local
listenaddress - When a connection arrives, it opens a tunnel channel to
forwarddestination - Data flows bidirectionally through the encrypted SMTP tunnel
- On the server side, the connection is made to the final destination
# Access a remote database through the tunnel
[[client.forward]]
listen = "127.0.0.1:3306"
forward = "mysql.internal:3306"
protocol = "tcp"
# Access a remote web application
[[client.forward]]
listen = "127.0.0.1:8080"
forward = "webapp.internal:80"
protocol = "tcp"Then connect your application to 127.0.0.1:3306 as if the database were local.
The tunnel establishes a legitimate-looking SMTP session:
- Server sends
220 ESMTPbanner (mimics Postfix). - Client sends
EHLO. - Server offers
STARTTLS. - TLS handshake completed.
- Client authenticates via a custom
AUTH PLAINtoken (HMAC-SHA256). - Communication switches to binary mode for data streaming.
After the handshake, the tunnel uses an efficient binary framing protocol:
| Field | Size | Description |
|---|---|---|
| Type | 1 byte | Frame type (DATA, CONNECT, CLOSE, PING, PONG) |
| Channel ID | 2 bytes | Multiplexed channel identifier |
| Payload Length | 2 bytes | Length of payload data |
| Payload | N bytes | Frame data |
Supported frame types:
DATA (0x01)β Tunnel dataCONNECT (0x02)β Open a new channelCONNECT_OK (0x03)β Channel opened successfullyCONNECT_FAIL (0x04)β Channel open failedCLOSE (0x05)β Close a channelPING (0x06)/PONG (0x07)β Latency measurement
- Transport layer: TLS 1.2+ (via SMTP STARTTLS)
- Application layer: ChaCha20-Poly1305 (defense-in-depth)
- Key derivation: HKDF-SHA256 with per-direction keys
- Authentication: HMAC-SHA256 tokens with timestamp-based anti-replay
/usr/local/bin/
βββ smtptunnel-server # Server binary
βββ smtptunnel-client # Client binary
/etc/smtptunnel/
βββ configs/ # Per-instance configuration files
β βββ config_abc123.toml # Registered service configs
β βββ config_def456.toml
βββ certs/ # TLS certificates by hostname
βββ mail.example.com/
βββ ca.key # CA private key
βββ ca.crt # CA certificate (copy to clients)
βββ server.key # Server private key
βββ server.crt # Server certificate
This section provides a complete, step-by-step guide for setting up a tunnel from scratch.
git clone https://github.com/youruser/smtptunnel.git
cd smtptunnel
make build
sudo ./smtptunnel-server install # On server
sudo ./smtptunnel-client install # On clientOption A β Wizard (recommended):
sudo smtptunnel-server wizardFollow the prompts. Note the generated username and secret.
Option B β Manual:
# Generate certificates
sudo smtptunnel-server gencerts -hostname mail.yourdomain.com
# Create config
cat > server-config.toml << 'EOF'
[server]
listen = "0.0.0.0:587"
hostname = "mail.yourdomain.com"
cert_file = "/etc/smtptunnel/certs/mail.yourdomain.com/server.crt"
key_file = "/etc/smtptunnel/certs/mail.yourdomain.com/server.key"
log_level = "info"
[server.tls]
min_version = "1.2"
[stealth]
enabled = true
min_delay_ms = 50
max_delay_ms = 500
padding_sizes = [4096, 8192, 16384, 32768]
dummy_probability = 0.1
EOF
# Add a user
sudo smtptunnel-server adduser alice -c server-config.toml
# Note the generated secret!sudo smtptunnel-server service install server-config.tomlThe server is now running and will auto-start on boot.
Copy /etc/smtptunnel/certs/mail.yourdomain.com/ca.crt from the server to the client machine.
Option A β Wizard (recommended):
smtptunnel-client wizardEnter the server address, username, and secret when prompted.
Option B β Manual:
# client-config.toml
[client]
server = "your-server-ip:587"
username = "alice"
secret = "the-secret-from-step-2"
ca_cert = "/path/to/ca.crt"
insecure_skip_verify = false
reconnect_delay = "2s"
max_reconnect_delay = "30s"
# SOCKS5 proxy for general browsing
[[client.socks]]
listen = "127.0.0.1:1080"
# Port forward for database access
[[client.forward]]
listen = "127.0.0.1:3306"
forward = "db.internal:3306"
protocol = "tcp"
[stealth]
enabled = true
min_delay_ms = 50
max_delay_ms = 500
padding_sizes = [4096, 8192, 16384, 32768]
dummy_probability = 0.1# Direct run:
smtptunnel-client run -c client-config.toml
# Or register as service:
sudo smtptunnel-client service install client-config.toml# Test SOCKS5 proxy
curl -x socks5h://127.0.0.1:1080 https://ifconfig.me
# Test port forwarding
mysql -h 127.0.0.1 -P 3306 -u dbuser -p
# Ping through tunnel
smtptunnel-client ping -c client-config.toml
# Check connection status
smtptunnel-client status -c client-config.tomlEducational and authorized use only. Use responsibly.