我希望使用 SSH 建立一个临时端口转发,运行本地命令然后退出,关闭 ssh 连接。
该命令必须在本地运行,而不是在远程站点上运行。
例如,考虑 DMZ 中的服务器,您需要允许计算机中的应用程序连接到端口 8080,但您只有 SSH 访问权限。
如何才能做到这一点?
我希望使用 SSH 建立一个临时端口转发,运行本地命令然后退出,关闭 ssh 连接。
该命令必须在本地运行,而不是在远程站点上运行。
例如,考虑 DMZ 中的服务器,您需要允许计算机中的应用程序连接到端口 8080,但您只有 SSH 访问权限。
如何才能做到这一点?
假设您从命令行使用 OpenSSH....
SSH 可以打开一个连接,该连接将维持隧道并尽可能长时间保持活动状态:
ssh -fNT -Llocalport:remotehost:remoteport targetserver
您也可以让 SSH 在服务器上启动一些运行一段时间的东西。隧道将在那个时候开放。只要隧道仍在使用中,远程命令退出后 SSH 连接就应该保持。如果您只使用一次隧道,则指定一个短暂的“睡眠”,让隧道在使用后过期。
ssh -f -Llocalport:remotehost:remoteport targetserver sleep 10
如果您希望能够从本地运行的脚本中终止隧道,那么我建议您在 shell 中将其作为后台,然后记录 pid 以便稍后终止。假设您使用的是包含 Bourne shell 的操作系统......
#/bin/sh
ssh -f -Llocalport:remotehost:remoteport targetserver sleep 300 &
sshpid=$!
# Do your stuff within 300 seconds
kill $sshpid
如果您不喜欢使用 shell 将 ssh 设置为后台,您还可以使用高级 ssh 功能来控制后台进程。如此处所述,SSH 的功能ControlMaster
以及ControlPath
您如何使其工作。例如,将以下内容添加到您的~/.ssh/config
:
host targetserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
现在,您的第一个连接targetserver
将设置一个控件,以便您可以执行以下操作:
$ ssh -fNT -Llocalport:remoteserver:remoteport targetserver
$ ssh -O check targetserver
Master running (pid=23450)
$ <do your stuff>
$ ssh -O exit targetserver
Exit request sent.
$ ssh -O check targetserver
Control socket connect(/home/sorin/.ssh/cm_socket/sorin@192.0.2.3:22): No such file or directory
显然,这些命令也可以包装到您的 shell 脚本中。
您可以使用类似于此的脚本(未经测试):
#!/bin/bash
coproc ssh -L 8080:localhost:8080 user@server
./run-local-command
echo exit >&${COPROC[1]}
wait