Port Tunnel lets you manage reverse SSH tunnels with a modern Web dashboard and a powerful CLI. Persistent state, automatic server health checks, and one-file packaging.
# create & activate venv (optional)
python3 -m venv venv && source venv/bin/activate
# install deps
pip install -r requirements.txt
# run web ui on 8080
python main.py --webport 8080
# add a tunnel (remote:80 -> local:8080)
python main.py add web80 80 8080
pyinstaller --onefile --add-data "static:static" main.py
./dist/main --webport 8080
Bootstrap dashboard with dark mode, real-time tunnel list, quick add/remove, and server details.
Scriptable commands to add, list, and delete tunnels—perfect for automation and servers without a GUI.
Server heartbeat every 30s. If unreachable, tunnels are cleared and the server entry is removed.
Our intuitive Web UI gives you complete control over your reverse SSH tunnels with real-time status updates and one-click management.
Grab the binary or build from source. The static Web UI can be bundled inside the executable using PyInstaller’s --add-data.
# Clone the repository
git clone https://github.com/porttunnel/PortTunnel.git
cd PortTunnel
# Make the installation script executable and run it
chmod +x install-porttunnel.sh
sudo ./install-porttunnel.sh
git clone https://github.com/porttunnel/PortTunnel.git
cd PortTunnel
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python main.py --webport 8080
# Run directly from command line
PortTunnel.exe --webport 8080
# Add a tunnel
PortTunnel.exe add web80 80 8080
Example unit file:
[Unit]
Description=Port Tunnel
After=network.target
[Service]
ExecStart=/usr/local/bin/porttunnel --webport 8080
Restart=always
User=youruser
WorkingDirectory=/home/youruser
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now porttunnel
# list tunnels
python main.py list
# add tunnel (name, remote_port, local_port)
python main.py add web80 80 8080
# delete tunnel
python main.py delete web80
# show server info
python main.py server
# list tunnels
PortTunnel.exe list
# add tunnel (name, remote_port, local_port)
PortTunnel.exe add web80 80 8080
# delete tunnel
PortTunnel.exe delete web80
# show server info
PortTunnel.exe server
curl http://localhost:8080/server
curl http://localhost:8080/tunnels
curl -X POST http://localhost:8080/tunnels \
-H "Content-Type: application/json" \
-d '{"name":"web80","remote_bind_port":80,"local_port":8080}'
curl -X DELETE http://localhost:8080/tunnels/web80
pyinstaller --onefile --add-data "static:static" main.py
./dist/main --webport 8080
Questions, issues, or feature requests? Open a GitHub issue or send us a message at support@porttunnel.org.