原文地址:反向路径过滤——reverse path filter 作者:pwp_cu

反向路径过滤——reverse path filter

一、原理
先介绍个非对称路由的概念
参考《Understanding Linux Network Internals》三十章,
30.2. Essential Elements of Routing
Symmetric routes and asymmetric routes
Usually, the route taken from Host A to Host B is the same as the route used to get back from Host B to Host A; the route is then called symmetric . In complex setups, the route back may be different; in this case, it is asymmetric.

关于反向路径过滤,参考《Understanding Linux Network Internals》三十一章,
31.7. Reverse Path Filtering
We saw what an asymmetric route is in the section "Essential Elements of Routing in Chapter 30. Asymmetric routes are not common, but may be necessary in certain cases. The default behavior of Linux is to consider asymmetric routing suspicious and therefore to drop any packet whose source IP address is not reachable through the device the packet was received from, according to the routing table.
However, this behavior can be tuned via /proc on a per-device basis, as we will see in Chapter 36. See also the section "Input Routing" in Chapter 35.

二、检查流程
如果一台主机(或路由器)从接口A收到一个包,其源地址和目的地址分别是10.3.0.2和10.2.0.2,
即, 如果启用反向路径过滤功能,它就会以为关键字去查找路由表,如果得到的输出接口不为A,则认为反向路径过滤检查失败,它就会丢弃该包。

关于反向路径过滤,ipv4中有个参数,这个参数的说明在Documentation/networking/ip-sysctl.txt中。
rp_filter - INTEGER
    0 - No source validation.
    1 - Strict mode as defined in RFC3704 Strict Reverse Path
        Each incoming packet is tested against the FIB and if the interface
        is not the best reverse path the packet check will fail.
        By default failed packets are discarded.
    2 - Loose mode as defined in RFC3704 Loose Reverse Path
        Each incoming packet's source address is also tested against the FIB
        and if the source address is not reachable via any interface
        the packet check will fail.

Current recommended practice in RFC3704 is to enable strict mode
    to prevent IP spoofing from DDos attacks. If using asymmetric routing
    or other complicated routing, then loose mode is recommended.

The max value from conf/{all,interface}/rp_filter is used
    when doing source validation on the {interface}.

Default value is 0. Note that some distributions enable it
    in startup scripts.

三、源代码分析
git commit 373da0a2a33018d560afcb2c77f8842985d79594

net/ipv4/fib_frontend.c
 192 int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
 193                         int oif, struct net_device *dev, __be32 *spec_dst,
 194                         u32 *itag)
 195 {
             // 是否启用反向路径过滤
 216         /* Ignore rp_filter for packets protected by IPsec. */
 217         rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev);
 
             // 检查路由表
         // 注意这里的源地址贺目的地址是反过来的,
         // 看看其他函数是如何调用fib_validate_source()就明白了。
 227         if (fib_lookup(net, &fl4, &res))
 228                 goto last_resort;

// 运行到这里,说明反向路由是可达的
         // 下面分成两种情况检查输出设备是否就是输入设备
 237 #ifdef CONFIG_IP_ROUTE_MULTIPATH
             // 启用多路径时,任意一个匹配,就用它了
 238         for (ret = 0; ret < res.fi->fib_nhs; ret++) {
 239                 struct fib_nh *nh = &res.fi->fib_nh[ret];
 240
 241                 if (nh->nh_dev == dev) {
 242                         dev_match = true;
 243                         break;
 244                 }
 245         }
 246 #else
 247         if (FIB_RES_DEV(res) == dev)
 248                 dev_match = true;
 249 #endif
 250         if (dev_match) {
              // 反向路径过滤检查成功了,返回
 251                 ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
 252                 return ret;
 253         }
 254         if (no_addr)
 255                 goto last_resort;
             // 运行到这里,说明反向路径检查是失败的,
         // 如果rpf为1,表示反向路径检查必须成功才能正常返回,
         // 否则只好返回错误。
 256         if (rpf == 1)
 257                 goto e_rpf;
 278 e_rpf:
 279         return -EXDEV;

四、实例
本网络有三台机器,R1, R2 和PC,子网掩码都是255.255.0.0。
R2 (10.1.0.2) ---- (10.1.0.1) R1 (10.3.0.1) ---- (10.3.0.2) PC
R2 (10.2.0.2) ---- (10.2.0.1) R1

注意,设置R2的默认路由为10.1.0.1
现在,从PC上能够ping通10.1.0.2,但是ping不通10.2.0.2。
tcpdump显示,R2接到icmp request,但是不发送icmp reply。

PC
$ ip a
inet 10.3.0.2/16 brd 10.3.255.255 scope global eth0
$ ip r
10.3.0.0/16 dev eth0  proto kernel  scope link  src 10.3.0.2
default via 10.3.0.1 dev eth0

R1
$ ip a
inet 10.1.0.1/16 brd 10.1.255.255 scope global eth1
inet 10.2.0.1/16 brd 10.2.255.255 scope global eth2
inet 10.3.0.1/16 brd 10.3.255.255 scope global eth3
$ ip r
10.1.0.0/16 dev eth1  proto kernel  scope link  src 10.1.0.1
10.2.0.0/16 dev eth2  proto kernel  scope link  src 10.2.0.1
10.3.0.0/16 dev eth3  proto kernel  scope link  src 10.3.0.1

R2
$ ip a
inet 10.1.0.2/16 brd 10.1.255.255 scope global eth1
inet 10.2.0.2/16 brd 10.2.255.255 scope global eth2

