SSH Scripts

De WikiMar
Dreceres ràpides: navegació, cerca

Other Bash Scripts

v1 Cron script to keep a reverse tunnel

#!/bin/bash

REMOTE_HOST="[email protected]"
REMOTE_PORT="1122"
SSHKEY="/home/marti/.ssh/id_dsa"
COMMAND="ssh -f -N -p23 -i $SSHKEY -CD 8080 -g -R $REMOTE_PORT:localhost:22 $REMOTE_HOST"
# important: -f fa que quedi en background i el script continui
# -n fa que no obri ternimal nomes port forwarding

LOGFILE="/home/marti/routes-load.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S')   

#disable next line?:
echo "$DATE - Started" >> $LOGFILE

# Is the tunnel up? Perform two tests:

# 1. Check for relevant process ($COMMAND)
pgrep -f -x "$COMMAND" || ($COMMAND && echo "$DATE - Not in ps" >> $LOGFILE)

# 2. Test tunnel by looking at 'netstat' output on $REMOTE_HOST
ssh -p23 -i $SSHKEY $REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_PORT.*LISTEN" > /dev/null 2>&1

if [ $? -ne 0 ] ; then
   echo "$DATE - Not in netstat" >> $LOGFILE
   pkill -f -x '$COMMAND'
   $COMMAND
fi

Edit /etc/ssh/sshd_config and add/modify the following lines :

# TCPKeepAlive yes
# ClientAliveInterval 30
# ClientAliveCountMax 99999
# GatewayPorts yes
millor:
# GatewayPorts clientspecified

More information on keeping SSH connections stable: http://drupal.star.bnl.gov/STAR/comp/sofi/facility-access/ssh-stable-con

v1.2 Cron script to keep a reverse tunnel in case pgrep is not available - better

#!/bin/bash

# REMOTE_HOST="[email protected]"
REMOTE_PORT="9922"
#SSHKEY="/home/marti/.ssh/id_dsa"
#COMMAND="ssh -p23 -i $SSHKEY -CD 8080 -f -N -g -R $REMOTE_PORT:localhost:22 $REMOTE_HOST"
COMMAND="/usr/bin/ssh -f -N -R $REMOTE_PORT:127.0.0.1:22 -L 6622:127.0.0.1:6622 [email protected] ssh -R 0.0.0.0:$REMOTE_PORT:127.0.0.1:9922 -L 6622:127.0.0.1:443 -p 443 [email protected]"


LOGFILE="/home/marti/routes-load.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S')   

#disable next line?:
echo "$DATE - Started" >> $LOGFILE

# Is the tunnel up? Perform two tests:

# 1. Check for relevant process ($COMMAND)
if ! ps ax | grep -v grep | grep "$COMMAND" > /dev/null 2>&1
then
    echo "$DATE - Not in ps" >> $LOGFILE
    $COMMAND
    #Potser: exit 
fi

# 2. Test tunnel by looking at 'netstat' output on $REMOTE_HOST
ssh -p23 -i $SSHKEY $REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_PORT.*LISTEN" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Not in netstat" >> $LOGFILE
   pkill -f -x '$COMMAND'
   $COMMAND
fi

Si es per obrir "SSH", i a la maquina remota hi ha "nmap" es pot fer:

# 2.
ssh -p23 -i $SSHKEY $REMOTE_HOST nmap -sV -p $REMOTE_PORT 127.0.0.1 | grep -i "OpenSSH" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Not detected as OpenSSH" >> $LOGFILE
   pkill -f -x '$COMMAND'
   $COMMAND
fi

Alternativa 1:

if [ $(ps ax | grep "$COMMAND" | grep -vc grep) -lt 1 ]

Alternativa 2:

#ps ax | grep -v grep | grep "$COMMAND" > /dev/null 2>&1
#if [ $? -ne 0 ]

$? es el exit code de la ultima comanda. Si es 0=success. En cas de grep vol dir que ha trobat.

v2 Cron script to keep a local tunnel

login-hook

