OPENPPP2 通过 rinetd/gost 前置端口转发的问题
问题现象
许多人在部署 PPP PRIVATE NETWORK™ 2(openppp2)时,尝试在前置机使用 rinetd、gost 等端口转发工具,结果发现速度剧烈波动——时而跑满带宽,时而骤降为低速,本文将阐述原因及解决方法。
为什么会出现 TCP-over-TCP 灾难?
- openppp2 的设计目标:它是为直连网络环境优化的单点吞吐效率技术,所有加速机制(包括拥塞控制和 VMUX)都基于一个假设——客户端与服务器之间是一条端到端的单层 TCP 连接。
- openppp2 链路:默认基于 TCP(
ppp://),将 IP 帧封装在一条 TCP 连接中传输。 - rinetd/gost 转发机制:它们会将客户端↔服务器的一条 TCP 连接拆分成两条独立的 TCP 连接(客户端↔中转机、中转机↔服务器)。
- 后果:这就形成了 双层 TCP 嵌套——链路层(IP 帧)外面又套了一层 TCP(转发层)。两层 TCP 各自拥有独立的拥塞控制和重传机制,网络抖动时互相叠加放大,导致吞吐量剧烈震荡。这完全破坏了 openppp2 为直连链路设计的优化算法。
- VMUX 加剧问题:openppp2 的 VMUX(虚拟多路复用)会把多个子流合并到同一条物理连接中,以提升效率。但当物理连接本身已经是双层 TCP 时,任何一个子流的微小波动都会触发整个连接的拥塞控制,使波动全局化,速度剧烈起伏。VMUX 的加速算法(单边/双边加速)原本建立在端到端单层连接之上,此时反而成了放大器。
为什么 SNAT 是稳定的?
SNAT 工作在网络层,它只修改 IP 包地址,不拆分 TCP 连接。客户端到服务器的 TCP 连接是完整的单层连接,openppp2 的拥塞控制和 VMUX 能直接作用于真实链路,符合其直连优化的前提,因此速度平稳。
为什么 HTTP/SOCKS 转发没有类似问题?
- 普通应用(HTTP/SOCKS):转发的是应用层原始数据流(例如 HTTP 请求),这些数据在传输层被分段,但不会在 TCP 负载中再次封装 IP 包。
- openppp2 链路:传输的是完整的 IP 包(内含 TCP/UDP 段),当它再经过一层 TCP 转发时,就形成了 TCP(转发层)封装 TCP(链路层) 的嵌套。
- 所以,rinetd/gost 转发普通流量时没问题,但转发 openppp2 帧时必然触发 TCP-over-TCP 灾难。
为什么关闭 VMUX 后,rinetd/gost 的影响变小?
- VMUX 开启时:多个子流共享同一物理连接,双层 TCP 导致所有子流同步震荡,速度表现为剧烈波动。
- VMUX 关闭后:每个子流独立传输,波动被限制在单一子流内,不会“传染”给其他子流。虽然单个子流仍受 TCP 嵌套影响,但宏观上速度波动幅度减小,可能从“剧烈震荡”变为“相对平稳的慢速”。
- 关闭 VMUX 意味着放弃了它为直连网络设计的加速优化,但同时也移除了波动放大效应,因此影响变小。
实践建议
- 尽量避免使用 rinetd/gost 等端口转发工具前置 openppp2 服务器,因为它们破坏了 openppp2 依赖的直连网络假设。
- 如果必须前置,请关闭 VMUX(
--tun-mux 0),以减轻波动。 - 推荐方案:使用 Layer 3 IP 转发(如 SNAT),保持端到端的 TCP 连接透明,让 openppp2 的直连优化充分发挥作用。
1万+

被折叠的 条评论
为什么被折叠?



