我在 MikroTik 上设置了一个 6to4 SIT 隧道,如下所示MikroTik 帮助文件中的 Hurricane Electric 示例。
它确实有效,但与某些资源的连接速度非常慢,并且经常超时。例如,在升级和重新配置guix 的速度徘徊在 50 KiB/s 左右,并且在下载内核时通常会失败,可能是因为它是一个很大的包。
隧道代理的技术支持建议 1280 的 MTU 太小,应该改用 1480。事实上,如果我将隧道接口的 MTU 更改为该值,连接速度就会恢复正常并以 MiB 为单位计数。我不知道为什么这样做有效,但可能是因为在某些时候,网络设备不需要将较大的数据包拆分成较小的片段,这需要一些开销。
但我遇到了另一个问题:与某些服务器的连接挂起。guix pull
挂起。curl -v
针对有问题的 URL 运行会导致 TLS 协商超时 ( curl: (28) SSL connection timeout
) 或加密库故障 ( curl: (35) gnutls_handshake() failed: Помилка у функції pull.
)。
可以 ping 服务器,但是使用 MTU 大小的消息进行 ping(ping6 -s
后面跟着八位字节数)收到Packet too big
第一个 ping 的响应,然后丢弃其余的 ping。TCP 连接成功,但 TLS 协商超时。MTU 太大,无法连接到此服务器。
RFC 4213提供:
使用静态隧道 MTU 的节点将隧道接口视为具有固定接口 MTU。默认情况下,MTU 必须介于 1280 到 1480 字节(含)之间,但应为 1280 字节。
RFC 6343有一个关于“PMTUD 失败”的部分,其中链接到RFC 2923建议将 IPv6 的 MTU 回退到 1280,除非能够修复“ICMP 黑洞”。
MikroTik 的示例配置建议使用 1280 以避免 MTU 协商的必要性。还有一个clamp-tcp-mss
默认开启的设置:
控制是否更改收到的 TCP SYN 数据包的 MSS 大小。启用后,如果当前 MSS 大小超过隧道接口 MTU(考虑到 TCP/IP 开销),路由器将更改收到的 TCP SYN 数据包的 MSS 大小。收到的封装数据包仍将包含原始 MSS,并且只有在解封装后才会更改 MSS。
这也许可以解释为什么 ping 偶尔允许我通过隧道成功发送高达 65527(显然是 65535 减 8)的大量消息。但是,这会尝试匹配隧道 MTU,而我需要确定每个连接的 MTU,该 MTU 可能小于隧道 MTU。我该怎么做,以便不需要降低隧道 MTU?
答案1
MikroTik 的 IPv6 默认配置似乎缺少路径 MTU 发现。将此规则添加到 IPv6 防火墙有帮助 (来源):
/ipv6 firewall mangle
add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn
这选项的含义:
change-mss - 将数据包的最大段大小字段值更改为 new-mss 参数指定的值
IP 标头中的 Clamp-to-pmtu 功能设置 (DF) 位可动态发现路径的 PMTU。主机发送该路径上的所有数据报时都会设置 DF 位,直到收到 ICMP 目标无法到达消息,其代码表示“需要分片,并且设置了 DF”。收到此类消息后,源主机会减少该路径的假定 PMTU。
syn-新连接
因此,规则会尝试找出每个新连接的 MTU。(上面引用的描述显然适用于 IPv4。IPv6 规范要求不存在碎片,因此不能使用 DF 位。)