我有一个在端点上建立反向隧道的脚本HostB
。它看起来像这样:
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
当我手动运行它时,它就像./tun.sh
它一样工作,并且我可以在 HostB 上看到,userA 已登录。如果我在 HostA 上但从另一个控制台再次运行它,它会按预期工作 - 它不会启动第二个隧道。
到目前为止一切都很好。
我现在将 crontab 编辑为如下所示:
crontab -l
# m h dom mon dow command
*/1 * * * * /home/userA/bin/tun.sh
它每分钟运行一次脚本。这应该没问题,因为如果隧道已经建立,脚本就会终止。
但是,现在 userA 没有像我从控制台手动运行它一样登录。
脚本顶部的测试代码确认该脚本正在被调用,并且它具有执行权限/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]
由于某种原因-V
写入stderr
而不是写入stdout
,但这是一个细节。这里的要点是脚本每分钟都会执行一次。
我的问题是:为什么SSH隧道没有建立?
答案1
感谢@Andrew 指出ssh-agent
.据我所知,如果希望能够建立隧道而不必每次输入密码,则必须存储或删除密码。我选择删除它。作为记录,以下是根据我收到的评论进行的一些清理:
#!/usr/bin/env bash
# Establish tunnel
createTunnel() {
/usr/bin/ssh -i /home/laptopuser/.ssh/id_rsa_tunnel -R 2200:localhost:22 [email protected]
}
# Do nothing if tunnel is already established
/usr/bin/ssh -i /home/user/laptopuser/.ssh/id_rsa_tunnel -p 2200 [email protected] true
if [[ $? -ne 0 ]]; then
createTunnel
fi
定时任务:
# m h dom mon dow command
*/1 * * * * /home/laptopuser/bin/establishTunnel.sh
将您的隧道 ID 复制到 vps:
ssh-copy-id -i /home/user/laptopuser/.ssh/id_rsa_tunnel vps.com
等待隧道运行(请参阅sudo watch grep CRON /var/log/syslog
),如果您尚未进入,请复制您的普通 ID~/.ssh/authorized_keys
ssh-copy-id vps.com -p 2200
理想情况下,隧道将作为专用用户在 vps 和笔记本电脑上运行。
答案2
我有一个类似的问题 - 如果从脚本执行而不是从 crontab 执行,ssh 隧道可以工作。 ssh 在 $HOME/.ssh 中查找密钥和known_hosts。如果您在用户 tom 下从 bash 运行脚本,则 $HOME 将是 /home/tom。如果脚本从 crontab 运行,则用户将为 root,$HOME 将为 /home/root(或未定义)。
解决方案:在脚本中为拥有密钥的用户定义 HOME。
HOME=/home/tom