$ ip r
10.1.0.0/16 dev eth1  proto kernel  scope link  src 10.1.0.2
10.2.0.0/16 dev eth2  proto kernel  scope link  src 10.2.0.2
default via 10.1.0.1 dev eth1

请问这是什么原因?
你可以返回去细细思考5分钟......

我的回答:
假设R2的两个接口分别为A(10.1.0.2)、B(10.2.0.2)。
从PC ping 10.2.0.2时,包的路径是PC-->10.3.0.1-->10.2.0.2,
此时包的 ,
以进行反向路径检查, 得到输出设备是A,
因为目的地址是10.3.0.2,只能使用默认路由。A!=B,反向路径检查失败,
丢弃该包!

五、如何解决
两种方法:
1 On R2:
ip route add 10.3.0.0/16 via 10.2.0.2
增加一条关于10.3.0.0/16子网的路由。

2 On R2:
/etc/sysctl.conf
net.ipv4.conf.default.rp_filter = 0
禁用反向路径检查。

反向路径过滤——reverse path filter的更多相关文章

  1. Nodejs基础:路径处理模块path总结

    模块概览 在nodejs中,path是个使用频率很高,但却让人又爱又恨的模块.部分因为文档说的不够清晰,部分因为接口的平台差异性. 将path的接口按照用途归类,仔细琢磨琢磨,也就没那么费解了. 获取 ...

  2. 反向代理(Reverse Proxy)

    反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时 ...

  3. Swagger 路径过滤 -PreSerializeFilters

    Swagger 默认显示所有api, 如果要做路径过滤,可以这样做. //过滤,只显示部分api app.UseSwagger(c=> { c.PreSerializeFilters.Add(( ...

  4. RxJava【过滤】操作符 filter distinct throttle take skip first MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. 反向代理服务器(Reverse Proxy)

    反向代理服务器(Reverse Proxy)   普通代理服务器是帮助内部网络的计算机访问外部网络.通常,代理服务器同时连接内网和外网.首先内网的计算机需要设置代理服务器地址和端口,然后将HTTP请求 ...

  6. 37.Node.js工具模块---处理和转换文件路径的工具 Path模块

    转自:http://www.runoob.com/nodejs/nodejs-module-system.html Node.js path 模块提供了一些用于处理文件路径的小工具,我们可以通过以下方 ...

  7. bat批处理文件怎么将路径添加到path环境变量中

    bat批处理文件怎么将路径添加到path环境变量中 摘自:https://zhidao.baidu.com/question/1887763143433391788.html 永久性的: @echo ...

  8. day18 时间:time:,日历:calendar,可以运算的时间:datatime,系统:sys, 操作系统:os,系统路径操作:os.path,跨文件夹移动文件,递归删除的思路,递归遍历打印目标路径中所有的txt文件,项目开发周期

    复习 ''' 1.跨文件夹导包 - 不用考虑包的情况下直接导入文件夹(包)下的具体模块 2.__name__: py自执行 '__main__' | py被导入执行 '模块名' 3.包:一系列模块的集 ...

  9. 探秘神奇的运动路径动画 Motion Path

    CSS 中有一个非常有意思的模块 -- CSS Motion Path Module Level 1,翻译过来也就是运动路径.本文将对 motion path 一探究竟,通过本文,你可以了解到: 什么 ...

随机推荐

  1. js-ES6学习笔记-Generator函数

    1.Generator 函数是 ES6 提供的一种异步编程解决方案.形式上,Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部 ...

  2. JPEG/PNG/GIF图片格式简析

    JPEG/PNG/GIF是Web浏览器广泛支持的3种图片格式. 1.JPEG格式最适合保存照片和其他复杂图像. 2.GIF和PNG格式最适合保存logo和其他包含单色.线条.文本的简单图形. 3.JP ...

  3. 高性能JavaScript(编程实践)

    避免双重求值JavaScript 允许你在程序中提取一个包含代码的字符串,然后动态执行,有四种方法可以实现,eval(),Function() 构造函数 settimeout 和 setinterva ...

  4. sass在vue注意的地方

    当用@import导入vue页面的时候,在sass/scss文件里面的url,路径开始就是导入的vue位置. 当前目录结构 App.vue 我在App.vue导入了public.scss,那在publ ...

  5. Python 基于Python实现Ftp文件上传,下载

    基于Python实现Ftp文件上传,下载   by:授客 QQ:1033553122 测试环境: Ftp客户端:Windows平台 Ftp服务器:Linux平台 Python版本:Python 2.7 ...

  6. linux 网络和流量监控

    1.流量监控 工具iptraf 安装:sudo apt-get install iptraf 运行:sudo iptraf   2.网络监控扫描 参考:https://www.cnblogs.com/ ...

  7. nodejs图像处理模块

    首先是搜索了npm包的性能比较,找到了这篇: https://github.com/ivanoff/images-manipulation-performance 性能最好的当属sharp,由于安装不 ...

  8. Lodash学习笔记

    有多年开发经验的工程师,往往都会有自己的一套工具库,称为utils.helpers等等,这套库一方面是自己的技术积累,另一方面也是对某项技术的扩展,领先于技术规范的制订和实现. Lodash就是这样的 ...

  9. PHP 8中数据类型

    PHP  一共支持八种数据类型 4种标量数据类型 boolean布尔型   只有两个值  true 和  flase integer整形  包括正整数和负整数,无小数位 float/double 浮点 ...

  10. How to Be Assertive Asking for What You Want Firmly and Fairly

    What Is Assertiveness? It's not always easy to identify truly assertive behavior. This is because th ...