我试图了解不同类型的(虚拟)接口(例如 TUN/TAP、veth 等)之间的区别,并在容器的上下文中研究其中一些类型。
是否可以仅使用 TUN/TAP 接口在容器(在其自己的网络命名空间中)和主机的网络命名空间之间发送数据包,或者是否需要一对 veth 对(每个命名空间中的一端)来执行此操作?
根据我的理解,TUN/TAP 接口只能用于从与该接口的网络命名空间对应的网络堆栈向用户空间发送/接收数据包,而不能在网络命名空间之间发送数据包。它是否正确?
答案1
tun/tap 接口总是属于某个应用程序:发送到该接口的数据包由应用程序读取,并且应用程序写入的数据包通过该接口进入内核网络堆栈。
通常,您将使用虚拟以太网对 (veth) 连接网络命名空间。它们只是将数据包转发到该对接口中的另一个接口。
没有什么可以阻止您编写一个完全执行此操作的应用程序:打开两个 tun/tap 接口,从一个接口读取数据包并将其转发到另一个接口,反之亦然。您还可以使用现成的应用程序来执行此操作,例如socat
.
甚至可以编写两个应用程序,每个应用程序打开一个tun/tap接口,应用程序之间通过其他方式进行通信,从而实现转发。基本上所有 VPN 应用程序都以这种方式工作(尽管对于 VPN 应用程序来说,“通过其他方式”通常是“通过现有网络连接”,因此实际上并不重要)。
所以,是的,使用正确的应用程序,您可以使用 tun/tap 接口连接命名空间。然而,一般来说,这样做没有多大意义,因为你必须编写这样的应用程序,而且它的效率会比仅使用 veth-pair 低。
编辑
我尝试将一个 tun 接口移至我创建的socat
网络命名空间中,尽管在主网络命名空间中运行ns0
,但它工作正常,正如我所预期的那样:socat
socat TUN:10.1.0.254/24,tun-name=tun0a,iff-up TUN:10.1.0.1/24,tun-name=tun0b
ip link set tun0b netns ns0
tun0b
然后您必须再次设置移动后的地址。
因此,“交叉”是通过在与进程不同的命名空间中拥有一个(或两个)tun/tap 网络接口来实现的。