aboutsummaryrefslogtreecommitdiff
path: root/main.sh
diff options
context:
space:
mode:
authorClément Zrounba <6691770+clement-z@users.noreply.github.com>2021-01-16 17:45:26 +0100
committerClément Zrounba <6691770+clement-z@users.noreply.github.com>2021-01-16 17:45:26 +0100
commit9d323266b9fecbaeb8118947edf662fdf28cb77c (patch)
tree81b6b09aabeffce7d160ae3884848305335e4077 /main.sh
parent45e825cbaeb0dd5f40b5051955d4455a8a6f6e47 (diff)
downloadproxy-tcp-ssh-9d323266b9fecbaeb8118947edf662fdf28cb77c.tar.gz
proxy-tcp-ssh-9d323266b9fecbaeb8118947edf662fdf28cb77c.zip
rename script
Diffstat (limited to 'main.sh')
-rwxr-xr-xmain.sh270
1 files changed, 0 insertions, 270 deletions
diff --git a/main.sh b/main.sh
deleted file mode 100755
index 98f2c19..0000000
--- a/main.sh
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/bin/bash
-
-function usage() {
- echo \
-"SYNOPSYS
- $0 (-S|--ssh-host) SSHHOST (-t|--tunnel) TUNNELSPEC [OPTIONS]
-DESCRIPTION
- Spawn TCP tunnels between your computer and a remote SSH server. If the
- connection fail for some reason, the script will try to re-create the
- tunnels automatically every TIMEOUT seconds.
-OPTIONS
- -S,--ssh-host SSHHOST
- Set the ssh host. SSHHOST can be either the full hostname as you would
- specify it on the ssh command-line (e.g. [user@]myserver.com or hostname
- if it is set up in your ssh config).
-
- -t,--tunnel TUNNELSPEC
- Specify the ports to tunnel as a comma-separated list of either single
- ports or port pairs (e.g. -t 443,80:8080 will establish tunnels
- local:443-remote:443 and local:8080-remote:80). Note that you have to
- be a privileged user (i.e. a user with the CAP_NET_BIND_SERVICE
- capability) to be able to bind to ports below 1024.
-
- -p,--ssh-port SSHPORT /!\\ Not implemented
- Set the ssh remote port if different from the default.
-
- -H,--host HOST
- Set the tunnel host. HOST can be either the IP or hostname of the
- server to tunnel to, as seen from the ssh host. Defaults to localhost.
-
- -i,--interface IF /!\\ Not implemented
- Specify the local interface to bind to. Defaults to localhost. Setting
- it to 0.0.0.0 will make the tunnel available to other clients on your
- network (depending on your firewall rules).
-
- -f
- Fork the script to the background.
-
- -h,--help
- Print this help and exit.
-EXAMPLES
- Todo
-AUTHOR
- Clément Zrounba
-"
-}
-
-function parse_args() {
- ARG_POS_PARAMS=""
- while (( "$#" )); do
- case "$1" in
- -f|--fork)
- ARG_FORK=0
- shift
- ;;
- -h|--help)
- ARG_HELP=0
- shift
- ;;
- -H|--host)
- if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
- ARG_HOST=$2
- shift 2;
- else
- echo "Error: Argument for $1 is missing" >&2
- exit 1
- fi
- ;;
- -S|--ssh-host)
- if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
- ARG_SSHHOST=$2
- shift 2;
- else
- echo "Error: Argument for $1 is missing" >&2
- exit 1
- fi
- ;;
- -S*)
- if [ -n "${1:2}" ]; then
- ARG_SSHHOST=${1:2}
- shift 1;
- else
- echo "Error: Option not understood: $1" >&2
- exit 1
- fi
- ;;
- --ssh-host=*)
- if [ -n "${1:2}" ]; then
- ARG_SSHHOST=${1:11}
- shift 1;
- else
- echo "Error: Option not understood: $1" >&2
- exit 1
- fi
- ;;
- -t|--tunnel)
- if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
- ARG_TUNNELSPEC=$2
- shift 2;
- else
- echo "Error: Argument for $1 is missing" >&2
- exit 1
- fi
- ;;
- -*)
- echo "Error: Unsupported flag $1" >&2
- exit 1
- ;;
- *) # preserve positional arguments
- ARG_POS_PARAMS="$ARG_POS_PARAMS $1"
- shift
- ;;
- esac
- done
-
- # Check SSHHOST is given
- if [ -z "$ARG_SSHHOST" ]; then
- echo "Error: no ssh host specified" >&2
- exit 1
- fi
-
- # Check TUNNELSPEC is given
- if [ -z "$ARG_TUNNELSPEC" ]; then
- echo "Error: no tunnel(s) specified" >&2
- exit 1
- fi
-}
-
-function check_low_port_cap()
-{
- [ $(id -u) == 0 ] && echo "yes" && return
- # Check capability as well ?
-
- echo "no"
-}
-
-function parse_tunnel_spec() {
- local tunnel_spec=(${1//,/ })
- local can_access_low_local_ports=$(check_low_port_cap)
-
- declare -ag _TUNNEL_PORTS_LOCAL
- declare -ag _TUNNEL_PORTS_REMOTE
-
- for tunnel_spec_entry in ${tunnel_spec[*]}; do
- local ports=(${tunnel_spec_entry/:/ })
-
- local local_port=${ports[0]}
- local remote_port=${ports[1]:-$local_port}
-
- echo "Local endpoint $BIND_IF:$local_port will be tunnelled to remote endpoint $TUNNEL_HOST:$remote_port"
-
- if [ $local_port -lt 1024 ] && [ $can_access_low_local_ports == "no" ]; then
- echo "Error: local port below 1024 specified but running as an unprivileged user" >&2
- exit 1
- fi
-
- _TUNNEL_PORTS_LOCAL+=($local_port)
- _TUNNEL_PORTS_REMOTE+=($remote_port)
- done
-}
-
-# Parse command line arguments into ARG_* variables
-parse_args $@
-
-# Make positional parameters accessible through $1, $2, ...
-eval set -- "$ARG_POS_PARAMS"
-
-# Print help and exit if requested
-if [ 0 == "$ARG_HELP" ]; then
- usage
- exit 0
-fi
-
-# Assign values or defaults to other parameters from ARG_* variables
-SSH_HOST=${ARG_SSHHOST:-}
-BIND_IF=${ARG_BIND_IF:-localhost}
-TUNNEL_HOST=${ARG_HOST:-localhost}
-SSH_PORT=${ARG_SSHPORT:-22}
-DO_FORK=$([ "$ARG_FORK" == "0" ] && echo "yes" || echo "no")
-
-# Parse tunnel args into _TUNNEL_PORTS_* variables
-parse_tunnel_spec $ARG_TUNNELSPEC
-TUNNEL_PORTS_LOCAL=(${_TUNNEL_PORTS_LOCAL[*]})
-TUNNEL_PORTS_REMOTE=(${_TUNNEL_PORTS_REMOTE[*]})
-
-# Logfile location
-# comment to use stdout/stderr
-#LOGFILE=proxy.log
-#LOGFILE_ERR=proxy.log
-
-# set default log to stdout/stderr
-LOGFILE=${LOGFILE:-/dev/stdout}
-LOGFILE_ERR=${LOGFILE_ERR:-/dev/stderr}
-
-function start_and_monitor_tunnels() {
- # This function takes port numbers as arguments and creates as many TCP
- # tunnels like so:
- # BIND_IF:$local_port <--> SSH_HOST <--> TUNNEL_HOST:$remote_port
- # If the tunnel fails or ssh exits, we either:
- # - try again after a timeout if exit code is not 0
- # - exit if exit code is 0
- # NOTE: for now we just **always** try again after timeout
- local timeout_sec=${1:-10}
-
- local ntunnels=${#TUNNEL_PORTS_LOCAL[*]}
-
- declare -a ssh_tunnel_opt
- for i in `seq 0 $(($ntunnels - 1))`; do
- local local_port=${TUNNEL_PORTS_LOCAL[$i]}
- local remote_port=${TUNNEL_PORTS_REMOTE[$i]}
-
- ssh_tunnel_opt+=("-L")
- ssh_tunnel_opt+=("${BIND_IF}:${local_port}:${TUNNEL_HOST}:${remote_port}")
- done
-
- while true; do
- # Try establishing the tunnel
- echo -n "Starting tunnel... "
- ssh -N \
- ${ssh_tunnel_opt[*]} \
- -o "ServerAliveInterval 10" \
- -o "ServerAliveCountMax 3" \
- -o "ExitOnForwardFailure yes" \
- ${SSH_HOST} &
- local pid="$!"
- # make sure to kill ssh when killed/parent exits
- trap "kill '$pid'" EXIT
- echo "OK"
- wait
-
- local exit_code="$?"
- echo "ssh exited with exit code ${exit_code}"
- #if [[ ${exit_code} != 0 ]]; then
- if true; then
- # If ssh exited with non-zero code, wait a bit and retry
- echo "restarting in ${timeout_sec}s..."
- sleep ${timeout_sec}
- else
- echo "exiting."
- return 0
- fi
- done
-}
-
-# Start the tunnels and redirect outputs
-if [ ${LOGFILE} != "/dev/stdout" ] || [ ${LOGFILE_ERR} != "/dev/stderr" ]; then
- echo "\
- Logs will be redirected to:
- stdout --> ${LOGFILE}
- stderr --> ${LOGFILE_ERR}
- "
-fi
-
-# In the following block, the following redirections are set up:
-# - 777 goes to stdout of current script (and not global /dev/stdout)
-# - 1 goes to $LOGFILE
-# - 2 goes to $LOGFILE_ERR
-{
- # Enable trace
- #set -x
-
- # Set up CTRL-C callback (write to stdout of script, not log)
- trap_ctrl_c_callback="
- echo 'Interrupt signal received, exiting...' 1>&777
- exit 130
- "
- trap "${trap_ctrl_c_callback}" SIGINT
-
- start_and_monitor_tunnels
-} 777>&1 1>>${LOGFILE} 2>>${LOGFILE_ERR}