我想通过一个 SSH 堡垒服务器(即 )访问几个不同的 SSH 服务器(即dest1
)。我想避免每次想连接到不同的 SSH 服务器时都登录堡垒服务器。我该怎么做呢?dest2
bastion
我尝试将我的公钥添加到堡垒服务器。但是,堡垒服务器禁用了公钥登录,需要密码登录。(密码是密码和 Yubikey 输出的组合。)
我尝试设置动态端口,然后通过动态端口进行本地端口转发。
我使用以下命令设置动态端口。出现提示时,我输入密码。
ssh -f -N -o KeepAlive=yes -D 127.0.0.1:55555 -l user bastion
然后我使用以下命令设置本地端口转发。
ssh -vvv -f -N -L 127.0.0.1:44444:dest1:22 -p 55555 localhost
该命令不起作用。我收到以下输出和错误消息。
OpenSSH_8.0p1, OpenSSL 1.1.1b 26 Feb 2019
debug2: ssh_connect_direct
debug1: Connecting to 127.0.0.1 [127.0.0.1] port 55555.
debug1: Connection established.
kex_exchange_identification: Connection closed by remote host
如果可行,那么我可以简单地执行以下操作来访问 dest1:
ssh -p 44444 me@localhost
后面我会为dest2再设置一个本地端口转发,以类似的方式访问dest2。
编辑:注意:我正在使用 Cygwin。
原始示例
您的尝试没有成功,因为这不是
-D
应该使用的方式。它不会创建您可以简单地通过 SSH 访问的直接侦听器。相反,它创建了一个SOCKS侦听器,它只与可以使用 SOCKS4/5 代理告诉“服务器”他们首先想要的主机的应用程序兼容——这就是“动态”部分的来源。如果使用第一个命令,您的第二个命令会起作用
-L 55555:localhost:22
,但老实说,这两个命令是完全多余的——它不会为您节省任何身份验证检查或任何东西。事实上,您最终会比必要的更多次对堡垒进行身份验证。直接用就
ssh -L 44444:dest1:22 bastion
行了。(如果你有多个隧道,你可以在这个命令上指定多个-L。)然后你就可以使用ssh -p 44444 me@localhost
来访问dest1。建立隧道:
ssh user@bastion -f -N -L 40001:dest1:22 -L 40002:dest2:22
连接到目标 1:
ssh localhost -p 40001
备选方案 1
您可以朝另一个方向走,只使用
-D 55555
动态隧道选项。但是,您不能简单地将它与ssh -p
;一起使用。您需要可以充当 SOCKS 客户端的其他软件。一个示例是 socat,您可以将其用作 sshProxyCommand
帮助程序:建立隧道:
ssh user@bastion -f -N -D 55555
连接到目标 1:
ssh dest1 -o ProxyCommand="socat stdio socks4a:localhost:[%h]:%p,socksport=55555"
备选方案 2
您可以使用
ControlPath
和ControlMaster
选项告诉初始ssh客户端充当其他客户端的代理:建立连接:
ssh user@bastion -S ~/.ssh/S.bastion -f -N -M
打开交互式外壳:
ssh bastion -S ~/.ssh/S.bastion
连接到其他服务器:
ssh bastion -S ~/.ssh/S.bastion -t "ssh dest1"
添加隧道:
ssh bastion -S ~/.ssh/S.bastion -O forward -L 12345:dest1:22
删除隧道:
ssh bastion -S ~/.ssh/S.bastion -O cancel -L 12345:dest1:22
(SSHv2 不假设将通过连接创建什么样的通道。就像一个 SSHv2 连接可以承载任意数量的 TCP 隧道或 ssh-agent 请求一样,它也可以承载任意数量的交互式和非交互式 shell 会话– 不一定是 0 或 1。)
~/.ssh/config 文件选项如下所示: