在这个问题的末尾添加了新的细节;我可能正在关注原因。
我有一个基于 UDP OpenVPN 的 VPN 设置tap模式(我需要,tap因为我需要 VPN 来传递多播数据包,这在tun网络中似乎是不可能的)与互联网上的少数客户端。我在 VPN 上经常遇到 TCP 连接冻结的情况。也就是说,我将建立一个 TCP 连接(例如一个 SSH 连接,但其他协议也有类似的问题),并且在会话期间的某个时刻,流量似乎将停止通过该 TCP 会话传输。
这似乎与发生大数据传输的点有关,例如我是否ls在 SSH 会话中执行命令,或者我是否cat是一个长日志文件。一些 Google 搜索在 Server Fault上找到了许多类似上一个这样的答案,表明可能的罪魁祸首是 MTU 问题:在高流量期间,VPN 试图发送数据包,这些数据包在两个管道之间的某处被丢弃VPN 端点。上面链接的答案建议使用以下 OpenVPN 配置设置来缓解问题:
fragment 1400
mssfix
Run Code Online (Sandbox Code Playgroud)
这应该将 VPN 上使用的 MTU 限制为 1400 字节,并修复 TCP 最大段大小以防止生成任何大于该值的数据包。这似乎稍微缓解了这个问题,但我仍然经常看到冻结。我尝试了许多大小作为fragment指令的参数:1200、1000、576,所有结果都相似。我想不出两端之间有什么奇怪的网络拓扑结构会引发这样的问题:VPN 服务器运行在直接连接到 Internet的pfSense机器上,而我的客户端也在另一个位置直接连接到 Internet。
另一个奇怪的难题:如果我运行该tracepath实用程序,那么这似乎可以解决问题。示例运行如下所示:
[~]$ tracepath -n 192.168.100.91
1: 192.168.100.90 0.039ms pmtu 1500
1: 192.168.100.91 40.823ms …Run Code Online (Sandbox Code Playgroud) 根据这里的表格,它说 MTU = 1500 字节,有效载荷部分是 1500 - 42 字节或 1458 字节(<- 这实际上是错误的!)。现在最重要的是您必须添加 IPv4 和 UDP 标头,它们是 28 个字节(20 个 IP + 8 个 UDP)。这使我的最大可能应用程序消息为 1430 字节!但是通过在互联网上查找这个数字,我看到的是 1472。我在这里计算错误吗?
我想知道的是我可以通过网络发送的最大应用程序消息,而不会产生碎片风险。它绝对不是 1500,因为它包括帧头。有人可以帮忙吗?
令人困惑的是 PAYLOAD 实际上可以大到 1500 字节,这就是 MTU。那么现在有效载荷为 1500 的线内尺寸是多少?从该表中,它可以大到 1542 字节。
所以我可以发送的最大应用程序消息是 1472 (1500 - 20 (ip) - 8 (udp)) 最大线径为 1542。当事情实际上很简单时,事情会变得如此复杂,这让我感到惊讶。而且我不知道如果表上写的是 1542,那么有人是如何想出数字 1518 的。
我们在客户处安装了数十个嵌入式设备,所有这些设备都可以使用我们的 OpenVPN 服务。一般情况下这很好,但我们的一些客户有严重的路径 MTU 问题。我们对客户修复网络的影响是有限的,因此我们需要 OpenVPN 来处理它。简而言之,我的问题是:
我如何在每个客户端的基础上减轻某些客户端的低路径 MTU,即不使用全局设置来适应所有客户端的最坏情况
请注意,我们的最坏情况非常糟糕:路径 MTU 576,丢弃所有碎片,不对自身进行碎片化,不尊重 DF 位。你明白为什么我不想在全球范围内解决这个问题。
该OpenVPN的联机帮助提供了许多MTU的相关选项,最显着的--link-mtu, --tun-mtu, --fragment and --mssfix。但它也说
--link-mtu [...] 除非您知道自己在做什么,否则最好不要设置此参数。
--tun-mtu [...] 最好使用 --fragment 和/或 --mssfix 选项来处理 MTU 大小问题。
于是我开始尝试用--fragment和--mssfix,但很快就意识到,至少前者必须设置不仅客户端,但也服务器端。然后我查看了服务器端每个客户端的配置,--client-config-dir但它说
以下选项在特定于客户端的上下文中是合法的:--push、--push-reset、--iroute、--ifconfig-push 和 --config。
没有提到 MTU 选项!
所以这里是我更具体的问题:
link-mtu和tun-mtu气馁?这些选项有哪些潜在问题?请注意,我对低级 IP 标头处理非常满意。link-mtu tun-mtu fragment mssfix必须在服务器端镜像才能工作?link-mtu tun-mtu fragment mssfix可以用于client-config-dir?client-config-dir:是否有任何替代方案来对抗每个客户端的低路径 MTU?笔记:
当我在设置了 DF 位并且数据包大小对于我的路由器来说太大的情况下 ping 远程站点时,第一个 ICMP“需要分段”消息从路由器发送。之后,消息来自我的本地主机。
Netstat -rC(在 Linux 上)允许我查看路由表缓存,但是
1) 似乎在名为 MSS 的列下显示 MTU(我希望它是链接的较低 TCP MSS)
2) 始终将值显示为 1500
我的本地主机必须在某处缓存 PMTU,以便它可以生成所需的碎片消息。但是我怎么看呢?
这是我机器上的一个示例(netstat 上的 -n 禁止反向 DNS 查找):
[root@vbcentos ~]# ping -c 4 -M do -s 1431 212.58.244.69
PING 212.58.244.69 (212.58.244.69) 1431(1459) bytes of data.
From 217.155.134.6 icmp_seq=1 Frag needed and DF set (mtu = 1458)
From 217.155.134.4 icmp_seq=2 Frag needed and DF set (mtu = 1458)
From 217.155.134.4 icmp_seq=2 Frag needed and DF set (mtu = 1458)
From 217.155.134.4 …Run Code Online (Sandbox Code Playgroud) 我遇到了这个问题,当 mtu 设置为 1500 时,我只能连接到像 google.com 和 ibm.com 这样的网站,但是如果我尝试连接到其他任何东西,它只会显示一个空白页面。当 mtu 降低到 1499 时,它开始工作。我很好奇为什么会这样,如果将 mtu 设置为 1499 是否会在将来引起问题?我实际上对此知之甚少,我只是听说过,正在寻找一个很好的解释。
当我得到关于为什么 MTU 仅下降 1 个字节的解释时,我将用解释更新我的问题。
我使用的是 100 Mbps 的快速以太网,其帧大小小于 1500 字节(根据我的教科书,有效载荷为 1472 字节)。在那,我能够发送和接收消息大小为 65507 字节的 UDP 数据包,这意味着数据包大小为 65507 + 20(IP 标头)+ 8(UDP 标头)= 65535。
如果帧的有效载荷大小本身最大为 1472 字节(根据我的教科书),IP 的数据包大小怎么会大于这里的 65535?
我使用发件人代码作为
char buffer[100000];
for (int i = 1; i < 100000; i++)
{
int len = send (socket_id, buffer, i);
printf("%d\n", len);
}
Run Code Online (Sandbox Code Playgroud)
接收器代码为
while (len = recv (socket_id, buffer, 100000))
{
printf("%d\n". len);
}
Run Code Online (Sandbox Code Playgroud)
我观察到send returns -1上i > 65507和recv打印或接收的分组maximum of length 65507。
我有一个应用程序可以从更大的以太网帧中受益。(理论上,我们可以将出站数据包的数量减少 > 50%,甚至可能减少 66%。)
我还在为我的应用程序服务器的新安装指定候选托管公司的网络要求。至少,最好不要限制客户端连接受益于巨型帧。
但这有多现实?一些一般性问题,假设我们可以控制的网络段是 Jumbo Frame-friendly (交换机支持大型 MTU,允许 ICMP MTU 路径发现等):
好的,我刚刚解决了几个 Xserve、Netgear GSM7224 和 Drobo B800i 之间的巨型帧问题。事实证明,Xserves(Mac OS X 10.6.8 服务器)和 Drobo B800i 接受 MTU(以字节为单位)正常预期(1500-9000),但 Netgear 似乎希望它包括各种以太网页眉/页脚(拖车) 我最终得到了 Xserves & Drobo 的 MTU 配置为 9000 和 Netgear 端口设置为 9216 的 MTU。
我使用以下命令通过 Netgear 测试和验证两个 Xserve 之间的 MTU(注意:这些是 Mac OS X 命令,Windows 和 Linux 的命令不同):
ping -D -s <mtu> <ip_address>
traceroute -F <ip_address> <mtu>
Run Code Online (Sandbox Code Playgroud)
前者的用法在man页面中注明为“指定要发送的数据字节数。默认为56,当与8字节的ICMP头数据组合时,转换为64个ICMP数据字节”。在测试中,我发现ping -D 1472 <ip_address>由于 8 字节的 ICMP 标头数据加上 20 字节的 IP 标头(请参阅此和此),to相当于 MTU 1500 。这一切都说得通。
现在,为什么是 9000 …
我的 OpenVPN 隧道无法达到线速。网关是托管在 OVH 的 Debian Jessy 虚拟服务器。客户端是我的 freebsd 10.2 家庭服务器(Intel I3 Ivy Bridge)或我的 RaspberryPI2。我停用了加密和身份验证。我有一个 100mbit/s 的对称 FTTH 连接,但隧道的速度仅达到 20-40mbit/s。直接连接(无隧道)总是产生我期望的 100mbit/s。我用iperf3测试了性能。我首先尝试使用我的 freebsd 家庭服务器。我尝试了所有关于 mssfix、fragment 等的推荐设置。没有任何帮助。
然后我想也许是我的freebsd机器。所以我在我的 RPI2 上安装了一个新的 raspbian Jessy 并进行了一些更深入的测试:
首先,我从 OpenVPN 配置中删除了所有 MTU 设置,并让路径 MTU 处理事情(希望如此)。因为我在两台机器上都没有激活防火墙,所以它应该可以工作。这些是我的 vpn 配置:
server 10.8.0.0 255.255.255.0
port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0
user nobody
group nogroup
persist-key
persist-tun
ifconfig-pool-persist ipp.txt
keepalive 10 120
push "redirect-gateway def1"
status openvpn-status.log
verb 3
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/vpn.theissen.io.crt
key /etc/openvpn/easy-rsa/keys/vpn.theissen.io.key
dh /etc/openvpn/easy-rsa/keys/dh4096.pem
tls-auth …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个 9000 字节的 MTU,用于 KVM 来宾和主机系统之间的存储通信。主机有一个br1具有 9000 字节 MTU的网桥 ( ):
host# ip link show br1
8: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP
link/ether fe:54:00:50:f3:55 brd ff:ff:ff:ff:ff:ff
inet 172.16.64.1/24 brd 172.16.64.255 scope global br1
inet6 fe80::21b:21ff:fe0e:ee39/64 scope link
valid_lft forever preferred_lft forever
Run Code Online (Sandbox Code Playgroud)
来宾有一个连接到此网桥的接口,该接口也有一个 9000 字节的 MTU:
guest# ip addr show eth2
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:50:f3:55 brd ff:ff:ff:ff:ff:ff
inet 172.16.64.10/24 brd 172.16.64.255 scope global eth2
inet6 fe80::5054:ff:fe50:f355/64 scope …Run Code Online (Sandbox Code Playgroud) mtu ×10
networking ×4
openvpn ×3
tcp ×3
ethernet ×2
tcpip ×2
udp ×2
vpn ×2
bridge ×1
ip ×1
jumboframes ×1
linux ×1
performance ×1