我公司的生产服务器(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
,运行netcat
( nc
),然后通过这个隧道执行到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
命令而不是dirname
和basename
可能无法解决与不同的用户名称的问题?
这可以通过执行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"
, command
在host
上执行,而不是在本地机器上执行。