#!/bin/bash
COMMAND="/Users/<user>/devel/tunnel-start.sh"
LOGFILE="/home/marti/routes-load.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S') 


if [ "$(ps ax | grep tunnel-start.sh | grep -vc grep)" -lt 1 ]; then
    echo "$DATE - Not in ps" >> $LOGFILE
    $COMMAND &
    #sudo -u <user> /Users/<user>/devel/tunnel-start.sh &
    exit
fi


#Opcional: Potser es pot mirar tambe el nestat local si el port esta obert:
netstat -an | egrep "tcp.*:$REMOTE_PORT.*LISTEN" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Not in netstat" >> $LOGFILE
   pkill -f -x '$COMMAND'
   $COMMAND &
fi


tunnel-start.sh

#!/bin/bash
 
while [ 1 ]; do
 ssh -N -L 6667:127.0.0.1:6667 -o ServerAliveInterval=3 [email protected]
 sleep 5
done

More info: http://crz.lt/2007/09/26/setting-up-a-permanent-ssh-tunnel-on-mac-os-x/

-o ServerAliveInterval=15 or even 60 should be fine and with less stress:

  • ServerAliveInterval: number of seconds that the client will wait before sending a null packet to the server (to keep the connection alive).
  • ClientAliveInternal: number of seconds that the server will wait before sending a null packet to the client (to keep the connection alive).

Setting a value of 0 (the default) will disable these features so your connection could drop if it is idle for too long.



Cron script to keep a double reverse tunnel (using a gateway)

#!/bin/bash

REMOTE_PORT="9922"
LOCAL_PORT="6722"
#COMMAND="/usr/bin/ssh -f -N -R $REMOTE_PORT:127.0.0.1:22 -L 6622:127.0.0.1:6622 [email protected] ssh -R 0.0.0.0:$REMOTE_PORT:127.0.0.1:9922 -L 6622:127.0.0.1:443 -p 443 [email protected]"
#COMMAND="/usr/bin/ssh -R 9922:127.0.0.1:22 -L 6622:127.0.0.1:6622 [email protected] ssh -N -R 0.0.0.0:9922:127.0.0.1:9922 -L 6622:127.0.0.1:443 -p 443 [email protected]"

COMMAND1="/usr/bin/ssh -f -N -L $LOCAL_PORT:xx.server:23 [email protected]"
COMMAND2="/usr/bin/ssh -f -N -R 0.0.0.0:$REMOTE_PORT:127.0.0.1:22 -p $LOCAL_PORT [email protected]"

LOGFILE="/home/logica/checksshbackup.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S')


#disable next line?:
#echo "$DATE - Started" >> $LOGFILE


# 2 tests to check if the tunnel is working:

# 1st Check the 2 processes are running
#if [ $(ps ax | grep "$COMMAND" | grep -vc grep) -lt 1 ]

if ! ps ax | grep -v grep | grep "$COMMAND1" > /dev/null 2>&1
then
    echo "$DATE - Command1 not in ps" >> $LOGFILE
    $COMMAND1
fi

if ! ps ax | grep -v grep | grep "$COMMAND2" > /dev/null 2>&1
then
    echo "$DATE - Command2 not in ps" >> $LOGFILE
    $COMMAND2
fi


# 2nd Test tunnel

ssh -p $LOCAL_PORT [email protected] netstat -an | egrep "tcp.*:$REMOTE_PORT.*LISTEN" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Not in netstat" >> $LOGFILE
   pkill -f -x '$COMMAND1'
   pkill -f -x '$COMMAND2'

   $COMMAND1
   $COMMAND2
#else
#   echo "Ok"
fi

exit



v3 Cron script to keep a local/remote tunnel v3 using autossh - better

login-hook

#!/bin/bash
COMMAND="/home/<user>/tunnel-start.sh"
LOGFILE="/home/<user>/tunnel-start.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S') 

if [ "$(ps ax | grep tunnel-start.sh | grep -vc grep)" -lt 1 ]; then
    echo "$DATE - Starting tunnel-start.sh" >> $LOGFILE
    $COMMAND &
    exit
fi


tunnel-start.sh

