通过 TCP 连接创建 VPN

use*_*983 1 linux vpn tcp tun-tap

我需要通过 TCP 连接创建一个虚拟 IP 网络。托管系统是Linux,带有TUN/TAP内核驱动,很容易接收和重新注入虚拟网络的IP包。

困难的部分是将接收到的 IP 数据包传输到另一台主机。由于一些非技术原因,我只能通过 TCP 协议而不是 UDP 传输数据包。通过 UDP 传输 IP 数据包很容易,但使用 TCP 就变得很棘手,原因如下:

UDP协议不支持重传/重排序,就像IP一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(这些是 TCP/IP 正常工作所必需的,如果这些“特性”丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果 IP 数据包通过 TCP 传输,则所有必需的“功能”都将丢失,除非它们以某种方式进行模拟。

看来我必须在 TCP 连接上伪造某种数据包重复/丢失/重新排序,或者修补内核 TCP/IP 协议堆栈。这两种选择都不容易。

我的问题还有其他更简单的解决方案吗?还是我只是进入了一个完全错误的方向?我都是耳朵。

==== 更新 ====

我正在考虑使用原始 IP 套接字(它可以在仍然使用 TCP 数据包的同时轻松摆脱物理网络上的所有 TCP 重传/重新排序内容)来传输接收到的虚拟网络 IP 数据包。但是在接收主机上,如何只接收我感兴趣的数据包并将所有其他 IP 数据包返回到内核 TCP/IP 堆栈?

Kil*_*nDS 5

首先,您不想通过 TCP 创建 VPN,因为您最终会得到 tcp-over-tcp。主要问题是您的内部 TCP 和外部 TCP 的计时器可能会显着不同,这会对您的 TCP 会话可靠性产生负面影响。你可以在这里找到更长的解释。

UDP协议不支持重传/重排序,就像IP一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(这些是 TCP/IP 正常工作所必需的,如果这些“特性”丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果 IP 数据包通过 TCP 传输,则所有必需的“功能”都将丢失,除非它们以某种方式进行模拟。

这是没有意义的,如果您的外层使用 TCP 作为传输机制,则没有什么可以阻止您的内层仍然使用完整的 ip/tcp 堆栈,包括这些功能。它们可能会像我说的那样严重冲突,但这并不是说这个功能消失或完全中断。

看起来您实际上只想使用 TCP 来获取标头并忽略实际协议,这确实可以避免 tcp over tcp 的问题。然而,这又是一个非常糟糕的主意。防火墙、NAT、DPI、tcp 增强器的流处理变得越来越普遍,如果你伪造 TCP 数据包,你可能会加重这些盒子的压力,可能再次破坏你自己的连接。

所以你应该问问自己为什么不能使用 UDP,以及是否没有替代协议(标头)是可以的,比如 GRE 或 L2TP。