how to create a ssh tunnel for port forwarding using a control socket

the easiest way to explain the concept is to simply include a sample shell script:

#!/bin/sh


usage(){
    cat <<EOM

$program - control ssh tunnel to remote host
dave capella  <http:_grox.net/mailme>  09/23/2016

usage: $program -h | start|stop|status host:port

-h      print this help message and quit.
start   create tunnel
stop    destroy tunnel
status  show current tunnel status
host    remote host name (tunnel destination)
port    tcp port to tunnel through connection

notes:
* creates or destroys tunnel to remote host
* uses ssh control socket for port forwarding
* assumes port is unused on local host
* assumes a (relatively) secure environment. e.g., the
  socket name is predictable, and placed in /tmp.
* written as a demonstration of the concept (and memory aid for me)

EOM
    exit 2
}


bail(){
    cat <<EOM

ERROR: $1
try '-h'

EOM
    exit 1
}


dostart(){
        destination=$1
        port=$2
        socket=$3
        #
        # some of these options are not strictly necessary,
        # and/or should be specified in the ~/.ssh/config file,
        # but are included due to paranoia, and as a memory aid.
        #
        # q - quiet operation
        # x - no X forwarding
        # 4 - tcp v4 (sigh) someday the world will adopt ipv6- maybe...
        # 2 - ssh version 2. paranoia: shouldn't need this.
        # a - disable agent forwarding. paranoia.
        # C - compress data
        # f - background ssh before command execution
        # M - master mode
        # N - do not execute a remote command
        # n - close the terminal input stream (stdin)
        # T - no pseudo-tty
        # L - listen spec (next argument): local port : local host : forward port
        #
        ssh -qxM42aCNfnTL $port:localhost:$port -S $socket -o ExitOnForwardFailure=yes $destination
        dostatus $port
}


dostop(){
        destination=$1
        socket=$2
        ssh -S $socket -O exit $destination
        dostatus $port
}


dostatus(){
        port=$1
        netstat -at | grep "$port.*LIST"
}


############################################################
# main
############################################################
program=`basename $0`

case $1 in
        start|stop|status)
                action=$1
                [ -n "$2" ] || bail "no destination:host specified."
                destination=`echo $2 | cut -f1 -d:`
                port=`echo $2 | cut -f2 -d:`
                socket=/tmp/ssh-$destination-$port.socket
                ;;
        *)
                usage
                ;;
esac
shift

case $action in
        start) dostart $destination $port $socket ;;
        stop) dostop $destination $socket ;;
        status) dostatus $port ;;
esac
############################################################
# eof: sshtunnelctl                  vim:noet:ts=4 sts=4 sw=4 tw=80