#!/usr/bin/env bash # Usage: ./simple-ssh-reverse-tunnel # or # bash simple-ssh-reverse-tunnel # Description: Open or close a ssh reverse tunnel based on a web page. # Author: Patrick Neumann (patrick@neumannsland.de) # Platform: Raspbian GNU/Linux 9.x # Version: 1.02 # Date: 2019-04-22 (first release: 2013-03-06) # Link: (work in progress) # License: GPL3 # Warranty: This program is distributed WITHOUT ANY WARRANTY #=== CONFIGURATION (binaries) ================================================== # Relative paths are more portable but less secure. # Absolute paths are more secure but less portable. readonly WHICH_BIN="which" # common readonly PRINTF_BIN="$( ${WHICH_BIN} "printf" )" # common readonly OPENSSL_BIN="$( ${WHICH_BIN} "openssl" )" # common readonly CUT_BIN="$( ${WHICH_BIN} "cut" )" # common readonly WGET_BIN="$( ${WHICH_BIN} "wget" )" # common readonly SSH_BIN="$( ${WHICH_BIN} "ssh" )" # common readonly PGREP_BIN="$( ${WHICH_BIN} "pgrep" )" # common readonly LOGGER_BIN="$( ${WHICH_BIN} "logger" )" # common readonly PKILL_BIN="$( ${WHICH_BIN} "pkill" )" # common readonly SLEEP_BIN="$( ${WHICH_BIN} "sleep" )" # common #=== FUNCTION ================================================================== # NAME: transform # DESCRIPTION: transform file name or commands into sha512. # PARAMETER 1: command (string) #=============================================================================== transform () { ${PRINTF_BIN} "${1}" | ${OPENSSL_BIN} dgst -sha512 | ${CUT_BIN} -d " " -f 2 } #=== CONFIGURATION (user) ====================================================== SERVER="example.com" DIR="cnc/" FILENAME="$( transform "any-string" )" PORT="22222" #=== CONFIGURATION (dynamic) =================================================== CONTENT="$( ${WGET_BIN} -q \ "https://${SERVER}/${DIR}/${FILENAME}.html" \ -O- )" COMMAND="${SSH_BIN} -nNTXYR :${PORT}:localhost:22 ${SERVER}" #------------------------------------------------------------------------------- # This is the real magic of this script... #------------------------------------------------------------------------------- case "${CONTENT}" in "$( transform "open" )" ) if ! ${PGREP_BIN} -f "${COMMAND}" > /dev/null 2>&1 ; then # Place port and user in "~/.ssh/config" before! ${COMMAND} & ${LOGGER_BIN} "${0} - backward channel initiated" fi ;; "$( transform "close" )" ) if ${PGREP_BIN} -f "${COMMAND}" > /dev/null 2>&1 ; then # 1st try to interupt ${PKILL_BIN} -INT -f "${COMMAND}" ${SLEEP_BIN} 5 if ${PGREP_BIN} -f "${COMMAND}" > /dev/null 2>&1 ; then # if needed: try (harder) to terminate ${PKILL_BIN} -f "${COMMAND}" ${SLEEP_BIN} 5 if ${PGREP_BIN} -f "${COMMAND}" > /dev/null 2>&1 ; then # if nothing helps: KILL! ${PKILL_BIN} -KILL -f "${COMMAND}" fi fi ${LOGGER_BIN} "${0} - backward channel closed" fi ;; * ) ${LOGGER_BIN} "${0} - RECEIVED UNKNOWN COMMAND!" exit 1 ;; esac exit 0