#!/bin/bash

LOGFILE="/home/<user>/tunnel-start.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S') 
 
while [ 1 ]; do
 echo "$DATE - Starting autossh" >> $LOGFILE
 autossh -M 0 -q -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 8081:localhost:80 my.linuxbox.at.home
 sleep 5
done

More info: http://en.gentoo-wiki.com/wiki/Autossh

Without them, the -f option complains that it needs a command to fork and will just quit. -N says no command and -q says be quiet. Also if you would like to have a special key with no passphrase you can generate one and then use it via the -i option for ssh.

The above command will make ssh send a keep-alive request if no other data has been sent for 60 seconds, if it doesn't receive a reply after 3 attempts it will close the connection. autossh will then detect its been closed and attempt re-establish it.

The "-M 0" option disables autossh's own monitoring which uses separate ports and is less reliable.




v4 Cron script to verify that a tunnel is working connecting through it to ssh

El ssh executat a tunnel-start-xx2.sh conté -L 127.0.0.1:28083:127.0.0.1:23

#!/bin/bash

COMMAND="/home/marti/tunnel-start-xx2.sh"
LOGFILE="/home/marti/tunnel-hook-xx2.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S') 


# Test to connect via ssh to the local forwared port
ssh -p28083 -o ConnectTimeout=1 -o ConnectionAttempts=1 [email protected] exit 
# > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Cannot connect to local tunnel" |tee $LOGFILE
   pkill -f -x '$COMMAND'

   sudo killall tunnel-start-xx2.sh
   sudo killall sshguard
   sudo killall autossh
   sudo killall tunnel-start-xx2.sh
   sudo killall sshguard
   sudo killall autossh
   sudo killall tunnel-start-xx2.sh
   sudo killall sshguard
   sudo killall autossh

   $COMMAND &
   exit
fi



v5 Cron script to verify that a tunnel is working connecting through it to ssh - better

tunnel-hook-xx

#!/bin/bash

COMMAND="/home/marti/tunnel-start-xx"
LOGFILE="/home/marti/tunnel-hook-xx.log"
DATE=$(date +'%Y-%m-%d %H:%M:%S')   

# Test to connect via ssh to the local forwared port
ssh -p18083 -o ConnectTimeout=2 -o ConnectionAttempts=1 -i /home/marti/.ssh/id_dsa [email protected] exit 
# > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$DATE - Cannot connect to local tunnel" |tee -a $LOGFILE

   sudo pkill -f -x '$COMMAND'
   sudo killall tunnel-start-xx
   sudo killall autossh
   sudo pkill -f "ssh -q -N -p443"
   sudo killall tunnel-start-xx

   $COMMAND &

   sleep 1
   /home/marti/tunnel-hook-xx-test

   exit
fi


tunnel-start-xx

#!/bin/bash

REMOTE_HOST="[email protected]"
SSHKEY="/home/marti/.ssh/id_dsa"

LOGFILE="/home/marti/tunnel-start-xx.log"


#COMMAND="/usr/bin/ssh -f -N -p23 -i $SSHKEY -CD 8080 -g -R $REMOTE_PORT:localhost:22 $REMOTE_HOST"
# -f fa que quedi en background i el script continui
# -n fa que no obri ternimal nomes port forwarding

while [ 1 ]; do
 # Carregem les routes per utilitzar la xarxa sense fils:
 ### /home/marti/routes-load

 DATE=$(date +'%Y-%m-%d %H:%M:%S') 
 echo "$DATE - Starting ssh" |tee -a $LOGFILE

 #Connecta a xx.server a traves de LAN amb el proxy X.X.X.X
sudo ssh -q -N -p443 -i $SSHKEY -CD 18081 -L 127.0.0.1:18082:127.0.0.1:3333 -L 127.0.0.1:18083:127.0.0.1:23 -L 127.0.0.1:18084:aspmx.l.google.com:25 -o "ProxyCommand /usr/bin/corkscrew X.X.X.X 8080 %h %p" -o "ServerAliveInterval 10" -o "ServerAliveCountMax 2" -g -R *:7722:localhost:22 $REMOTE_HOST
 #sudo autossh -M 0 -q -N ... ##autossh sometimes it stops working for some reason, so now using only ssh

 sleep 5
