Created
October 9, 2015 05:52
-
-
Save blakewrege/bd61cbe398aa3374a923 to your computer and use it in GitHub Desktop.
reverse tunnel ssh script
This file contains hidden or 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
#!/bin/bash | |
# Script: rssht (Reverse SSH Tunnel) | |
# Author: Khizer Naeem (khizernaeem(x)gmail.com) | |
# Created : 09 Sep 2012 | |
# Version: 1.04 | |
# Latest Revision: 10 Feb 2013 | |
# Tested on: Centos/RHEL 6, Centos/RHEL 5, | |
# Description: A bash script to maintain reverse ssh tunnel with remote port forwardings. | |
# URL: http://kxr.me/scripts/rssht_v1.03 | |
# | |
# Copyright (C) 2013 Khizer Naeem All rights reserved. | |
# This copyrighted material is made available to anyone wishing to use, | |
# modify, copy, or redistribute it subject to the terms and conditions | |
# of the GNU General Public License v.2. | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
############################# | |
## CONFIGURATION VARIABLES ## | |
############################# | |
REMOTE_HOST=t4ls.duckdns.org # The remote host to which you want to forward the ports | |
REMOTE_SSH_PORT=22 # SSH port of the remote host | |
REMOTE_USER=cclub # SSH user for the remote host (Should have password less login from this machine with this user) | |
SSH_RUN_DIR=/var/run/rssht/ # Directory to keep ssh socket connection and pid file (Should exist) | |
PORTS_REMOTELY_ACCESSIBLE=yes # If set to yes, -g switch will be used while making the ssh connection. Read ssh manual for detail of -g | |
SSH_BIN=/usr/bin/ssh # Location of the ssh client on this host | |
REFRESH_SOCKET=15 # If set to a non-zero integer, this script will restart the ssh session if its that many minutes old. | |
########################### | |
## PORT FORWARDING TABLE ## | |
########################### | |
REMOTE_FWDS=( | |
1337:localhost:80 | |
) | |
####################### | |
## SSH OPTIONS TABLE ## | |
####################### | |
# These options will be passed to ssh with the -o switch e.g -o "ControlMaster yes" | |
# You can comment this out if you want the script to obey the ssh config | |
SSH_OPTS=( | |
'ControlMaster yes' | |
'PreferredAuthentications publickey' | |
'Ciphers arcfour256' | |
'Compression yes' | |
'TCPKeepAlive yes' | |
'ServerAliveCountMax 3' | |
'ServerAliveInterval 10' | |
) | |
# ///////////////////////// | |
# // Do not modify below // | |
# ///////////////////////// | |
################### | |
## SCRIPT CHECKS ## | |
################### | |
if [ "$1" == "install" -o "$1" == "--help" -o "$1" == "-h" ] | |
then | |
echo "INSTALLATION INSTRUCTIONS:" | |
echo | |
echo "# Set the configuration variables and forwardings" | |
echo | |
echo "# Make sure you have ssh keys generated" | |
echo "ssh-keygen" | |
echo | |
echo "# Setup password-less login to the remote host" | |
echo "ssh-copy-id '$REMOTE_HOST -l $REMOTE_USER -p $REMOTE_SSH_PORT'" | |
echo | |
echo "# Add the cron job" | |
echo "echo '*/5 * * * * root $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/$(basename ${BASH_SOURCE[0]})' > /etc/cron.d/rssht_$REMOTE_HOST" | |
exit 0 | |
fi | |
############################### | |
## SSH CONNECTION EVALUATION ## | |
############################### | |
# - If socket exists: | |
# 1-If the socket is old kill the connection (so that a new one is created) | |
# 2-Run the check command on the socket | |
# 2.1- if it passes, do nothing, exit | |
# 2.2- if it fails kill ssh and remove socket file | |
# - Run the ssh command | |
# Socket file | |
SOCK_FILE="$SSH_RUN_DIR/$REMOTE_HOST.sock" | |
# PID file | |
PID_FILE="$SSH_RUN_DIR/ssh_$REMOTE_HOST.pid" | |
if (mkdir -p $SSH_RUN_DIR) | |
then : | |
else | |
echo "FATAL Error: Cannot create RUN directory $SSH_RUN_DIR/" | |
fi | |
if [ -S "$SOCK_FILE" -o "$1" == "stop" ] | |
then | |
# If Socket is older than {REFRESH_SOCKET} minutes OR if stop argument is passed, stop the connection | |
if [ "$REFRESH_SOCKET" -gt "0" -o "$1" == "stop" ] | |
then | |
if [ -n "$(find $SOCK_FILE -mmin +$REFRESH_SOCKET)" -o "$1" == "stop" ] | |
then | |
if [ "$1" == "stop" ] | |
then | |
echo "Stop argument passed, killing .." | |
else | |
echo "Existing SSH connection is old, killing .." | |
fi | |
# Send the exit command to the existing socket | |
ssh -O exit -S $SOCK_FILE $REMOTE_HOST &> /dev/null | |
# Kill the pid if the process some how still exists | |
if (kill -0 $(cat $PID_FILE) &> /dev/null ) | |
then | |
echo "killing ssh process $(cat $PID_FILE)" | |
kill -9 $(cat $PID_FILE) &> /dev/null | |
fi | |
rm -rf $PID_FILE &> /dev/null | |
fi | |
fi | |
fi | |
#If the user passed stop, don't proceed further | |
[ "$1" == "stop" ] && exit 0 | |
# Check the status of the SSH connection through the socket file | |
if (ssh -O check -S $SOCK_FILE $REMOTE_HOST &> /dev/null) | |
then | |
# SSH connection is fine | |
echo "ssh connection is fine, exiting" | |
exit 0 | |
else | |
# SSH socket check failed | |
# Try killing the PID first | |
if [ -e "$PID_FILE" ] | |
then | |
if (kill -0 $(cat $PID_FILE) &> /dev/null ) | |
then | |
echo "killing ssh process $(cat $PID_FILE)" | |
kill -9 $(cat $PID_FILE) &> /dev/null | |
rm -rf $PID_FILE &> /dev/null | |
fi | |
fi | |
# Remove the socket if it still exists | |
if [ -S "$SOCK_FILE" ] | |
then | |
if (rm -rf "$SOCK_FILE" &> /dev/null) | |
then | |
echo "FATAL ERROR: Cannot remove stalled socket file $SOCK_FILE" | |
echo "Exiting.." | |
exit 9 | |
else | |
echo "Stalled socket file removed" | |
fi | |
fi | |
fi | |
fi | |
# The socket and process should be gone by now; If not this is an exception; exit! | |
# This should not happen | |
if [ -S "$SOCK_FILE" ] | |
then | |
echo "Exception: Cannot remove socket file. SSH connection seems to be stuck" | |
echo "Exiting" | |
exit 11 | |
fi | |
########################## | |
## SSH COMMAND CREATION ## | |
########################## | |
# Whether to use -g switch or not | |
P_R_A="" | |
[ "$PORTS_REMOTELY_ACCESSIBLE" == "yes" ] && P_R_A="-g" | |
# Remote forwardings | |
RFWDS="" | |
for i in "${!REMOTE_FWDS[@]}" | |
do | |
RFWDS="$RFWDS-R ${REMOTE_FWDS[$i]} " | |
done | |
# SSH options | |
SOPTS="" | |
for i in "${!SSH_OPTS[@]}" | |
do | |
SOPTS="$SOPTS-o '${SSH_OPTS[$i]}' " | |
done | |
# SSH final command | |
SSH_COMMAND="$SSH_BIN $SOPTS $P_R_A -f -q -N -S $SOCK_FILE $RFWDS -p $REMOTE_SSH_PORT -l $REMOTE_USER $REMOTE_HOST" | |
##################### | |
## RUN SSH COMMAND ## | |
##################### | |
eval "$SSH_COMMAND" | |
if [ "$?" -ne "0" ] | |
then | |
echo "FATAL ERROR: SSH command failed" | |
echo "SSH_COMMAND=$SSH_COMMAND" | |
exit 10 | |
else | |
#Save the PID | |
SOCK_CHECK=$(ssh -O check -S $SOCK_FILE $REMOTE_HOST 2>&1) | |
SPID=$(echo $SOCK_CHECK | cut -d'=' -f2 | sed 's/)//') | |
echo "$SPID" > $PID_FILE | |
echo "RSSHT to host $REMOTE_USER@$REMOTE_HOST:$REMOTE_SSH_PORT started successfully ssh pid: $SPID" | |
exit 0 | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment