iptables与IP报文分片浅析

本文详细描述了如何通过iptables配置来测试UDP分片包的处理,发现iptables不会直接过滤IP分片,而是等待内核重组报文。实验结果显示,即使设置了分片过滤选项,完整数据包仍能被接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

192.168.0.11(iperf 服务端)
192.168.0.10(iperf 接收端)

​ 系统因会发送大于MTU的UDP组播包,且用户基于都是基于UDP带端口的组播,但是由于UDP分片抓包后,经wireshark分析,分片携带的数据是不会带源目端口,只有首包带,用户怀疑分片被iptables隔离导致无法正常接收数据包,故而进行此次分片iptables过滤测试

配置iptables

# 针对分片过滤的选项 -f
	This means that the rule only refers to second and further IPv4 fragments of fragmented packets.  Since there is no  way  to  tell the  source or destination ports of such a packet (or ICMP type), such a packet will not match any rules which specify them.  When the "!" argument precedes the "-f" flag, the rule will only match head fragments, or unfragmented packets.  This  option  is  IPv4 specific, it is not available in ip6tables
	
# 可见
	1. 当设置 -f后,该规则只适用分片报文的除首报文的后续报文,而且如果指定源目端口的话,该规则无法匹配,因为iptables无法确认分片的源目端口
	2. 当设置 ! -f 后,该规则只会匹配未分片的包,或者分片的首包(首包带源目端口)
# 192.168.0.11,由于设置为发送UDP数据,故而仅设置OUTPUT即可,因接收端端口是随机生成的,这里不做任何规则限制
	#	iptables -A OUTPUT -p udp --dport 8888 -j LOG --log-prefix "UDP-OUTPUT: " --log-level debug
	#	iptables -A OUTPUT -p udp --dport 8888 -j ACCEPT
	# 	iptables -A OUTPUT -p udp -j DROP

# 192.168.0.10, 由于设置为接收UDP数据,故而设置INPUT即可
	iptables -A INPUT -p udp --sport 8888 -j LOG --log-prefix "UDP-INPUT: " --log-level debug
	iptables -A INPUT -p udp --sport 8888 -j ACCEPT
	iptables -A INPUT -p udp -j DROP

设置iperf

# 192.168.0.11
	iperf3 -s -i 1 -B 192.168.0.11 -p 8888 -f M

# 192.168.0.10,从服务端下载数据
	iperf3 -c 192.168.0.11 -p 8888 -l 50000 -t 5 -i 1 -b 10M -f M -u -R

查看tcpdump

192.168.0.10接收端一个完整的UDP报文经tcpdump抓取如下:

17:35:29.013919 IP (tos 0x0, ttl 64, id 21554, offset 0, flags [+], proto UDP (17), length 1500)
    192.168.0.11.ddi-udp-1 > 192.168.0.10.57198: UDP, length 50000
