Automate reverse SSH (and VNC) tunnel setup for remote hosts behind a firewall.
The problem — you want to access new hosts on remote sites with restricted firewalls.
The solution — have each host phone home on boot and leave a connection shortcut on your management server.
- Run bootstrap.sh on your management (Target) server — it pushes scripts to the new host and kicks off setup.
- reverseSSH.sh runs on the new host: exchanges SSH keys, allocates ports, and installs a persistent reverse tunnel.
- On the Target, use the generated
build-<PORT>.shshortcut to connect, or run tunnel-status.sh to see all active tunnels. - Optionally run reverseVNC.sh on the host to add a VNC tunnel on the second allocated port.
- When decommissioning a host, run teardown.sh on the remote host.
| Script | Purpose |
|---|---|
| findopenport.sh | Finds 2 unused ports in the dynamic range (49152–65535). Run on the Target; called remotely by reverseSSH.sh. |
| bootstrap.sh | Pushes all setup scripts to a new host and triggers reverseSSH.sh remotely. Run this first. |
| tunnel-status.sh | Shows all active reverse tunnels and cross-references them against the port registry. |
| Script | Purpose |
|---|---|
| reverseSSH.sh | Main setup: installs autossh, exchanges keys, allocates ports, installs persistence (systemd or cron), starts the tunnel. |
| reverseVNC.sh | Adds a reverse VNC tunnel (port 5900) using the second allocated port. Run after reverseSSH.sh. |
| reverseZabbix.sh | Adds a reverse Zabbix agent tunnel (port 10050). Append to reverseSSH.sh if needed. |
| teardown.sh | Cleanly removes the tunnel, persistence config, and port registry entry. |
| report.sh | Post-install diagnostic: shows IPs, gateway, DNS, hostname, and allocated ports. |
| File | Purpose |
|---|---|
| autossh-tunnel.service | Systemd unit for the SSH tunnel. Installed by reverseSSH.sh when --systemd is passed. Reads config from /etc/autossh-tunnel.conf. |
# Install findopenport.sh
cp findopenport.sh /usr/local/bin/findopenport.sh
chmod +x /usr/local/bin/findopenport.sh
# Ensure your SSH keypair exists at ~/.ssh/id_rsa# The new host must be reachable right now (e.g. on-site before it goes remote)
sudo bash bootstrap.sh <user> <new-host-ip>
# Use --systemd for systemd-based persistence (recommended over cron)
sudo bash bootstrap.sh --systemd <user> <new-host-ip># Use the generated shortcut
./build-<PORT>.sh
# Or connect directly
ssh -p <PORT> <user>@127.0.0.1
# See all active tunnels
bash tunnel-status.shsudo bash reverseVNC.sh --systemd <user> <target-host>
# Then on Target: ./vnc-<PORT>.shsudo bash teardown.sh <user> <target-host>Each time a host sets up a tunnel, reverseSSH.sh appends a record to ~/tunnel-registry.txt on the Target:
54321=build-54321,2026-04-23T10:00:00Z
tunnel-status.sh reads this file to display hostnames alongside active ports. teardown.sh removes the entry when a host is decommissioned.
| Method | When to use |
|---|---|
systemd (--systemd) |
Recommended for modern Linux. Starts After=network-online.target, restarts automatically, logs to journald. |
| cron (default) | Use on systems without systemd (older distros, containers). |