[如同设置 IPsec 客户端 MTU 的正确方法(Linux/Racoon),但不同之处在于响应方没有路由器]
我有一个设置,其中本地网络中的机器需要与数据中心中的 Linux 服务器通信。本地网络的路由器有一个静态外部 IP 地址,因此我在路由器和服务器上都配置了策略,以在传输模式下使用 IPsec 相互通信。
这对于小数据包来说效果很好,但是服务器无法准确确定传出数据包的 MTU,从而导致连接挂起。
避免这些问题的最佳方法是什么?
目前的想法:
限制路由表中的 MTU。这需要服务器上的静态路由,并且基本上可以工作,但当我在两周内引入移动(“roadwarrior”)客户端时,它就无法正常工作了。
使用 iptables 修改传入数据包的 TCPMSS 设置。这似乎没有实际效果,并且不适用于 UDP。
答案1
这是 Linux 内核 IPsec 的一个错误。它在决定是否对传出数据包进行分段时没有考虑传输模式 ESP 封装的大小;然后由于超出了接口 MTU,它在输出时被丢弃。我不知道这个问题是否已在较新的内核中得到修复。
答案2
1) 数据包没有 MTU。MTU 适用于接口。数据包大小与接口 MTU 进行比较。2) 路由器始终知道其接口的 MTU。此信息可能存在错误,但确实存在。3) 可以修改传入数据包的 TCP MSS。这对传输有实际影响。
至于您的设置 - IPSec 通道可以封装的最大大小(无碎片)由 IPSec 标头大小决定,因此这取决于转换集和加密密码。如果不知道,就无法计算。
不过,如果有效载荷 + 报头的总和大于传出接口的 MTU,这并不意味着数据包将被丢弃 - 可能会发生碎片。即使封装数据包设置了 DF 位 - 它可能会也可能不会被复制到外部报头(如果我们谈论隧道),这取决于您的安全端点的配置。
我不太明白您的设置。我猜您使用的是 IPsec 传输模式,并带有一些中间封装,如 gre 或 ipip。