VPS MTU 怎么查怎么设:先测再改,别抄 1400/1420

VPS MTU 怎么查,中文教程的答案高度统一:1400、1420、1450,三个数字轮着推荐。我们反过来做了一遍,38 个商家公开测试 IP,两个探测源,76 个测量点,从 1472 字节 payload 直接打过去,全部通,一个都没被拦。
所以这篇不给新数字。它给一条命令,让你在两分钟里测出自己那条路的真实上限,再决定要不要动配置。
结论:76 个点,payload 1472 全部直通
口径写在这里,后面所有数字都受它约束:测的是从探测源到商家公开测试 IP 这条路上,带 DF 位、不分片的报文能过的最大值,也就是到目标地址的路径 MTU。探测源只有两个,cn-probe-1(中国广东,电信 AS4816 单线)和 cn-probe-2(中国北京,阿里云 BGP AS37963 多线)。
结果:38 个 IP × 2 个源 = 76 个测量点,payload 1472 全部直通,两个源一个不差。这个结果的含义是「这 76 条路径的 MTU 都不小于 1500」,不是「等于 1500」。之所以写成 1500,是因为本机接口 MTU 就是 1500,1472 的 payload 已经是这台机器能发出去的最大不分片报文;路径比 1500 更宽我们也测不出来。这一点在后面的「测不到什么」里会再讲一次。
| 项目 | cn-probe-1 | cn-probe-2 |
|---|---|---|
| 测量点数 | 38 | 38 |
| 路径 MTU ≥ 1500(本机封顶) | 38 | 38 |
| payload 1472 直通 | 38 | 38 |
| 低于 1500 的点 | 0 | 0 |
这 38 个 IP 覆盖 Vultr 七个机房、RackNerd、DMIT、Hetzner、ALEXHOST,以及一批只标了 ASN 的入口。路径从广东出海、从北京出海,落到洛杉矶、达拉斯、西雅图、东京、香港、法兰克福、赫尔辛基、悉尼。没有一条路在中间被削掉。
这不是行业定律。它只说明:在这 38 个入口、这两个源、这一天的这个时段,路径 MTU 没有一处小于 1500。换成隧道、PPPoE 拨号、或者中间有运营商做 MSS 干预,结论就会变。
三个数别混:接口 MTU、路径 MTU、TCP MSS
这三个数经常被当成一个数讲,是绝大多数 MTU 教程读完之后仍然不会查的根本原因。它们量的东西不一样,改的地方也不一样。
接口 MTU 是本机网卡
ip link show
输出里每个网卡一行,mtu 后面跟的就是接口 MTU。两条探测源上主网卡的这一项都是 1500(ip -o link show 实测,cn-probe-1 的 eth0/eth1、cn-probe-2 的 eth0 都是 mtu 1500)。
它只决定一件事:本机发出去的包,单个最大能有多大。超过它,内核在本地就把包拦下来,包根本没进网线。所以接口 MTU 是 1500 的时候,你 ping 的 payload 上限就是 1472,再大一点会直接报错,跟路径通不通没关系。
路径 MTU 是整条路能过的最大值
从你到目标,中间要过交换机、路由器、隧道、运营商互联。每一段都有自己的 MTU,整条路能过的最大值,等于这些段里最小的那一个。
这个数在本机配置里看不到,只能测。测法就是 ping -M do 二分,两分钟能跑完。VPS MTU 出问题的场景,多半就是这个数比接口 MTU 小。
TCP MSS 是握手时谈出来的载荷上限
ss -ti
连上目标之后,输出里有一行长这样。这是目标 108.61.201.151、源 cn-probe-1、握手刚完成时读的原文:
cubic wscale:10,7 rto:330 rtt:109.57/41.851 ato:40 mss:1448 pmtu:1500 rcvmss:1448 advmss:1448 cwnd:10
mss:1448、pmtu:1500、advmss:1448 三个字段挨在一起,很容易看花。pmtu 是这条连接当前认为的路径 MTU,mss 是实际协商出来的 TCP 载荷上限,advmss 是本机通告给对端的值。
1448 这个数怎么来的:1500 − 20(IP 头)− 20(TCP 头)− 12(时间戳选项)= 1448。时间戳选项本身 10 字节,为了 4 字节对齐再补 2 字节,一共吃掉 12。
有人记得 MSS 是 1460,那是 1500 − 20 − 20,没算时间戳。两种都正常,取决于两端有没有开 tcp_timestamps。这两条探测源上 /proc/sys/net/ipv4/tcp_timestamps 都是 1,所以协商出来是 1448。
还有一个坑。连接空转久了再看 ss -ti,mss 会显示 524。那不是协商值,是接收窗口变小之后内核夹出来的显示值。要读真值,连上之后立刻读。握手没完成的连接(SYN-SENT)里也一样,mss 是占位值,advmss 还停在 1460,因为那时还不知道对端开不开时间戳。这两种行都不能当协商结果用。
VPS MTU 两分钟自己查:从 1472 起步,二分到不通
命令就一条,payload 从 1472 开始。
ping -M do -s 1472 -c 3 108.61.219.200
-M do 是禁止分片,-s 是 payload 字节数。1472 + 8(ICMP 头)+ 20(IP 头)= 1500,正好是标准以太网的满包。
通的输出是这样,第一行回显的 1480 是 1472 加 8 字节 ICMP 头,不是 1500:
1480 bytes from 108.61.219.200: icmp_seq=1 ttl=47 time=264 ms
再往上加 1 字节:
ping -M do -s 1473 -c 3 108.61.219.200
ping: local error: message too long, mtu=1500
1472 通、1473 不通,路径 MTU 就是 1500。报错里那个 mtu=1500 是内核从路由表读出来的值,不是中间设备回给你的。
不通的时候,让脚本自己找边界
1472 不通,往下二分。最后那个参数换成目标地址,sudo 是因为 -M do 要 raw socket:
sudo bash -c '
lo=1200; hi=1472
while [ $lo -lt $hi ]; do
mid=$(( (lo + hi + 1) / 2 ))
if ping -M do -s $mid -c 1 -W 1 "$1" >/dev/null 2>&1; then lo=$mid; else hi=$(( mid - 1 )); fi
done
echo "payload=$lo path_mtu=$(( lo + 28 ))"
' _ 你的目标IP
跑完打出一行 payload=xxxx path_mtu=xxxx。想确认这个数稳不稳,隔十分钟再跑一次,路径变了数会变。
38 个 IP 全表:76 个格子没有一个低于 1500
每一行是一个商家公开测试 IP,后两列是两条源各自测到的路径 MTU,口径同上一节。1500 / 1500 表示两条源都是 1500,不是平均值。
| # | IP | 实测归属 | cn-probe-1 | cn-probe-2 |
|---|---|---|---|---|
| 1 | 108.61.219.200 | 洛杉矶 AS20473 Vultr | 1500 | 1500 |
| 2 | 108.61.201.151 | 东京 AS20473 Vultr | 1500 | 1500 |
| 3 | 108.61.210.117 | 法兰克福 AS20473 Vultr | 1500 | 1500 |
| 4 | 108.61.196.101 | 伦敦 AS20473 Vultr | 1500 | 1500 |
| 5 | 108.61.212.117 | 悉尼 AS20473 Vultr | 1500 | 1500 |
| 6 | 45.32.100.168 | 新加坡 AS20473 Vultr | 1500 | 1500 |
| 7 | 139.84.130.100 | 班加罗尔 AS20473 Vultr | 1500 | 1500 |
| 8 | 198.23.249.100 | 达拉斯 AS36352 | 1500 | 1500 |
| 9 | 103.145.107.134 | 香港 AS9232 | 1500 | 1500 |
| 10 | 41.216.177.64 | Purwokerto AS139989 | 1500 | 1500 |
| 11 | 156.251.191.11 | 洛杉矶 AS17561 | 1500 | 1500 |
| 12 | 192.3.253.2 | 西雅图 AS36352 RackNerd | 1500 | 1500 |
| 13 | 107.175.180.6 | 洛杉矶 AS36352 | 1500 | 1500 |
| 14 | 154.17.30.96 | 洛杉矶 AS906 DMIT | 1500 | 1500 |
| 15 | 45.194.21.254 | 香港 AS140227 | 1500 | 1500 |
| 16 | 85.137.248.30 | 阿姆斯特丹 AS200019 ALEXHOST | 1500 | 1500 |
| 17 | 103.158.191.1 | 香港 AS932 | 1500 | 1500 |
| 18 | 107.151.244.169 | 香港 AS154321 | 1500 | 1500 |
| 19 | 103.214.172.1 | 香港 AS42960 | 1500 | 1500 |
| 20 | 86.53.184.254 | 伦敦 AS3257 | 1500 | 1500 |
| 21 | 38.79.115.254 | 洛杉矶 AS174 | 1500 | 1500 |
| 22 | 216.36.82.2 | 洛杉矶 AS3257 | 1500 | 1500 |
| 23 | 45.129.13.2 | Eygelshoven ASN 未取得 | 1500 | 1500 |
| 24 | 154.21.202.46 | 香港 AS979 | 1500 | 1500 |
| 25 | 206.119.91.254 | 香港 AS140227 | 1500 | 1500 |
| 26 | 172.81.96.254 | 东京 AS137535 | 1500 | 1500 |
| 27 | 107.174.123.254 | 洛杉矶 AS36352 | 1500 | 1500 |
| 28 | 192.210.207.88 | 圣克拉拉 AS36352 RackNerd | 1500 | 1500 |
| 29 | 154.29.146.1 | 洛杉矶 AS979 | 1500 | 1500 |
| 30 | 45.158.23.1 | 洛杉矶 AS35251 | 1500 | 1500 |
| 31 | 93.179.124.115 | 香港 AS25820 | 1500 | 1500 |
| 32 | 216.36.103.254 | 洛杉矶 AS3257 | 1500 | 1500 |
| 33 | 38.209.67.2 | 洛杉矶 AS174 | 1500 | 1500 |
| 34 | 104.234.155.1 | 东京 AS151487 | 1500 | 1500 |
| 35 | 156.225.92.126 | 洛杉矶 AS140869 | 1500 | 1500 |
| 36 | 202.97.27.238 | 圣何塞 AS4134 | 1500 | 1500 |
| 37 | 78.46.170.2 | 法尔肯施泰因 AS24940 Hetzner | 1500 | 1500 |
| 38 | 95.217.255.81 | 赫尔辛基 AS24940 Hetzner | 1500 | 1500 |
76 个格子,最低 1500,最高 1500。没有一格是 1492 或 1450。按前面说的口径,这 76 个格子读作「不小于 1500」,而在本机接口 MTU 1500 的前提下,实测能到 1500 就是上限了。
标签不可信,看 ASN 和 hostname
这批 IP 的原始标签里,有十六个和实测归属对不上。挑反差大的几个:
| 原标签 | IP | 实测地区 | ASN |
|---|---|---|---|
| 六六云 台湾 | 156.251.191.11 | 洛杉矶 | AS17561 LARUS |
| 六六云 日本 | 41.216.177.64 | Purwokerto, ID | AS139989 |
| Vultr 纽约 | 198.23.249.100 | 达拉斯 | AS36352 |
| 日本 测试 | 103.158.191.1 | 香港 | AS932 |
| 美东 测试 | 216.36.82.2 | 洛杉矶 | AS3257 |
| 美东 测试2 | 45.129.13.2 | Eygelshoven, NL | 未取得 |
| 美东 测试4 | 45.158.23.1 | 洛杉矶 | AS35251 |
| 美东 测试6 | 104.234.155.1 | 东京 | AS151487 |
| 欧洲 测试3 | 93.179.124.115 | 香港 | AS25820 |
| 香港 测试2 | 202.97.27.238 | 圣何塞 | AS4134 |
标着纽约的那台落在达拉斯,标着美东的几台分别在洛杉矶、东京和荷兰,标着香港的那台是 AS4134 的骨干地址,落在圣何塞。hostname 也不能全信:216.36.82.2 的 PTR 是 ip-216-36-82-2.chi.megapath.net,chi 指芝加哥,实测在洛杉矶。地址归属只能当线索,判断机器在哪,看 ASN 更靠得住。
能确认商家名的只有几家,都有主机名做证据:Vultr 七个(*.vultrusercontent.com,AS20473)、RackNerd(lg-sea.racknerd.com 和 lg-sj.racknerd.com,AS36352)、DMIT(host-by.dmit.com,AS906)、Hetzner(fsn1-speed.hetzner.com 和 hel1-speed.hetzner.com,AS24940)、ALEXHOST(AS200019,阿姆斯特丹)。其余只写 ASN 和地区。
这件事跟 MTU 有关系。同一家商家的「纽约」入口实际在达拉斯,意味着你 ping 出来的延迟和路径,都是达拉斯那条路的,跟纽约没关系。路径 MTU 也一样,它只属于你测的那条路。
路径 MTU 干净、延迟却难看,那是另一条线。同一套探测源我们做过延迟测量的方法论拆解,毫秒数怎么来的、加包数为什么没用,都在 VPS 延迟怎么测才准 里。想按价格和机房筛机器,最新优惠与套餐比价 按价位排好了,可以先圈出候选再逐台验。
VPS MTU 设到 1473 会怎样:三个源都直接拒发
payload 加到 1473,需要 1501 的 MTU。三条源(两条国内,加一条美国洛杉矶的 us-probe-1,Zenixcloud AS402506)对三个目标(108.61.219.200、108.61.201.151、78.46.170.2)返回的是同一条报错(cn-probe-2 的 Message 首字母大写,另两条源小写):
ping: local error: message too long, mtu=1500
注意是 local error。包没发出去,是内核在本地拦下的,不是中间某台路由器回了 ICMP frag needed。这跟很多人想象的 MTU 黑洞不是一回事。黑洞是包发出去了、中间设备丢掉、该回的 ICMP 又被 ACL 拦掉,发送端一直重传,连接卡死。
这 76 个点之所以碰不到黑洞,是因为本机接口 MTU 就是 1500,超过的包压根出不了网卡。真要遇到黑洞,得凑齐两个条件:本机接口 MTU 比路径 MTU 大(本机 1500、路上某段 1450),并且那段路回的 ICMP 被拦。隧道叠加最容易凑齐,PPPoE 拨号也容易。
判断是不是黑洞,别只看 ping。ping -M do -s 1472 不通、换成 -s 1400 就通,这个组合才像。如果 1472 直接通了,说明这条路本身没问题,SSH 卡住要从别处找原因(丢包、会话限制、对方限速)。反过来,报错是 local error 的那种情况也跟黑洞无关——包根本没出网卡,是本机接口 MTU 卡住的。
PPPoE 的 1492,少的 8 字节在哪
宽带拨号上网,接口 MTU 常见 1492。差的 8 字节是这么没的。
以太网一帧能装 1500 字节 payload。PPPoE 要在里面塞自己的头:版本/类型 1 字节、code 1 字节、session ID 2 字节、length 2 字节,共 6 字节;后面还要一个 2 字节的 PPP 协议字段,指明里面装的是 IP。6 + 2 = 8,1500 − 8 = 1492。
所以 PPPoE 接口上,payload 上限是 1492 − 28 = 1464,不是 1472。同一台机器换成拨号接入,能过的最大不分片报文就少 8 字节。
这里有个常被混淆的点:改 PPPoE 接口的 MTU,改的是本机网卡,不是路径。拨号链路上真正卡你的,是运营商 BRAS 那一侧的 MTU,那个数你改不了,只能适配。适配的办法是让 TCP 一开始就谈小一点。
MSS 钳制:clamp 和 set 不是一回事
MSS 钳制改的是握手包里的 MSS 字段,让两端从一开始就按小包发,不依赖 ICMP 通告。适合 ICMP 被拦、或者中间设备根本改不了的情况。
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
两条命令的区别在值从哪来。--clamp-mss-to-pmtu 读的是本机路由表里那条路的 pmtu,路由说 1500 就按 1500 算,MSS 给 1448。--set-mss 是你写死一个数,路由怎么变都不动。
问题就出在这儿:clamp 依赖路由的 pmtu 是准的。如果路由显示 1500、实际路径只有 1450,clamp 算出来的 1448 照样过不去,你会以为钳制没用。这种情况只能 --set-mss 写死。
数值必须带前提,没有通用推荐值:
| MSS | 前提 |
|---|---|
| 1460 | 1500 路径,无时间戳(1500−20−20) |
| 1448 | 1500 路径,有时间戳(1500−20−20−12) |
| 1452 | 1492 路径(PPPoE),无时间戳 |
| 1440 | 1492 路径,有时间戳 |
| 1360 | 1400 路径(IPSec/GRE 隧道常见),无时间戳 |
链选 FORWARD 还是 OUTPUT
转发别人的流量走 FORWARD,本机自己发起的连接走 OUTPUT。在 VPS 上给容器或 NAT 后面的机器做钳制,FORWARD 才对;只改本机,OUTPUT 才生效。写完不用重启,新连接立刻按新值谈,老连接不受影响。
症状对照:卡在哪一步,指向哪个数
接口 MTU 是 1500、路径上有一段更小的机器,症状就是这个样子:Speedtest 跑满,scp 传一个大备份却卡在某个百分比不动,重试还卡在同一个位置。换断点续传能传完,速度掉下来一截。这种形态指向路径 MTU 小于本机接口 MTU:小包能过,满包过不去,TCP 一直重传。要确认还是那两条命令,ping -M do -s 1472 与逐级往下二分。这类形态我们没有实测数据,所以不给具体路径 MTU 数值。
另一种是网页。首屏文字出来了,图片一张张往下加载,某一张停住,刷新又好了。这种也常被当成浏览器或者 CDN 的问题,其实是同一条路上的大响应体被卡。
| 现象 | 更像什么 | 怎么验 |
|---|---|---|
SSH 能登进去,scp 传大文件卡在某个百分比 |
路径 MTU 小于本机接口 MTU | -s 1472 失败、-s 1400 成功 |
| 网页首屏出来了,图片或字体转一半停住 | 同上,大响应体被卡 | 开发者工具看失败请求的大小 |
| 测速跑满,游戏里持续微卡 | 跟 MTU 无关,看丢包和抖动 | 连测 100 包看 mdev 与丢包率 |
| 下载小文件正常,超过 1MB 就断 | 路径 MTU 或中间设备会话限制 | 换 curl 拉同一个小文件对比 |
| 只有某个机房卡,换机房就好 | 那条路的 MTU 或丢包 | 两个机房各跑一次二分 |
前两行是同一类问题,验证方式一样。第三行经常被误判成 MTU,其实正好相反:MTU 卡的是满包,小包一路畅通,游戏里那种持续微卡通常来自丢包或抖动。测速满分说明带宽够,微卡说明链路质量有问题,去查丢包率,别改 MTU。
四档 payload 的 RTT 对照也能说明这一点。同一个目标 108.61.219.200,cn-probe-1 上 payload 56 / 1000 / 1400 / 1472 的平均 RTT 是 255.954 / 255.559 / 255.769 / 255.580 ms,四档最大差 0.395 ms。包改小不会让路变快,只会让同样的数据多发几个包。
丢包那一组也一样。同一目标、同一条源,56 字节和 1472 字节的丢包率没有随包变大而升高:cn-probe-1 上是 0% 和 0%,cn-probe-2 上是 10% 和 10%,中间那档 1400 分别是 10% 和 5%,三档没有单调关系。丢包跟路径质量有关,跟包大小无关。
如果二分下来路径 MTU 确实小于 1500,问题多半在接入方式,不在机器本身。换机器之前,先看 各家商家的接入与线路,有的入口天生带隧道。
两种 pmtu 别混
tracepath 的输出里也有 pmtu 字样,很多人拿它当路径 MTU 用,这是最容易出错的地方。
ping -M do 二分得到的是到目标地址的路径 MTU,一个数,代表整条路的上限。
tracepath 每一跳后面跟的 pmtu,是路径中段某一跳通告的 MTU,是那一段自己的值,会随跳数变。它可能比到目标的路径 MTU 小,因为后面还有更宽的路段;也可能相等,因为那一段就是最窄的。
我们在另一篇香港机房实测里记录到过 pmtu 1456,出现在第 20 跳 165.154.225.187 那一行。那一整轮实测的路由表里,pmtu 1500 出现 12 次,pmtu 1456 只出现 1 次。另有一轮去日本的路径实测,广东源第 18 跳、北京源第 15 跳都报 pmtu 1454,两个源一致,随后连续 no reply,最后一行是 Too many hops: pmtu 1454。
这两个数跟 76 个点的 1500 不冲突。不过 1454 和 1456 这两条路我们没做过 ping -M do 二分,所以不知道它们的全程路径 MTU 是多少,只能确认中间某一跳报了这两个值。1456 和 1454 是路径中段某台设备告诉你,我这一段能过这么大;1500 是从源到目标一路走下来、DF 位报文实际能过的最大值。前者是局部通告,后者是全程上限,测的不是同一件事。
所以看到 tracepath 报 1456,不要立刻去改接口 MTU。先跑 ping -M do -s 1472:通了,说明到目标的整条路没问题,那个 1456 只是中间某段的通告值;不通,再往下二分找边界,那才是要处理的数。
这套实测测不到什么
测的是路径 MTU,不是接口 MTU。接口 MTU 在本机,ip link show 一眼就有,不需要测。
测的是两个探测源到商家公开测试 IP。cn-probe-1 在广东、电信单线;cn-probe-2 在北京、阿里云 BGP。这两个源之外的路,没有数据。你从成都、从新加坡、从法兰克福连过去,路径可能完全不同。
测试 IP 不等于你买的那台实例。商家公开的 looking glass 地址反映的是那个入口的接入段,你开通的机器落在哪台宿主机、走哪个上联,是另一回事。测试 IP 全 1500、你的实例卡住,这种情况完全可能发生。
payload 上限被本机接口 MTU 卡在 1472。1472 通只能证明路径 MTU 不小于 1500,不能证明它更大。要验证 9000 的 jumbo frame,得两端和中间全部支持,这套方法测不了。
76 个点是这一天的这一次。路径会变,运营商调整、路由切换都会影响。所以 VPS MTU 这件事,这批数据能用来说明多数情况下不用改,不能当永久结论。
FAQ
商家测试 IP 1472 通,我买的机器还是卡,为什么?
测试 IP 和你的实例不在同一台宿主机,也不一定走同一个上联。先在自己的实例上跑一遍二分,再对比。
商家说 MTU 1500,是谁的口径?
多半是接口 MTU。接口 1500 不代表路径 1500,两个数得分开问。
1472 通、1473 不通,说明什么?
说明本机接口 MTU 是 1500,且到目标的路径不小于 1500。这是标准以太网下的正常状态,不用改。
tracepath 报 1456,是不是该把 MTU 改成 1456?
不必。1456 是中间某跳的通告值,不是到目标的路径 MTU。先用 ping -M do -s 1472 确认全程。
改接口 MTU 会断网吗?
会。改的瞬间这条链路上的连接全部重建,SSH 会掉。要在控制台或者带外能进的前提下改,改完立刻验证。
MSS 钳制要重启吗?
不用。iptables 规则即时生效,只影响之后新建的连接,已建立的连接还按老值跑。
按机房和线路逐台测过的机器在 VPS 测评,下单前值得对一遍。选机时容易踩的另一类坑是 IP 属性,同一个机房不同段差别很大,原生 IP 怎么判断 里用 7 个 IP 拆过三种口径。想按机房维度横向比,香港 VPS 机房怎么选 有 15 个入口的双源实测,也正是前面 pmtu 1456 那条数据的出处。