done




v5 Cron script to verify that a tunnel is working connecting through it to ssh - better, cleaned up

tunnel-hook-xx

#!/bin/bash
# start the script with "test" to display status   ./tunnel-hook-xx test

REMOTEUSER="vpn"
REMOTEHOST="xx.server"
SSHKEY="/home/marti/.ssh/id_dsa"

REMOTESSH=443
NEWLOCALPORT=12122

LOCALSSH=22
NEWREMOTEPORT=12122

STARTCOMMAND="/home/marti/tunnel-start-germ2a"

LOGFILE="${0}.log"
LOGFILE="/home/marti/$(basename $LOGFILE)" #In case the script is run from a symbolic link (ex. /etc/network/if-up.d/), we force another specific folder for the logs

if [ "$1" = "test" ] ; then    # Only test and display OK/No OK
  ssh -p $NEWLOCALPORT -o ConnectTimeout=1 -o ConnectionAttempts=1 -i $SSHKEY [email protected] exit 
  # > /dev/null 2>&1
  if [ $? -ne 0 ] ; then
     echo "No OK"
  else
     echo "OK"
  fi
  exit
fi

# Try to connect via ssh to the local forwared port $NEWLOCALPORT
ssh -p $NEWLOCALPORT -o ConnectTimeout=2 -o ConnectionAttempts=1 -o StrictHostKeyChecking=no -i $SSHKEY [email protected] exit 
# > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   echo "$(date +'%Y-%m-%d %H:%M:%S') - Cannot connect to local tunnel $NEWLOCALPORT" |tee -a $LOGFILE

   sudo pkill -f -x '$STARTCOMMAND'
   BASENAMESCRIPT=$(basename $STARTCOMMAND)
   sudo killall $BASENAMESCRIPT
   # sudo pkill -f "ssh -q -N -p443"
   sudo pkill -f "ssh -q -N -p $REMOTESSH -g -R *:$NEWREMOTEPORT:127.0.0.1:$LOCALSSH -L 127.0.0.1:$NEWLOCALPORT:127.0.0.1:$REMOTESSH"
   sudo killall $BASENAMESCRIPT

   $STARTCOMMAND &

   exit
fi


tunnel-start-xx

#!/bin/bash

REMOTEUSER="vpn"
REMOTEHOST="xx.server"
SSHKEY="/home/marti/.ssh/id_dsa"

REMOTESSH=443
NEWLOCALPORT=12122

LOCALSSH=22
NEWREMOTEPORT=12122

LOGFILE="${0}.log"
LOGFILE="/home/marti/$(basename $LOGFILE)" #In case the script is run from a symbolic link (ex. /etc/network/if-up.d/), we force another specific folder for the logs

while [ 1 ]; do
 echo "$(date +'%Y-%m-%d %H:%M:%S') - Starting ssh" |tee -a $LOGFILE

 sudo ssh -q -N -p $REMOTESSH -g -R *:$NEWREMOTEPORT:127.0.0.1:$LOCALSSH -L 127.0.0.1:$NEWLOCALPORT:127.0.0.1:$REMOTESSH -L 127.0.0.1:18082:127.0.0.1:3333 -CD 18081 -o "ProxyCommand /usr/bin/corkscrew X.X.X.X 8080 %h %p" -o "ServerAliveInterval 10" -o "ServerAliveCountMax 2" -o StrictHostKeyChecking=no -i $SSHKEY [email protected]$REMOTEHOST

 # The first part "ssh -q -N -p $REMOTESSH -g -R *:$NEWREMOTEPORT:127.0.0.1:$LOCALSSH -L 127.0.0.1:$NEWLOCALPORT:127.0.0.1:$REMOTESSH" is used to kill this process by the tunnel-hook-xx script


 echo "$(date +'%Y-%m-%d %H:%M:%S') - Start script loop" |tee -a $LOGFILE
 sleep 5
done