17:35:29.013931 IP (tos 0x0, ttl 64, id 21554, offset 1480, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013934 IP (tos 0x0, ttl 64, id 21554, offset 2960, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013935 IP (tos 0x0, ttl 64, id 21554, offset 4440, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013936 IP (tos 0x0, ttl 64, id 21554, offset 5920, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013937 IP (tos 0x0, ttl 64, id 21554, offset 7400, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013939 IP (tos 0x0, ttl 64, id 21554, offset 8880, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013939 IP (tos 0x0, ttl 64, id 21554, offset 10360, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013940 IP (tos 0x0, ttl 64, id 21554, offset 11840, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013941 IP (tos 0x0, ttl 64, id 21554, offset 13320, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013942 IP (tos 0x0, ttl 64, id 21554, offset 14800, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013943 IP (tos 0x0, ttl 64, id 21554, offset 16280, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013944 IP (tos 0x0, ttl 64, id 21554, offset 17760, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013946 IP (tos 0x0, ttl 64, id 21554, offset 19240, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013976 IP (tos 0x0, ttl 64, id 21554, offset 20720, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.013978 IP (tos 0x0, ttl 64, id 21554, offset 22200, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014000 IP (tos 0x0, ttl 64, id 21554, offset 23680, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014001 IP (tos 0x0, ttl 64, id 21554, offset 25160, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014020 IP (tos 0x0, ttl 64, id 21554, offset 26640, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014040 IP (tos 0x0, ttl 64, id 21554, offset 28120, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014153 IP (tos 0x0, ttl 64, id 21554, offset 29600, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014158 IP (tos 0x0, ttl 64, id 21554, offset 31080, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014159 IP (tos 0x0, ttl 64, id 21554, offset 32560, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014160 IP (tos 0x0, ttl 64, id 21554, offset 34040, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014161 IP (tos 0x0, ttl 64, id 21554, offset 35520, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014162 IP (tos 0x0, ttl 64, id 21554, offset 37000, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014217 IP (tos 0x0, ttl 64, id 21554, offset 38480, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014219 IP (tos 0x0, ttl 64, id 21554, offset 39960, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014220 IP (tos 0x0, ttl 64, id 21554, offset 41440, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014266 IP (tos 0x0, ttl 64, id 21554, offset 42920, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014267 IP (tos 0x0, ttl 64, id 21554, offset 44400, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014268 IP (tos 0x0, ttl 64, id 21554, offset 45880, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014318 IP (tos 0x0, ttl 64, id 21554, offset 47360, flags [+], proto UDP (17), length 1500)
    192.168.0.11 > 192.168.0.10: ip-proto-17
17:35:29.014319 IP (tos 0x0, ttl 64, id 21554, offset 48840, flags [none], proto UDP (17), length 1188)
    192.168.0.11 > 192.168.0.10: ip-proto-17

查看LOG

[root@localhost ~]# dmesg -c
[ 1350.890866] UDP-INPUT: IN=ens33 OUT= MAC=00:0c:29:c5:cf:55:00:0c:29:f1:9e:4a:08:00 SRC=192.168.0.11 DST=192.168.0.10 LEN=32 TOS=0x00 PREC=0x00 TTL=64 ID=38867 DF PROTO=UDP SPT=8888 DPT=51611 LEN=12 
[ 1350.892407] UDP-INPUT: IN=ens33 OUT= MAC=00:0c:29:c5:cf:55:00:0c:29:f1:9e:4a:08:00 SRC=192.168.0.11 DST=192.168.0.10 LEN=50028 TOS=0x00 PREC=0x00 TTL=64 ID=38868 PROTO=UDP SPT=8888 DPT=51611 LEN=50008 
[ 1350.994383] UDP-INPUT: IN=ens33 OUT= MAC=00:0c:29:c5:cf:55:00:0c:29:f1:9e:4a:08:00 SRC=192.168.0.11 DST=192.168.0.10 LEN=50028 TOS=0x00 PREC=0x00 TTL=64 ID=38895 PROTO=UDP SPT=8888 DPT=51611 LEN=50008 
[ 1350.995336] UDP-INPUT: IN=ens33 OUT= MAC=00:0c:29:c5:cf:55:00:0c:29:f1:9e:4a:08:00 SRC=192.168.0.11 DST=192.168.0.10 LEN=50028 TOS=0x00 PREC=0x00 TTL=64 ID=38896 PROTO=UDP SPT=8888 DPT=51611 LEN=50008 
[ 1351.095065] UDP-INPUT: IN=ens33 OUT= MAC=00:0c:29:c5:cf:55:00:0c:29:f1:9e:4a:08:00 SRC=192.168.0.11 DST=192.168.0.10 LEN=50028 TOS=0x00 PREC=0x00 TTL=64 ID=38934 PROTO=UDP SPT=8888 DPT=51611 LEN=50008 
----------------- #剩下的略

注:从上述内核日志可见,iptables过滤方式如下:

  1. 首先发送端发送分片,然后接收端接收分片,该分片从网卡收到后,是可以被tcpdump抓取的,具体tcpdump与iptables关系参见我博客:https://blog.csdn.net/qq_41586875/article/details/123320437
  2. 等数据包到内核后(未设置针对分片过滤),内核对数据包进行报文重组,整合成一个完整的数据包,然后再开始进行iptables过滤,可见iptables并不会对IP分片进行过滤,也即不存在过滤分片了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺仔_牛奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值