如何通过SSH隧道为SSH连接configuration快捷方式

我公司的生产服务器(FOO,BAR …)位于两台网关服务器(A,B)之后。 为了连接到服务器FOO,我必须打开与我的用户名JOHNDOE服务器A或B的SSH连接,然后从A(或B)我可以访问任何生产服务器打开与标准用户名的SSH连接(让我们称之为威比)。

所以,每次我都要这样做:

ssh johndoe@a ... ssh webby@foo ... # now I can work on the server 

正如你可以想象的,当我需要使用scp或者如果我需要快速打开多个连接时,这是一个麻烦。

我已经configuration了一个SSH密钥,并且我正在使用.ssh / config作为一些快捷方式。

我想知道是否可以创build某种types的sshconfiguration来打字

 ssh foo 

让SSH为我打开/转发所有的连接。 可能吗?

编辑

womble的答案正是我正在寻找,但现在看来,我不能使用netcat,因为它没有安装在网关服务器上。

 weppos:~ weppos$ ssh foo -vv OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006 debug1: Reading configuration data /Users/xyz/.ssh/config debug1: Applying options for foo debug1: Reading configuration data /etc/ssh_config debug2: ssh_connect: needpriv 0 debug1: Executing proxy command: exec ssh a nc -w 3 foo 22 debug1: permanently_drop_suid: 501 debug1: identity file /Users/xyz/.ssh/identity type -1 debug2: key_type_from_name: unknown key type '-----BEGIN' debug2: key_type_from_name: unknown key type 'Proc-Type:' debug2: key_type_from_name: unknown key type 'DEK-Info:' debug2: key_type_from_name: unknown key type '-----END' debug1: identity file /Users/xyz/.ssh/id_rsa type 1 debug2: key_type_from_name: unknown key type '-----BEGIN' debug2: key_type_from_name: unknown key type 'Proc-Type:' debug2: key_type_from_name: unknown key type 'DEK-Info:' debug2: key_type_from_name: unknown key type '-----END' debug1: identity file /Users/xyz/.ssh/id_dsa type 2 bash: nc: command not found ssh_exchange_identification: Connection closed by remote host 

作为Kyle的答案的更具体的版本,你想放在~/.ssh/config文件中的是:

 host foo User webby ProxyCommand ssh a nc -w 3 %h %p host a User johndoe 

然后,当你运行“ssh foo”的时候,SSH会尝试SSH到johndoe@a ,运行netcatnc ),然后通过这个隧道执行到webby@foo的SSH。 魔法!

当然,为了做到这一点,需要在网关服务器上安装netcat。 这个软件包可用于每个主要的发行版和操作系统。

您可以在〜/ .ssh / config文件中使用ProxyCommand指令,例如使用netcat作为中继:

 host server2 ProxyCommand ssh server1 nc server2 22 

你只需要使用'ssh server2'。 该指令的手册页信息可在'man ssh_config'中find

我更喜欢不同的方法来维护到网关服务器的预先authentication隧道。 在~/.ssh/config

 Host a ControlMaster auto ControlPath ~/.ssh/control-master/%r@%h:%p 

然后在.bashrc

 s () { if ( ssh -O check a 2>&1 > /dev/null 2>&1 ) then ssh -ta ssh $1 else if [[ -S ~/.ssh/control-master/insyte@a:22 ]] then echo "Deleting stale socket..." rm ~/.ssh/control-master/insyte@a:22 fi echo "Opening master session..." if ssh -Nf a then ssh -ta ssh $1 fi fi } 

所以要连接到foo:

 s foo 

你第一次连接它会validation你对“a”,并打开一个持久的,背景的SSH隧道。 随后的“s”通话将通过预先通道隧道几乎瞬间打开。

很好用。

这种types的function存在于较新版本的OpenSSH中,可以被使用

 ssh -W server2 server1 

其中server2是您的预期目标, server1是您的代理主机。 通过在你的sshconfiguration文件中使用ProxyCommand选项,你可以ProxyCommand这个过程:

 host = *.example.com user = packs port = 22 ProxyCommand ssh -W %h:%p server1 

netcat在代理上不可用时,试试这个技巧:

 host foo User webby ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!' host a User johndoe 

那么你应该能够ssh foo

另外,如果你有一个最新版本的ssh(即用-W命令转发标准input和输出),你可以使用:

 host foo User webby ProxyCommand ssh -W foo:%pa host a User johndoe 

最后,仅仅因为我发现它很酷(而不是因为它会在你的特定情况下工作,由于用户名的差异), 朋友的博客文章指出如何使这种事情dynamic和recursion链SSH代理(以及一些东西那工作不好):

 host */* ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p 

然后ssh machine1/machine2应该给你一个machine2上的shell,通过machine1隧道传输。

我不知道是否使用自定义sed命令而不是dirnamebasename可能无法解决与不同的用户名称的问题?

这可以通过执行ssh -At johndoe@a ssh webby@foo来完成ssh -At johndoe@a ssh webby@foo-A命令转发您的ssh代理(这样您可以避免在代理上重新进行身份validation),而-t确保代理上存在terminal。 下面的bash函数可能是有用的:

 ssh-bounce () { local cmd="" for i in "$@"; do cmd+="ssh -At $i " done $cmd } 
 weppos:~ weppos$ ssh foo -vv [..] bash: nc: command not found 

Netcat没有安装在。 当你运行ssh host "command arg"commandhost上执行,而不是在本地机器上执行。