I have a script which establishes a reverse tunnel on an endpoint HostB. It looks like this:
cat tun.sh
#!/usr/bin/env bash
# Test code
/usr/bin/ssh -V 1> /home/userA/bin/tun.stdout 2> /home/userA/bin/tun.stderr
# Establish tunnel
createTunnel() {
/usr/bin/ssh -R *:19999:localhost:22 userB@hostB
}
# Do nothing if tunnel is already established
/usr/bin/ssh -p 19999 userA@hostB true
if [[ $? -ne 0 ]]; then
createTunnel
fi
when I run it manually like ./tun.sh it works, and I can see on HostB, that userA is logged in.
If I run it again on HostA but from another console, it works as expected - it does not launch a second tunnel.
Everything so far is good.
I now edit my crontab to look like this:
crontab -l
# m h dom mon dow command
*/1 * * * * /home/userA/bin/tun.sh
It runs the script every minut. This should be fine, since the script terminates if the tunnel is already established.
However, now userA does not get logged in as when I run it manually from the console.
The test code in the top of the script confirms that the script is being called, and that it has permission to execute /usr/bin/ssh:
~/bin$ ls
tun.sh tun.stderr tun.stdout
~/bin$ cat tun.stderr
OpenSSH_5.3p1 Debian-3ubuntu7, OpenSSL 0.9.8k 25 Mar 2009
~/bin$ cat tun.stdout
[empty]
For some reason -V writes to stderr and not stdout, but that is a detail. The main point is here that the script is being executed every minute.
My question is: why is the SSH tunnel not established?
/usr/bin/ssh -R *:19999:localhost:22 userB@hostB... Need not be the problem but that is a quite direct way to shell hell.ssh-agentseems to be the right pointer. I will post an answer when I have set this up correctly.