SSH Scripts
Other Bash Scripts
Contingut
- 1 v1 Cron script to keep a reverse tunnel
- 2 v1.2 Cron script to keep a reverse tunnel in case pgrep is not available - better
- 3 v2 Cron script to keep a local tunnel
- 4 Cron script to keep a double reverse tunnel (using a gateway)
- 5 v3 Cron script to keep a local/remote tunnel v3 using autossh - better
- 6 v4 Cron script to verify that a tunnel is working connecting through it to ssh
- 7 v5 Cron script to verify that a tunnel is working connecting through it to ssh - better
- 8 v5 Cron script to verify that a tunnel is working connecting through it to ssh - better, cleaned up
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
- more info: http://zedhead777.blogspot.de/2009/10/help-creating-cron-job-ssh-tunnel.html
- and http://www.anattatechnologies.com/q/2011/11/reverse-ssh-tunnel/
- info about sshd configuration: http://wiki.fabelier.org/index.php?title=Permanent_Reverse_SSH_Tunneling
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 unixsmod@earth 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 user@server 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 unixsmod@earth 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 unixsmod@earth 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 unixsmod@earth" COMMAND2="/usr/bin/ssh -f -N -R 0.0.0.0:$REMOTE_PORT:127.0.0.1:22 -p $LOCAL_PORT esrin@localhost" 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 esrin@localhost 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 marti@localhost 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 marti@localhost 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 $REMOTEUSER@localhost 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 $REMOTEUSER@localhost 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 $REMOTEUSER@$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