阿里云 2 核 4G 的 CentOS 7.9,安全组入站只放了 22 和 443,站点首页能打开但图片加载到一半卡住,curl 下载大文件停在 0 字节,服务器上 ping 外部正常,traceroute 到中间跳全是星号。

一开始怀疑是「客户端和服务端之间经过 IPSec 隧道,开销没有算进去」,查了一圈,方向不对。

把日志和配置对完,能解释这个现象的基本就这几处。安全组没有放行 ICMP,路径上的 PMTU 探测报文被丢弃。少数情况下是中间链路 MTU 小于 1500,大包需要分片但 DF 位阻止分片。

还有一种情况,云厂商安全组对 ICMP type 3 code 4 单独做了限制。

动手时先确认是不是 MTU 造成的问题

ping -M do -s 1472 -c 3 example.com

再往下逐步缩小包长找出路径 MTU

for s in 1400 1420 1440 1460; do ping -M do -s $s -c 1 example.com; done

随后放行需要的 ICMP 分片报文

iptables -I INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT

等前面都确认过,再让服务端按路径 MTU 调整 MSS

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

恢复的判定其实很直接。curl 下载大文件速度恢复正常,ping -M do -s 1472 能通,tcpdump 里不再出现大量 ICMP fragmentation needed。

这里还有个坑。全放行 ICMP 会暴露主机信息,按 type 放行需要的那几类即可,回显请求可以继续限速。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189