1、什么是反向路经检测
假设从eth0进来的报文是 src=a dst=b
如果开启了rp_filter (urpf反向路经检测)那么,查找路由以后,还需要在对这个报文进行检测。怎么检测?用a(也就是报文的源ip)作为目的地址来反查一下路由,如果查出来的结果是报文会从进来的口出去(也就是从哪里来,回复报文就从哪里出去),那么这个报文就是合法的可以继续;如果不一致,那么就是非法的报文,丢弃。
2、开启rp_filter参数的作用
- 减少DDoS攻击
校验数据包的反向路径,如果反向路径不合适,则直接丢弃数据包,避免过多的无效连接消耗系统资源。
- 防止IP Spoofing
校验数据包的反向路径,如果客户端伪造的源IP地址对应的反向路径不在路由表中,或者反向路径不是最佳路径,则直接丢弃数据包,不会向伪造IP的客户端回复响应。
3、具体的代码实现:
IN_DEV_RPFILTER 宏定义解释:
它的意思就是net.ipv4.conf.all.arp_filter和当前网卡的rp_filter两者取最大值,也就是说如果all.arp_filter设置为0了,但是某个网卡的rpf设置不为0,那么实际上还是打开rpf的意思!!!
宏定义展开以后:
__fib_validate_source:
注意这里的源地址和目的地址是反过来的
查找路由
如果匹配(要出去的口就是进来的口),那么直接return
如果不匹配,又开了反向路经检测,跳到e_rpf,返回-EXDEV
层层调用返回之后,回到了最初调用的地方ip_rcv_finish。因为返回的是-EXDEV,所以增加rpfilter的计数,然后把包丢掉!!!
ip_rcv_finish:
4、解决办法:
关闭rp_filter(有些操作系统默认是关闭)
/etc/sysctl.conf
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
sysctl -p 使之生效