Created
March 23, 2022 07:27
-
-
Save rkok/49d7e909e699833c4346b6d8148ab8a2 to your computer and use it in GitHub Desktop.
Persistent SSH tunnel helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Quit on error | |
set -e | |
# Functions | |
msg() { | |
echo -e "\x1B[1m$1\x1B[0m" | |
} | |
usage() { | |
echo "Usage:" | |
echo " Setup: $0 -u user -h host -s srcport -d dstport [-H dsthost]" | |
echo " Teardown: $0 -T -u user -h host -s srcport -d dstport [-H dsthost]" | |
echo " Help: $0 --help" | |
} | |
help() { | |
echo "Examples:" | |
echo | |
echo " Tunnelling localhost:1234 to MySQL on somehost:3306" | |
echo " $0 -u arnold -h somehost -s 1234 -d 3306" | |
echo " After running the above command, you can connect to the MySQL server like so:" | |
echo " mysql -h 127.0.0.1 -P 1234" | |
echo " To close the tunnel afterwards:" | |
echo " $0 -T -u arnold -h somehost -s 1234 -d 3306" | |
echo | |
echo " ---" | |
echo | |
echo " Tunnelling localhost:1234 to MySQL on farawayhost:3306 THROUGH somehost" | |
echo " $0 -u arnold -h somehost -s 1234 -d 3306 -H farawayhost" | |
} | |
# Static value | |
CONTROL_SOCKET='~/.ssh/%h_%p_%r.multiplex' | |
# Default values | |
DSTHOST=localhost | |
TEARDOWN=false | |
# Start parsing arguments | |
if [ "$1" == "--help" ]; then | |
usage | |
echo | |
help | |
exit 0 | |
fi | |
GIVEN=0 | |
OPTIND=1 | |
while getopts ':u:h:s:d:H:T' OPT; do | |
case "$OPT" in | |
u ) USER="$OPTARG" | |
GIVEN=$((GIVEN+1)) | |
;; | |
h ) HOST="$OPTARG" | |
GIVEN=$((GIVEN+1)) | |
;; | |
s ) SRCPORT="$OPTARG" | |
GIVEN=$((GIVEN+1)) | |
;; | |
d ) DSTPORT="$OPTARG" | |
GIVEN=$((GIVEN+1)) | |
;; | |
H ) DSTHOST="$OPTARG" | |
;; | |
T ) TEARDOWN=true | |
;; | |
\?) echo "Unknown option: -$OPTARG" >&2 | |
usage >&2 | |
exit 1 | |
;; | |
: ) echo "Missing option argument for -$OPTARG" >&2 | |
usage >&2 | |
exit 1 | |
;; | |
* ) usage >&2 | |
exit 1 | |
;; | |
esac | |
done | |
if [ $GIVEN -lt 4 ]; then | |
echo "Some mandatory options are missing. Make sure you have provided '-u', '-h', '-s' and '-d'" >&2 | |
usage >&2 | |
exit 1 | |
fi | |
if [ "$TEARDOWN" == "true" ]; then | |
echo -n "Closing SSH tunnel ... " | |
ssh \ | |
-o "ControlPath=$CONTROL_SOCKET" \ | |
-TO "exit" \ | |
$USER@$HOST | |
exit | |
fi | |
msg "Opening SSH tunnel $USER@$HOST $SRCPORT => $DSTHOST => $DSTPORT" | |
# Create SSH tunnel | |
# Errors will be caught by "set -e" | |
# -f: Go to background | |
# -q: Suppress MOTD | |
# -N: Don't execute any commands (forward only) | |
# -T: Don't allocate pseudo-terminal | |
# -M: Use as master process (so we can exit later) | |
ssh \ | |
-o ExitOnForwardFailure=yes \ | |
-o "ControlPath=$CONTROL_SOCKET" \ | |
-fqNTML "$SRCPORT:$DSTHOST:$DSTPORT" \ | |
$USER@$HOST |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment