BaleTunnel is a network tunneling tool that leverages the infrastructure of Bale Messenger combined with the WebRTC protocol to bypass heavy internet restrictions. Network traffic is transmitted through LiveKit's encrypted DataChannel and appears as a regular voice call within the Bale platform.
- Network traffic tunneling via WebRTC DataChannel
- End-to-end encryption powered by LiveKit
- SOCKS5 proxy for routing application traffic
- Server and client operating modes
- Access control system (allow-list / block-list)
- Configurable per-client bandwidth limits
- Interactive command-line interface (CLI)
- Cross-platform: Windows, Linux, and macOS
- No GUI required
- Python 3.10 or higher
- An active Bale Messenger account
cd BaleTunnel
pip install -r requirements.txtpython src/app.py serverThen enter the login command and authenticate with your phone number.
python src/app.py client --port 1080After logging in, use peers to list contacts and connect <server_id> to establish a tunnel to the server.
| Command | Mode | Description |
|---|---|---|
login |
Both | Log in with phone number |
logout |
Both | Log out |
status |
Both | Show connection status |
peers |
Both | List contacts |
connect <id> |
Client | Connect to a server |
disconnect |
Both | Disconnect |
pending |
Server | Show pending requests |
accept <id> [--save] |
Server | Accept a request |
reject <id> [--block] |
Server | Reject a request |
clients |
Server | Show connected clients |
kick <key> |
Server | Disconnect a client |
allow <uid> |
Server | Add to allow-list |
block <uid> |
Server | Block a user |
unblock <uid> |
Server | Unblock a user |
admission |
Server | Show allow-list |
blacklist |
Server | Show block-list |
exit |
Both | Exit the application |
Once the tunnel is established, a SOCKS5 proxy becomes available on the specified port:
curl --socks5-hostname 127.0.0.1:1080 http://ifconfig.meConfigure your browser or OS proxy settings to use SOCKS5 at 127.0.0.1:1080. Enabling "Proxy DNS" (remote DNS resolution) is required.
The following results were obtained during real-world testing:
| Parameter | Details |
|---|---|
| Server location | Infomaniak, Switzerland |
| Client connection | Iranian ADSL (Mokhaberat / TCI) |
| Download speed | 8–12 Mbps |
| Upload speed | Not measured |
| Latency | 120–170 ms |
Note: Performance depends on network conditions, server load, and ISP throttling. Results may vary.
BaleTunnel/
├── src/
│ ├── app.py # Entry point and CLI
│ ├── ws_client.py # WebSocket connection manager
│ ├── relay.py # Tunnel engine and SOCKS5 proxy
│ ├── transport.py # LiveKit transport layer
│ ├── protocol.py # Protobuf codecs
│ ├── rpc.py # gRPC-web calls
│ ├── persistence.py # Configuration storage
│ ├── settings.py # Constants and configuration
│ └── ca_bundle.pem # SSL certificate bundle
├── docs/
│ ├── guide-fa.md # Persian documentation
│ └── guide-en.md # English documentation
├── requirements.txt
├── .gitignore
└── README.md
- The WebRTC connection operates independently of the WebSocket signaling channel. If the WebSocket drops temporarily, the active tunnel remains intact.
- Configuration is automatically persisted in the application's working directory.
- The internal SNAT system supports up to 253 concurrent client connections.
- An egress filter prevents access to private and loopback addresses from the tunnel.
Developed by Ermia
Documentation for this project was written with the assistance of Claude Sonnet 4.6.
For questions and suggestions:
- Telegram: @theermia
- Channel: @thisisermia
This project was developed in response to the severe internet restrictions imposed in Iran. It only functions when voice calls through Bale Messenger can be established via an overseas server.
Hoping for better days for Iran.
MIT License