如何为通过SSH隧道的SSH连接配置快捷方式


22

我公司的生产服务器(FOO,BAR ...)位于两个网关服务器(A,B)的后面。为了连接到服务器FOO,我必须使用用户名JOHNDOE打开与服务器A或B的ssh连接,然后从A(或B)访问任何生产服务器,并使用标准用户名打开SSH连接(我们称之为WEBBY)。

因此,每次我必须做类似的事情:

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

可以想象,这在我需要使用scp或需要快速打开多个连接时很麻烦。

我已经配置了ssh密钥,并且还在使用.ssh / config来获取一些快捷方式。

我想知道是否可以创建某种ssh配置以便键入

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

Answers:


36

作为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),然后执行SSH以webby@foo通过此隧道。魔法!

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


优秀!我试图弄清楚这一点,我以前从未遇到过那种确切的情况。我将在这里保留我的答案,以防将来可能帮助其他情况不太明确的人。
凯尔·布​​兰特

我已经更新了原始问题,包括连接的详细输出。看来我不能使用netcat。默认情况下应该可用吗?
西蒙妮·卡列蒂

并非总是如此,您有能力安装它吗?您也许也可以使用telnet做到这一点,但我从未尝试过...
Kyle Brandt

您也可以将netcat下载到您的主目录并在那里进行编译。然后,您可以在代理命令中使用完整路径,即/ home / userName / bin / nc
Kyle Brandt

我刚刚检查了系统设置。在Ubuntu上,默认情况下netcat似乎可用,不幸的是,网关服务器由OpenSUSE驱动。我也将考虑在网关服务器上安装netcat。
Simone Carletti

7

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

host server2
    ProxyCommand ssh server1 nc server2 22

您将只使用“ ssh server2”。该指令的手册页信息可在“ man ssh_config”中找到


5

我更喜欢使用另一种方法来维护通往网关服务器的预先认证的隧道。在~/.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 -t a 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 -t a ssh $1
                fi
        fi
 }

因此,连接到foo:

s foo

首次连接时,它将针对“ a”对您进行身份验证,并打开一个持久的后台ssh隧道。随后对“ s”的调用将几乎通过预先认证的隧道立即打开。

效果很好。


2

这种功能存在于更新版本的OpenSSH中,可以通过以下方式使用

ssh -W server2 server1

server2您的目标目的地在哪里,并且server1是代理主机。您可以通过使用ProxyCommandssh配置中的选项来简化此操作,例如:

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

似乎要使此工作正常,您需要在所有三个位置使用OpenSSH 5.4+:桌面,中介,目标。(当然,第一个也是最后一个)。
史蒂夫·贝内特

@SteveBennett:我已经使用这种方法了一段时间了,它的效果非常好。我不得不在几个RHEL5系统上恢复为netcat方法,这很烦人。
Scott Pack

2

如果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用于转发标准输入和输出的命令),则可以使用:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

最后,只是因为我觉得它很酷(而不是因为用户名不同,并不是因为它可以在您的特定情况下运行),一个朋友的博客文章指出了如何使这种事情变得动态并递归地链接SSH代理(以及一些其他事情)效果不好):

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

然后ssh machine1/machine2给你一个贝壳machine2,穿过隧道machine1

我不知道如果使用自定义sed的命令,而不是dirnamebasename可能不解决不同用户名的问题?


2

这可以通过做来实现ssh -At johndoe@a ssh webby@foo。该-A命令转发您的ssh代理(这样可以避免必须在代理上重新进行身份验证),同时-t确保终端在代理上存在。以下bash函数可能有用:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}

到目前为止,这是最简单的解决方案。现在只需要再投票35次。(顺便说一句-A对我没有任何帮助。)
史蒂夫·贝内特

0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

未在上安装Netcat a。运行时ssh host "command arg"command将在上执行host,而不是在本地计算机上执行。


是的我知道。这正是我在评论womble的答案时所报告的内容。:)
西蒙娜·卡莱蒂

0

自OpenSSH 7.3(2016-08-01)起,该 ProxyJump选项和相应的-J命令行标志已可用,以允许通过一个或多个SSH堡垒或“跳转主机”进行更简单的间接访问。

这消除了Womble解决方案中对外部nc命令的依赖。

ssh -J johndoe@a webby@foo 

将以a用户johndoe的身份从您的工作站建立到网关服务器的SSH连接,并通过该通道将SSH会话通过隧道传递给用户Webby的主机foo。

为了简化该过程~/.ssh/config,您可以在和两者中创建主机定义ssh foo

Host a
    User johndoe

Host foo
    User Webby 
    ProxyJump a
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.