A lightweight reverse tunnel solution that allows an internet-isolated computer to access the web through another computer with internet access.
File Names:
- tunnel_on_b: Server (Computer B - internet-isolated)
- tunnel_on_a: Client (Computer A - internet-connected)
Scenario:
- Computer B: No internet access, has admin rights, can listen on ports
- Computer A: Has internet access, limited privileges, cannot listen on ports
- Goal: Enable Computer B to browse the web and access internet services
Traditional solutions don't work because:
- Computer A can't run a server (no admin rights)
- Standard proxies require the proxy server to have internet access
- VPNs require server-side listening, which Computer A can't do
This project implements a reverse tunnel architecture:
- Computer B acts as the server (listens on ports)
- Computer A acts as the client (connects outbound)
- Traffic flows: B → A → Internet → A → B
┌─────────────────────────────────────────────────────────────┐
│ Computer B (No Internet, Admin Rights) │
│ Runs: tunnel_on_b.py │
│ │
│ ┌──────────────┐ ┌───────────────────────────────┐ │
│ │ Applications │─────→│ tunnel_on_b (SOCKS Proxy) │ │
│ │ (Browser, │ │ - Listens: 127.0.0.1:3128 │ │
│ │ VS Code) │ │ - WebSocket: 0.0.0.0:3000 │ │
│ └──────────────┘ └───────────────────────────────┘ │
│ ↕ │
└───────────────────────────────────────────────────────────────┘
│
(Local Network Connection)
│
┌─────────────────────────────────────────────────────────────┐
│ Computer A (Internet Access, Limited Privileges) │
│ Runs: tunnel_on_a.py │
│ ↕ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ tunnel_on_a (Forwarder) │ │
│ │ - Connects to tunnel_on_b WebSocket │ │
│ │ - Forwards requests to internet │ │
│ │ - Returns responses │ │
│ └───────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌─────────────────────────────────────────┐ │
│ │ Internet / Web Services │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- ✅ SOCKS5 Proxy: Standard protocol, works with browsers and most applications
- ✅ WebSocket Tunnel: Reliable bidirectional communication
- ✅ Automatic Reconnection: A-Client automatically reconnects on connection drop
- ✅ Multiple Connections: Handles concurrent connections efficiently
- ✅ Stream Multiplexing: Multiple requests over a single WebSocket connection
- ✅ Lightweight: Pure Python, minimal dependencies
- ✅ Cross-Platform Ready: Designed for Windows, Linux support planned
- Python 3.7+
- websockets library (
conda install -c conda-forge websockets) - Local network connectivity between Computer A and B
# Copy example settings
copy settings.example.json settings.json # Windows
cp settings.example.json settings.json # Linux/Mac
# Edit settings.json with Computer B's IP address
# Update both b_ip_address and b_server_address fieldspython tunnel_on_b.pypython tunnel_on_a.py- SOCKS Proxy:
127.0.0.1:3128 - Protocol: SOCKS5
For detailed setup instructions, see SETUP.md.
TempoRemote/
├── README.md # Project overview (this file)
├── SETUP.md # Detailed setup instructions
├── .gitignore # Git ignore rules
├── settings.example.json # Example configuration (copy to settings.json)
├── settings.json # Your local configuration (gitignored)
├── tunnel_on_a.py # Computer A - Client forwarder (with internet)
├── tunnel_on_b.py # Computer B - Server with SOCKS proxy (isolated)
├── tests/
│ ├── A/ # Tests for Computer A
│ │ ├── probe.py # Connectivity diagnostics (A → B)
│ │ └── test_connectivity.py # Internet access test
│ ├── B/ # Tests for Computer B
│ │ ├── test_bind.py # WebSocket port binding test
│ │ └── test_b_local.py # Local server connectivity test
│ └── utils/ # Shared utilities
│ └── check_ip.py # IP address checker
└── .claude/ # Claude AI configuration
└── plan.md # Original project plan
-
WebSocket Server (port 3000):
- Listens for connection from Computer A
- Maintains persistent connection
- Multiplexes multiple streams
-
SOCKS5 Proxy (port 3128):
- Applications connect here
- Parses SOCKS5 protocol
- Forwards requests through WebSocket tunnel to A
-
Stream Management:
- Each SOCKS connection gets a unique stream ID
- Queues responses for each stream
- Handles connection lifecycle
-
WebSocket Client:
- Connects to tunnel_on_b's WebSocket server
- Automatic reconnection on failure
- Listens for forwarding requests
-
Internet Forwarder:
- Receives connection requests from tunnel_on_b
- Opens TCP connections to destination servers
- Forwards data bidirectionally
- Returns responses through tunnel
-
Connection Pooling:
- Manages multiple remote connections
- Buffers requests if connection not yet established
- Cleans up closed connections
Messages are JSON-encoded with the following types:
Request to establish connection to a remote host:
{
"type": "connect",
"id": "stream_123",
"payload": {
"host": "www.example.com",
"port": 443
}
}Data from SOCKS client to forward:
{
"type": "request",
"id": "stream_123",
"payload": {
"data": "<base64-encoded-data>",
"length": 1024
}
}Data received from remote server:
{
"type": "response",
"id": "stream_123",
"payload": {
"data": "<base64-encoded-data>",
"length": 2048
}
}Connection closed:
{
"type": "close",
"id": "stream_123"
}All network settings are configured in settings.json. Create this file by copying settings.example.json:
copy settings.example.json settings.json # Windows
cp settings.example.json settings.json # Linux/Mac{
"b_server": {
"websocket_port": 3000, // Port for WebSocket tunnel
"socks_port": 3128, // Port for SOCKS proxy
"bind_address": "0.0.0.0", // Address to bind to
"b_ip_address": "XXX.XXX.XX.XX" // Computer B's IP (for logs)
},
"a_client": {
"b_server_address": "XXX.XXX.XX.X", // Where to connect
"b_server_port": 3000 // WebSocket port
},
"network": {
"ping_interval": 20, // WebSocket keepalive (seconds)
"ping_timeout": 20, // Ping timeout (seconds)
"reconnect_delay": 5 // Reconnect delay (seconds)
}
}Required Changes:
- Update
b_ip_addresswith Computer B's actual IP - Update
b_server_addresswith Computer B's actual IP
Optional Changes:
- Adjust ports if 3000 or 3128 are already in use
- Tune network timeouts based on your network latency
# Use the included utility
python tests/utils/check_ip.py
# Or use system commands
ipconfig # Windows
ip addr show # Linux
ifconfig # Mac/Linuxcd tests/A
# Test connectivity to Computer B
python probe.py
# Test internet access
python test_connectivity.pycd tests/B
# Test WebSocket port binding
python test_bind.py
# Test local server connectivity
python test_b_local.pycd tests/utils
# Check IP address
python check_ip.py- Web Browsing: Use Firefox/Chrome with SOCKS proxy on Computer B
- VS Code Remote: Connect to remote servers through the tunnel
- API Access: Command-line tools with SOCKS support (curl --socks5)
- Development: Access cloud services, GitHub, npm registries
- Package Managers: pip, conda with proxy configuration
- No Encryption: Traffic between A and B is unencrypted (use on trusted networks only)
- No Authentication: Anyone on the network can connect to B's WebSocket server
- Performance: Adds latency due to tunneling overhead
- Windows-focused: Current version optimized for Windows (Linux support planned)
- Single Tunnel: One A-Client per B-Server (no load balancing)
- Local Network Only: This solution is designed for trusted local networks
- No Built-in Encryption: Use only on networks you trust
- HTTPS Still Encrypted: End-to-end HTTPS encryption is maintained
- Firewall Protection: B's firewall limits external access to port 3000
- No Access Control: Anyone who can reach B's WebSocket can use the tunnel
For Production Use:
- Add TLS encryption to the WebSocket connection
- Implement authentication (API keys or certificates)
- Add rate limiting and traffic monitoring
- Consider using a VPN for additional security
| Issue | Solution |
|---|---|
| "Connection refused" | Verify B-Server is running, check IP address in a_client.py |
| "Address already in use" | Kill existing process: netstat -ano | findstr :3000 then taskkill /PID <PID> /F |
| No internet through tunnel | Check SOCKS proxy settings, verify A-Client has internet |
| Firewall blocking | Run PowerShell as admin: New-NetFirewallRule -DisplayName "WebSocket Tunnel Port 3000" -Direction Inbound -LocalPort 3000 -Protocol TCP -Action Allow |
For detailed troubleshooting, see SETUP.md.
- Latency: ~10-50ms overhead (local network)
- Throughput: Limited by local network speed (typically 100Mbps - 1Gbps)
- Concurrent Connections: Tested with 10+ simultaneous connections
- Memory Usage: ~20-50MB per process
- TLS encryption for WebSocket tunnel
- Authentication mechanism
- HTTP CONNECT proxy support (in addition to SOCKS)
- Web dashboard for monitoring
- Linux compatibility testing
- Multiple A-Client support (load balancing)
- Bandwidth throttling and QoS
- Connection statistics and logging
This is a personal project currently in active development. Feel free to:
- Report issues
- Suggest improvements
- Fork and modify for your use case
This project is provided as-is for personal and educational use.
Inspired by reverse tunneling tools like:
- ngrok - Secure tunnels to localhost
- frp - Fast reverse proxy
- chisel - Fast TCP/UDP tunnel over HTTP
- SSH reverse tunneling - The OG reverse tunnel
Built with:
- Python 3 - Core language
- websockets - WebSocket implementation
- asyncio - Asynchronous I/O
Documentation:
- SETUP.md - Complete setup guide
- .claude/plan.md - Original project plan and architecture decisions
Quick Links:
- Test Computer A - Diagnostics for Computer A
- Test Computer B - Diagnostics for Computer B
- Utilities - Shared utility scripts