当客户端和主机在同一台机器上时,ssh 如何工作?

当客户端和主机在同一台机器上时,ssh 如何工作?

我借助 docker 容器来说明我的问题,但这个例子与问题的其余部分无关。事实上,任何允许使用桥接接口和 ssh 的程序都可以。

我使用 Docker 容器,它sshd在后台运行守护进程,该守护进程由在supervisord前台运行的守护进程生成。我主要使用 ssh 来安全地进行 X11 转发,而无需绑定/tmp/.X11-unix到容器中并将套接字完全暴露给容器。如果我docker top containername在启动容器后立即使用,我会得到以下输出:

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                4732                535                 1                   19:56               ?                   00:00:00            /usr/bin/python /usr/bin/supervisord
root                4745                4732                0                   19:56               ?                   00:00:00            /usr/sbin/sshd

这与预期一致。现在,我将容器上的端口 22 暴露给主机上的端口 5000。因此,我可以使用 登录到我的容器ssh -X username@localhost -p 5000。我知道当客户端和主机是不同的计算机和不同的网络时 ssh 是如何工作的,但是当客户端和主机是同一台计算机时我有一些疑问(在我的情况下,客户端是我的普通机器,主机是我普通机器上的容器)。我知道 docker 在我的普通机器上的物理网络设备和我的机器上的虚拟网络设备之间建立了一座桥梁。

  1. 但是我的普通机器和容器究竟如何相互通信?它们是否使用桥接设备分配给它们的 IP 地址并通过这些地址进行通信?

  2. 此过程中涉及的端口是如何消除使用 IP 地址的需要的?

  3. 当客户端和主机在同一台机器上并且按照我刚才概述的方式进行配置时,是否有最有效/推荐的使用 ssh 的方法。

广泛的互联网搜索并没有找到足够的答案。话虽如此,我当然不会断言这样的网站不存在!

答案1

本地通信如何工作?很简单:与普通的非本地通信完全一样,只是网络堆栈检测到通信的目的地在同一台机器上,因此它不需要将通信从堆栈移交给物理层,而是将其传递给 IP 层的接收部分。

尤其是这意味着 IP 地址仍然是必要的,因为 IP 网络连接总是需要源端口和地址以及目标端口和地址 - 在这种情况下,“特殊”部分只是源地址和目标地址相同127.0.0.1/localhost

从 SSH 或任何其他网络协议的角度来看,什么都没有改变。

就虚拟化而言,有两种方法:桥接网络和 NAT。

  • 使用桥接网络,虚拟机是网络的正式成员,拥有自己的地址和一切。其工作原理如下:
    • 虚拟化软件在主机中创建一个虚拟网络接口,反映虚拟机内部的模拟物理设备。
    • 在主机上,您可以创建一个网桥,并将虚拟设备和物理设备绑定到该网桥。这就像一个交换机,物理设备是通往网络其余部分的上行链路。
    • 就像真正的交换机一样,桥接设备知道连接到它的 IP 地址,并将相应地传输流量,而不会在线路上发送针对连接到桥接的(虚拟)设备之一的流量。在网络堆栈中,它位于链路层。
  • 使用 NAT,您无法直接与虚拟机通信,而必须使用主机作为路由器,就像大多数家庭网络一样。
    • 您仍拥有连接到(虚拟)交换机的虚拟接口。但此交换机并不充当网桥,也不连接到物理网络。
    • 主机的网络接口连接到物理网络和虚拟网络,并充当 NAT 路由器。如果您想直接与虚拟机通信,则必须进行端口转发。

我不确定 Docker 究竟是如何运行的,它可能使用了另一种方法,直接将物理主机上的端口连接到虚拟机的端口,而不需要整个 NAT 过程。

在您的 SSH 示例中,后台实际上发生了很多事情:

  • 如果您执行ssh user@localhost -p 5000,网络堆栈会检测到这是本地的,并且不会在线上发送流量。相反,它会将其发送到本地计算机的端口 5000。
  • 监听端口 5000 的 NAT 转发器将流量发送到虚拟接口,虚拟机在该虚拟接口上将该流量作为正常流量接收到端口 22 上。

相关内容