Skip to content

Instantly share code, notes, and snippets.

@alsunseri
Created November 23, 2024 22:34
Show Gist options
  • Save alsunseri/184bdb2f6420597abb21790e893a3e47 to your computer and use it in GitHub Desktop.
Save alsunseri/184bdb2f6420597abb21790e893a3e47 to your computer and use it in GitHub Desktop.
autossh reverse tunnel manager
#!/usr/bin/bash
# author - me and anthropic claude
# Configuration
REMOTE_HOST="[email protected]"
REMOTE_PORT="23237" # Port on the remote server
LOCAL_PORT="22" # Local SSH port to expose
MONITOR_PORT="0" # AutoSSH monitoring port (0 disables it)
AUTOSSH_PIDFILE="/tmp/reverse_tunnel_autossh.pid"
SSH_PIDFILE="/tmp/reverse_tunnel_ssh.pid"
# Log file for debugging
LOG_FILE="/tmp/reverse_tunnel.log"
start_tunnel() {
# Check if tunnel is already running
if [ -f "$AUTOSSH_PIDFILE" ] && kill -0 $(cat "$AUTOSSH_PIDFILE") 2>/dev/null; then
echo "Reverse tunnel is already running."
return 1
fi
# Export required AutoSSH settings
export AUTOSSH_PIDFILE="$AUTOSSH_PIDFILE"
export AUTOSSH_POLL=60
export AUTOSSH_FIRST_POLL=30
export AUTOSSH_GATETIME=0
export AUTOSSH_LOGLEVEL=7 # Verbose logging for debugging
export AUTOSSH_LOGFILE="$LOG_FILE"
# Start AutoSSH in background
autossh -M "$MONITOR_PORT" \
-f \
-N \
-R "$REMOTE_PORT:localhost:$LOCAL_PORT" \
"$REMOTE_HOST" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-o "ExitOnForwardFailure yes" \
-o "StrictHostKeyChecking accept-new" \
-o "RemoteCommand none" \
-o "RequestTTY no"
if [ $? -eq 0 ]; then
echo "Reverse tunnel started successfully."
# Store the SSH process PID
pgrep -f "ssh.*$REMOTE_HOST.*$REMOTE_PORT:localhost:$LOCAL_PORT" > "$SSH_PIDFILE"
echo "You can now access this machine via: ssh -p $REMOTE_PORT localhost (when logged into $REMOTE_HOST)"
echo "Or directly via: ssh -J $REMOTE_HOST -p $REMOTE_PORT localhost"
else
echo "Failed to start reverse tunnel."
return 1
fi
}
stop_tunnel() {
local killed=0
# Kill AutoSSH process if PID file exists
if [ -f "$AUTOSSH_PIDFILE" ]; then
if kill $(cat "$AUTOSSH_PIDFILE") 2>/dev/null; then
killed=1
echo "AutoSSH process terminated."
fi
rm -f "$AUTOSSH_PIDFILE"
fi
# Kill SSH process if PID file exists
if [ -f "$SSH_PIDFILE" ]; then
if kill $(cat "$SSH_PIDFILE") 2>/dev/null; then
killed=1
echo "SSH process terminated."
fi
rm -f "$SSH_PIDFILE"
fi
# Backup: Kill any remaining matching processes
if pgrep -f "ssh.*$REMOTE_HOST.*$REMOTE_PORT:localhost:$LOCAL_PORT" > /dev/null; then
pkill -f "ssh.*$REMOTE_HOST.*$REMOTE_PORT:localhost:$LOCAL_PORT"
killed=1
echo "Cleaned up remaining SSH processes."
fi
if [ $killed -eq 0 ]; then
echo "No running reverse tunnel found."
return 1
fi
}
status_tunnel() {
if [ -f "$AUTOSSH_PIDFILE" ] && kill -0 $(cat "$AUTOSSH_PIDFILE") 2>/dev/null; then
echo "Reverse tunnel is running."
echo "AutoSSH PID: $(cat "$AUTOSSH_PIDFILE")"
[ -f "$SSH_PIDFILE" ] && echo "SSH PID: $(cat "$SSH_PIDFILE")"
echo "Remote port: $REMOTE_PORT on $REMOTE_HOST"
echo "Local port: $LOCAL_PORT"
# Check if the tunnel is actually working
if ss -tln | grep -q ":$LOCAL_PORT "; then
echo "Local SSH port is listening."
else
echo "Warning: Local SSH port is not listening!"
fi
return 0
else
echo "Reverse tunnel is not running."
return 1
fi
}
check_dependencies() {
if ! command -v autossh >/dev/null 2>&1; then
echo "Error: autossh is not installed. Please install it first."
echo "On Debian/Ubuntu: sudo apt-get install autossh"
echo "On RedHat/CentOS: sudo yum install autossh"
exit 1
fi
}
case "$1" in
start)
check_dependencies
start_tunnel
;;
stop)
stop_tunnel
;;
status)
status_tunnel
;;
restart)
stop_tunnel
sleep 2
start_tunnel
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment