From c12283623a64544aaaab70f5cb21bd5741bb1754 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Thu, 7 May 2020 12:41:41 -0500 Subject: Version 0.3: add autossh support Added autossh support. mrgrctrnl will default to using autossh if it's installed; otherwise it'll do ssh in a while loop. I did include 'ExitOnForwardFailure=yes' in my ~/.ssh/config, but I'm thinking I should include that in __SSH_OPTIONS to be more robust. Might be in 0.3.1 or whatever. Another thing in 0.3.1 should be man pages and stuff. Maybe that'll be 0.4. I like version bumps. CHANGES HERE (right, that's what this message is for): - add autossh support: -S forces ssh ; -A forces autossh - rewrite usage; add config file example - change config file syntax (backward-compatible) - add a few other commandline options --- mrgrctrnl | 198 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 126 insertions(+), 72 deletions(-) diff --git a/mrgrctrnl b/mrgrctrnl index 796470c..b516596 100755 --- a/mrgrctrnl +++ b/mrgrctrnl @@ -1,126 +1,175 @@ #!/bin/sh # mrgrctrnl: configurable ssh tunneler # Author: Case Duckworth -# Version: 0.2 +# Version: 0.3 # License: MIT PRGN="${0##*/}" -usage() { - cat <"$__CMDF" + + # parse options + while getopts hkrnqSAc:s: OPT; do case "$OPT" in h) usage exit 0 ;; - q) _quiet=true ;; k) - tear_down + untunnel pkill -x "$PRGN" - exit + exit "$?" ;; r) - tear_down - exec "$PRGN" + untunnel + exec "$(cat "$__CMDF")" ;; - n) _run=false ;; + n) _RUN=false ;; + q) _LOG=false ;; + S) __SSH='ssh' ;; + A) __SSH='autossh' ;; c) __CONFIG="$OPTARG" ;; s) - __SSHCMD="$OPTARG" - _use_config=false - ;; - *) - usage - exit 1 + __SSH_ARGS="$OPTARG" + _USE_CONFIG=false ;; + *) exit 4 ;; esac done + shift $((OPTIND - 1)) - if $_use_config && [ ! -r "$__CONFIG" ]; then - echo "!! $PRGN: Cannot find config file '$__CONFIG'." - echo "Aborting." + # make sure ssh is installed + if ! command -v "$__SSH" >/dev/null; then + log "Not installed: $__SSH" exit 2 fi - if $_use_config; then + # make sure the config is readable + if $_USE_CONFIG && [ ! -r "$__CONFIG" ]; then + log "Cannot find config file $__CONFIG; aborting." + exit 3 + fi + + # load the config + if $_USE_CONFIG; then awk '{sub(/#.*$/,"");print}' "$__CONFIG" | while read -r machine user local remote key rest; do - if [ -z "$machine" ] || [ -z "$user" ] || - [ -z "$local" ] || [ -z "$remote" ]; then + if [ -z "$machine" ] || + [ -z "$user" ] || + [ -z "$local" ] || + [ -z "$remote" ]; then continue fi + case "$local" in + :*) local="localhost$local" ;; + esac + case "$remote" in + :*) remote="localhost$remote" ;; + esac + # shellcheck disable=2030 if [ -n "$key" ]; then - __SSHCMD="$__SSHCMD -i \"$key\"" + __SSH_ARGS="$__SSH_ARGS -i \"$key\"" fi if [ -n "$rest" ]; then - __SSHCMD="$__SSHCMD $rest" + __SSH_ARGS="$__SSH_ARGS $rest" fi - eval "tunnel $__SSHCMD" & + eval "tunnel_${__SSH##*/} $__SSH_ARGS" & done else - # shellcheck disable=2031 - eval "tunnel $__SSHCMD" & + #shellcheck disable=2031 + eval "tunnel_${__SSH##*/} $__SSH_ARGS" & fi wait } -tunnel() { - # shellcheck disable=2086 - $_quiet || echo ssh "$@" - $_run && { - touch "$__PIDF" - while [ -e "$__PIDF" ]; do - grep -q -e "$*" "$__PIDF" && { - sleep 3 - continue - } - # shellcheck disable=2015 - if ssh "$@" & then - printf '%s\t%s\n' "$!" "$*" >>"$__PIDF" - else - badpid="$!" - kill "$badpid" - sed "/^$badpid/d" "$__PIDF" >"$__PIDF~" && - mv "$__PIDF~" "$__PIDF" - continue - fi +usage() { + cat <>"$__PIDF" + else + badpid="$!" + kill "$badpid" + sed "/^$badpid/d" "$__PIDF" >"$__PIDF~" && + mv "$__PIDF~" "$__PIDF" + continue + fi + sleep 3 + done } -tear_down() { - printf '%s...' "Killing extant tunnels" +tunnel_autossh() { + set -- autossh -f "$@" + log "$@" + $_RUN || return + + "$@" && printf '%s\t%s\n' "$!" "$*" >"$__PIDF" +} + +untunnel() { + log "Killing tunnels" if [ -e "$__PIDF" ]; then while read -r pid _; do kill "$pid" 2>/dev/null @@ -128,8 +177,13 @@ tear_down() { rm "$__PIDF" else pkill -x ssh + pkill -x autossh fi - echo Done. + log "Done" +} + +log() { + $_LOG && printf '%s: %s\n' "$PRGN" "$*" >&2 } main "$@" -- cgit 1.4.1-21-gabe81