#!/usr/bin/env bash

# ssh-tunnels.bash - keep an SSH connection alive at all costs
# Licensed under the terms of the GNU GPLv3 or later
# Proprietary Software Must Perish!

# AUTHOR: Johannes Truschnigg ( johannes@truschnigg.info || https://johannes.truschnigg.info )

#configure these variables to fit your needs
#SSHT_NM_OVERRIDE=1 #set this to override querying network-manager to check if net is up
ssht_logname="remote-username"
ssht_rhost="remote-ssh-server.example.org"

#ssht_extraopts is a bash array, populated with verbatim ssh(1) options
#place your port forwarding specifications here (examples provided)
declare -a ssht_extraopts
ssht_extraopts=(
	"-L8080:127.0.0.1:80"
	"-L3890:127.0.0.1:389"
	"-L8081:127.0.0.1:8080"
	)


#don't modify this script below this line, unless you know what you are up to
SCRIPTNAME="${0##*/}"
test -n "${DEBUG}" && set -x
while :
do
	printf "%s: SSH starting up…\n" "${SCRIPTNAME}" 1>&2
	/usr/bin/ssh -C -N -l "${ssht_logname:-${LOGNAME}}" \
	-oBatchMode=yes \
	-oServerAliveCountMax=6 \
	-oServerAliveInterval=5 \
	-oStrictHostKeyChecking=no \
	-oExitOnForwardFailure=yes \
	"${ssht_extraopts[@]}" \
	"${ssht_rhost}"
	printf "%s: SSH terminated, scheduling rerun…\n" "${SCRIPTNAME}" 1>&2
	if test -x /usr/bin/nm-tool && test -z "${SSHT_NM_OVERRIDE}" #if true, assume networking is managed by NetworkManager
	then
		cnt=0
		while test "$(/usr/bin/nm-tool | /usr/bin/awk '/^State:/{print $2}')" != connected
		do
			#try not to produce too much output in case connection is down
			test $(( cnt % 20 )) -eq 0 \
			&& printf "%s: NetworkManager signaled net down, sleeping…\n" "${SCRIPTNAME}" 1>&2
			cnt=$(( ${cnt} + 1 ))
			sleep 3
		done
	fi
	sleep 10 #avoid looping too fast in case ssh fails
done
