我有一台计算机 C,通过 SSH 反向隧道连接到服务器 B 的端口 X。
现在我想通过计算机 B 的 X 端口从计算机 A 连接到计算机 C。
当我从计算机 A 到 B 进行常规 SSH 时,如下所示:
ssh -i KEYA B_USER@B_IP
连接良好。
但是当我在端口 X 进行连接时:
ssh -i KEYA B_USER@B_IP -p X
它要求输入用户密码。但我没有 B 用户的密码,然后它显示:在 PORT X 收到来自 B_IP 的断开连接:身份验证失败次数过多。
我无法找到解决这个问题的方法。我已经花了好几个小时绞尽脑汁。请帮忙。谢谢。
编辑:
用于从 C 连接到 B 的 SSH 反向隧道:
ssh -i KEYC -f -N -R B_IP:PORT_X:localhost:22 B_USER@B_IP -o GatewayPorts=yes
反向隧道连接良好。
答案1
建立隧道后,连接到X
B 端口的所有内容都会通过隧道传输到 C。C 上的 SSH 服务器localhost:22
代表从任何地方到达 B 的原始连接进行连接。任何监听22
C 端口的东西(无论是它sshd
还是其他东西)都会看到来自 C 的连接。
这意味着当你在 A 上执行此操作时:
ssh -i KEYA B_USER@B_IP -p X
C 上的监听服务器认为你做了类似这样的事情在C上:
ssh -i local_copy_of_KEYA B_USER@localhost -p 22
因此B_USER
, 的内容KEYA
应该被 SSH 服务器识别在C上。此时,它们对 B 是否有意义并不重要。隧道建立后,您应该将该地址B_IP:X
视为 localhost:22
来自 C 的地址的别名。除非您不必在 C 上,这就是建立隧道的全部意义所在。
当连接到端口时X
,B_IP
您应该指定一个对 C 有效的用户名和在 C 上验证该用户的密钥(或密码)。
需要明确的是:有两个分离SSH 连接:
- 从 C 到 B 的隧道。它创建一条从 B 到 C 的隧道,其一端是 C 上的 SSH 客户端(
ssh -R …
),另一端是 B 上的 SSH 服务器。 从 A 到 C 的一条连接。它的一端是 A 上的 SSH 客户端,另一端是 C 上的 SSH 服务器。它是应用层(SSH)中的单条连接,但从技术上讲有两个 TCP/IP 连接:
- 从A到B,
- 从C到C,
以及中间的隧道(B到C)。
已经建立的隧道连接 B 和 C,因此有一条路由:A 到 B 到 C(严格来说:A 到 B 到 C 到 C;一般来说可能是 A 到 B 到 C 到 D)。对于 TCP/IP,A 上的 SSH 客户端看到(创建)第一部分(A 到 B),而 C 上的 SSH 服务器看到另一部分(C 到 C;此部分由
ssh
启动隧道的进程动态创建ssh -R …
:)。对于 SSH(不同层!),A 上的 SSH 客户端和 C 上的 SSH 服务器是同一连接的两端。
重要的是,“A 到 C” SSH 连接只是通过 TCP/IP+隧道+TCP/IP 传输的有效载荷。隧道不会改变被隧道传输的应用层中的任何内容;它只是连接两个网络,转换地址和端口(比较:NAT)。
A 上的SSH 客户端(程序,ssh
)和 C 上的 SSH 服务器(程序,例如sshd
)对传输层(TCP)和互联网层(IP)的了解存在分歧;但属于应用层(SSH)的所有内容都在 A 和 C 之间按原样传输。特别是身份验证和加密仅由 A 上的 SSH 客户端和 C 上的 SSH 服务器管理。隧道的任何末端都不会干扰此有效载荷。
即使隧道的任何一端试图干扰有效载荷,它也无法做到——因为有加密。对于其他应用协议(没有加密),隧道可能会成功干扰;但它永远不会这样做,它的工作是依赖有效载荷而不改变它。
出于这些原因,您不应期望适用于 B 的凭据会自动适用于 C。B 只是隧道的一端。就 SSH(应用层协议)而言,您从 A 发起的 SSH 连接与 A 上的 SSH 客户端和 C 上的 SSH 服务器有关;仅此而已,与 B 无关。要更改身份验证过程,您需要重新配置 A 和/或 C。