Loading...
Loading...
Diagnose and fix SSH tunnel issues. Use when a tunnel is not connecting, a port is not responding, an SSH tunnel shows as stopped, the user reports "Permission denied", "Connection refused", or any SSH tunnel-related error.
npx skill4agent add statechangelabs/ssh-tunnel-manager ssh-tunnel-debugssh-tunnelsssh-tunnels status --jsonenabled: truealive: falseportOpen: falsessh-tunnels logs <tunnel-id>ssh-tunnels remove <id>
ssh-tunnels add --name "Same Name" --host <host> --user root --localPort <port> --remoteHost <rhost> --remotePort <rport> --enabledrootssh <user>@<host># Test SSH connectivity directly
ssh -o ConnectTimeout=5 -o BatchMode=yes <user>@<host> echo "OK" 2>&1--sshPort# Test basic connectivity
ping -c 3 -W 5 <host> 2>&1
# Test SSH port specifically
nc -z -w 5 <host> <ssh-port> 2>&1 && echo "Port open" || echo "Port closed/filtered"# Remove the old host key
ssh-keygen -R <host>
# The tunnel manager uses StrictHostKeyChecking=accept-new, so re-enabling should work
ssh-tunnels disable <id> && ssh-tunnels enable <id># Find what's using the port
lsof -i :<local-port> -P -n
# Either stop that process or change the tunnel's local port--localPort# SSH in and check if the service is running
ssh <user>@<host> "netstat -tlnp 2>/dev/null | grep <remote-port> || ss -tlnp | grep <remote-port>"--remoteHost--remotePort# Check the PID file
cat ~/.ssh-tunnels/pids/<id>.pid 2>/dev/null
# Try a manual SSH connection to see what happens
ssh -v -N -L <localPort>:<remoteHost>:<remotePort> <user>@<host>ssh-tunnels status --jsonalive: trueportOpen: true# For PostgreSQL (port 5432)
pg_isready -h 127.0.0.1 -p <local-port> 2>&1 || echo "Not ready"
# For HTTP services
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:<local-port>/ 2>&1
# For any TCP service (generic check)
nc -z -w 3 127.0.0.1 <local-port> && echo "Port responding" || echo "Port not responding"# Check if SSH agent is running and has keys loaded
ssh-add -l 2>&1
# Check if there's a network-level issue
# (all tunnels to the same host failing = host or network problem)
ssh-tunnels status --json | grep -E '"host"|"alive"'
# Force a full re-sync
ssh-tunnels syncssh-tunnels disable <id>
# Clean up any stale state
rm -f ~/.ssh-tunnels/pids/<id>.pid
ssh-tunnels enable <id>
ssh-tunnels logs <id># Check if it's running
pgrep -f "electron.*app.mjs" && echo "Running" || echo "Not running"
# Restart it
pkill -f "electron.*app.mjs"
# The LaunchAgent should restart it automatically, or:
launchctl unload ~/Library/LaunchAgents/com.statechange.ssh-tunnel-manager.plist 2>/dev/null
launchctl load ~/Library/LaunchAgents/com.statechange.ssh-tunnel-manager.plist
# Check launch agent status
launchctl list | grep statechange| Symptom | Most likely cause | First thing to try |
|---|---|---|
| "Permission denied" | Wrong SSH user | Recreate with |
| Tunnel stops immediately | Auth failure or port conflict | |
| Tunnel starts but port not open | Remote service down | SSH in and check the service |
| All tunnels failing | Network issue or SSH agent | |
| Tunnel works then dies | Server-side timeout | Check ServerAliveInterval |
| "Address already in use" | Port conflict | |