保持SSH隧道打开,并运行远程命令

防火墙后面的计算机(在远程位置)连接到我的服务器以打开隧道…目的是从服务器,我可以通过SSH连接到计算机。

计算机连接:

while true; do PORT=$(((RANDOM %= 1000) + 2000)); ssh -R $PORT:localhost:22 -o ServerAliveInterval=30 "server" "record_port.sh '$PORT';"; sleep 5; done 

服务器上的“record_port.sh”shell脚本包含:

 echo "$PORT" > "/tmp/tunnel.port"; while true; do sleep 300; done 

然后我可以通过以下方式连接到服务器:

 function computer { ssh -p `cat /tmp/tunnel.port` -o NoHostAuthenticationForLocalhost=yes localhost } 

服务器还在/ etc / ssh / sshd_config中有一个“ClientAliveInterval 30”,并使用rbash和dss键之类的东西。

我使用了一个随机端口,因为我发现有时端口已经被使用,意图是如果我终止服务器上的连接,计算机将在5秒钟后重新连接一个新的端口。

而且因为它是一个随机的端口,我需要shell脚本来logging正在使用的端口(没有任何运气与lsof)。

但问题是,如果互联网连接丢失,隧道closures,计算机将愉快地重新连接一个新的隧道在不同的端口号,但原来的进程(record_port.sh)继续:

 ps ax | grep "report_port" 4166 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2833 6863 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2605 20109 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2023 pstree init(1)─┬─... ├─sshd(28187)─┬─sshd(6860)───sshd(6862)───tunnel.port.sh(6863)───sleep(15533) │ ├─sshd... (my current shell) ├─tunnel.port.sh(4166)───sleep(15232) ├─tunnel.port.sh(20109)───sleep(15318) 

尽pipe没有端口随机化,但我还是使用了类似的模型。 我有电脑,我会叫远程N​​AT后面的“Hider”直接连接到本地,中央服务器,我会用公共IP调用“家”。 这个SSH链接的目的是在Hider的Home端创build用于访问SSH的端口。

这是在Hider上运行的脚本:

 #/bin/sh # script: allow-ssh-from-home unset DISPLAY interval=30 while : ; do echo opening tunnel at `date +'%Y-%m-%d %H:%M:%S %Z'` if ssh -NC \ -o IdentitiesOnly=yes \ -o IdentityFile=$HOME/.ssh/id_rsa-hider-tunnel \ -o CheckHostIP=no \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o GSSAPIAuthentication=no \ -o PasswordAuthentication=no \ -o ServerAliveInterval=30 \ -o ExitOnForwardFailure=yes \ -R2222:127.0.0.1:22 \ home.example.com then echo Respawning after success... else echo Delaying $interval seconds after failure... | tr -d '\012' sleep $interval echo done. Respawning... fi done #------------------------------------eof 

在Hider上,〜/ .ssh / authorized_keys文件有这个(有一些[elided]):

 command="",no-user-rc,no-pty,no-X11-forwarding,no-agent-forwarding ssh-rsa AAA[more keys]RQ== rsa-hider-tunnel-key 

在Home中,〜/ .ssh / config具有以下内容。 注意ServerAliveCountMax,允许更多的存活信息被遗漏(默认值是3),否则在Home上的SSH将会死亡。 同样的configuration也可能出现在Hider上,虽然我不确定,因为它已经有一段时间了。

 Host localhost NoHostAuthenticationForLocalhost yes Host * HashKnownHosts no FallBackToRsh no ForwardAgent yes ForwardX11 yes Compression yes ServerAliveInterval 30 ServerAliveCountMax 120 

Hider的使用模式是login,然后:

 $ exec ssh-agent bash $ ssh-add # add a key known for yourself@Home $ exec allow-ssh-from-home # links to Home, logs out if interrupted 

现在,从任何地方login到主页,然后:

 ssh -p 2222 localhost 

此时,Hider需要authentication – 这是一个好主意,以防有人闯入家中。

我现在使用的解决scheme是将命令拆分为两部分:

 while true; do PORT=$(((RANDOM %= 1000) + 2000)); ssh "server" "record_port.sh '$PORT';"; ssh -N -R $PORT:localhost:22 -o ServerAliveInterval=30 "server"; sleep 5; done 

虽然不完善,但它意味着第一个SSH连接可以在指定要尝试的端口号后返回,然后第二个SSH连接可以build立没有远程shell的隧道。

这会在服务器上留下“record_port.sh”(简单地运行)(没有while / sleep):

 echo "$PORT" > "/tmp/tunnel.port";