216 条网络命令(二):防火墙、conntrack、抓包、MTU

216 条网络命令(二):防火墙、conntrack、抓包、MTU

第二篇。上一篇讲地址、路由、连接与隧道;这一篇是防火墙、conntrack、抓包与 MTU。

五、netfilter(47 条)

iptables -vnL [链]

iptables -vnL  
iptables -vnL FORWARD --line-numbers | head -8  
关键:计数涨只说明匹配,不说明 hook 选对了。  
坑:DNAT 之后目的地址变了,包走 FORWARD 而不是 INPUT。  
    写在 INPUT 链的规则永远碰不到它——这是最高频的一条死路。  

iptables -t nat -vnL [PREROUTING|POSTROUTING]

关键:nat 表一条连接只查一次,所以计数只涨 1 是正常的。  
判据:计数涨了 = 改写成功?不一定。要看 conntrack 里有没有成对的会话。  

iptables -S

规则的可复现文本形式。

坑:只看 -L 不看 -S,容易漏掉链的默认策略(-P INPUT DROP 这类)。  

建立一条能用的基线

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT  
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP  
iptables -P INPUT DROP  

第一条几乎总是 ctstate。 没有它,回程包会被拦,你会看到「请求出去了、响应回不来」。

IPv6 的默认全通陷阱

ip6tables -S | head -20  
坑:ip6tables 的默认策略可能是 -P INPUT ACCEPT(全放行)。  
    v4 严、v6 裸奔,是极常见的配置失衡。  

v6 最小防护基线:

ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 1 -j ACCEPT    # 目的不可达  
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 2 -j ACCEPT    # 包太大  
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 3 -j ACCEPT    # 超时  
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 133:136 -j ACCEPT  # RS/RA/NS/NA  
ip6tables -A INPUT -p ipv6-icmp -j DROP  

ICMP:只禁 Echo,别封 Type 3 与 11

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT  
iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT  
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT  
反例:iptables -A INPUT -p icmp -j DROP  
    全禁 ICMP = 制造 PMTUD 黑洞。大包被丢,小包正常,症状极其难查。  

nft list ruleset

关键:inet 族一张表同时管 v4/v6。  
坑:看到 table inet 就以为都齐了,没确认规则落在哪个 priority。  
坑:iptables-nft 兼容表可能同时存在,两套规则并存。  

nmap -Pn -p <端口> <公网IP>

从外部验证暴露面。

判据:本机 ss 有监听 + 云侧放行 + 主机规则放行,三者缺一不可。  

六、conntrack(3 条)

conntrack -L

conntrack -L | grep 8080  
关键:同一会话应该有成对的两行(正向 + 反向)。  
坑:查不到就断定「没建连」——可能走了 XDP 旁路,或者被 NOTRACK 跳过。  

conntrack -S

conntrack -S  

看 insert_failed / drop / early_drop。这是表满的直接证据,即便系统日志里什么都没有。

cat /proc/sys/net/netfilter/nf_conntrack_count / max

cat /proc/sys/net/netfilter/nf_conntrack_count  
cat /proc/sys/net/netfilter/nf_conntrack_max  
判据:比值 > 0.9 且失败与并发峰值同步 → 表满。  
关键:每条约 300 字节常驻内核内存,且不可交换。  
      100 万条 ≈ 300 MB。1 GB 内存的网关上,调大上限可能先触发 OOM。  
顺序:永远先降产生速率,再评估调大。  

七、抓包(9 条)

三档深度,成本递增

档 命令 拿到什么
一 ip -s link / nstat -az / conntrack -S 计数器,包在不在
二 tcpdump -ni eth0 -c 20 '<filter>' 头部,谁发给谁
三 tcpdump -s0 -w /tmp/cap.pcap 全长载荷

先数计数,再抓包。 抓包成本最高,而且会引入新的怀疑对象。

tcpdump -ni eth0 -c 20 'tcp port 8099'

关键参数:  
  -n  不做反向 DNS(否则你会等解析超时)  
  -i  指定接口;隧道场景 wg0 是明文、eth0 是 UDP 密文  
  -c  限数,防止刷屏  
坑:默认只抓包头前若干字节。判「大包是否被丢」时,会以为包不存在。  

判读重点:[S] 之后有没有 [S.]、重传间隔、包长是否贴着 MTU。

tcpdump -ni eth0 udp port 51820

确认 WireGuard 外层密文包。

关键:外层看不到内层 IP——它被加密了。  
     在 eth0 找不到内层地址,不等于没走隧道。  
长度:148 / 92 字节是握手包。  

tcpdump -s0 -w /tmp/cap.pcap

第三档,抓全长。

坑:加密流量看不到载荷。  
坑:Wireshark 标 [TCP Previous segment not captured] 时,  
    先确认是不是抓包侧自己丢了。  
坑:含敏感数据要脱敏。  

八、路径与 MTU(21 条)

ping -M do -s <size> <dst> —— 找路径 MTU

-M do 禁止分片(DF 位),-s 是载荷大小。

# 前提:wg0 MTU = 1420  
ping -M do -s 1392 10.0.0.5    # 1392 + 8(ICMP) + 20(IP) = 1420  通  
ping -M do -s 1393 10.0.0.5    # 1421 > 1420                     不通  
铁律:不写链路 MTU 直接抄 1392,换环境就错。  
      1422/1423 那组数字只在路径 MTU = 1450 时成立。  

二分法找边界:

for s in 1200 1300 1350 1380 1392 1400; do  
  ping -c1 -W1 -M do -s $s 8.8.8.8 >/dev/null 2>&1 \  
    && echo "$s OK" || { echo "$s FAIL"; break; }  
done  

ping -c 4 <dst>

坑:默认载荷 56 字节,测不出任何 MTU 问题。  
坑:ping 通 ≠ 业务通;ping 不通 ≠ 服务不可用。  

traceroute -T -p 443 -n vs traceroute -I -n

TCP 探针穿透力最强,ICMP 探针对比着看。

判据:两种探针在某一跳开始分叉 → 那一跳就是策略设备(防火墙/负载均衡)。  
坑:中间的星号不是「不通」,是「这一跳没把 ICMP 送回给我」。  

mtr -rwz -c 10 <dst>

持续探测 + 丢包率统计。

关键:要写采样次数。短跑一次噪声极大。  
判据:某一跳 100% 丢包但后续跳恢复正常 → 忽略那一跳。  


下一篇:《216 条网络命令(三):DNS、TLS、队列、内核参数》