I am struggling with writing what I assume should be an easy script.
Basically I have a computer at work, which is hidden behind a NAT to which I don’t have access. I need to SSH into this computer, so the only way to do this is to set a reverse port redirect, where this NATted computer will connect to my server at home, while redirecting a port for it self and then I can simply ssh into it through my home server.
The .sh script will be executed by the computer at work every 5 minutes and this is what I would like it to do:
Check if there is an active ssh connection to my server going on and if yes, then simply do nothing and exit the script.
If there is no active connection detected, then connect by executing “ssh [email protected] -i key.priv” and exit the script.
If the ssh connection attempt hangs for some reason, for say longer than 2 minutes, then force exit the script (not sure if this is possible to do, if not, then it doesn’t have to be there)
Thank you kindly for your advice.
Here is Solutions:
We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.
Let’s assume you are using the following command to establish your SSH connection (I would prefer to use
.ssh/config file that will simplify the ssh command, but this is not mandatory):
ssh [email protected] -fTN -R 2222:127.0.0.1:22 -i $HOME/.ssh/id_rsa
- the options
-fTNwill push the connection into the background – I wrote this leading part, because this set of options is critical for my suggestion below;
- the option
-R 2222:127.0.0.1:22will create the reverse tunnel;
- the option
-i $HOME/.ssh/id_rsaindicates the identity file.
We can use
ps -aux | grep "<our command>" | sed '$ d' to check whether the connection is established or not. Based on this our script could be:
#!/bin/bash SSH_COMMAND="ssh [email protected] -fTN -R 2222:127.0.0.1:22 -i $HOME/.ssh/id_rsa" if [[ -z $(ps -aux | grep "$SSH_COMMAND" | sed '$ d') ]] then exec $SSH_COMMAND fi
Call this script
my_autossh, place it in
~/bin and make it executable. Then run
crontab -e and add the following job:
* * * * * $HOME/bin/my_autossh
If you do not want to use Cron, modify the scrip
my_autossh in this way:
#!/bin/bash SSH_COMMAND="ssh [email protected] -fTN -R 2222:127.0.0.1:22 -i $HOME/.ssh/id_rsa" while true; do if [[ -z $(ps -aux | grep "$SSH_COMMAND" | sed '$ d') ]] then eval $SSH_COMMAND else sleep 60 fi done
nohup to push it into the background:
nohup my_autossh >/dev/null 2>&1 &
Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