仅作为个人笔记查看,无任何参考价值!
什么是 rp_filter(反向路径过滤)?
rp_filter 的全称是 Reverse Path Filtering(反向路径过滤) 。它是 Linux 内核中的一个安全机制,核心目的是为了防止 IP 欺骗(IP Spoofing)攻击。
我们可以用一个通俗的例子来理解:
故事时间:
你是
ens160这张网卡的保安。今天有个快递员(外网请求数据包)从你这里进来了,包裹上写的寄件人地址是美国纽约(某个外网 IP)。作为保安,你很尽责。你偷偷查了一下公司的通讯录(Linux 路由表),发现如果公司要寄信去纽约,信件一律交给另一个保安
ens192去寄送(因为默认网关在它那)。这时候你(严格模式下的
rp_filter=1)就会怀疑:"既然去纽约要走ens192,那为什么从纽约来的快递会送到我ens160的手上?这绝对是个骗子假冒的地址!"于是,你默默地把这个包裹扔进了垃圾桶(丢包)。
这就是 rp_filter 的工作逻辑:它会把接收到的数据包的"源 IP"拿出来,当作"目的 IP"去查本地路由表。如果查出来的出接口(网卡)和这个包进来的接口不一致,内核就认为这个包是伪造的,直接丢弃。
rp_filter 的三个参数值:
-
0(No Filtering):关闭。完全不检查,哪怕路由表对不上也放行。 -
1(Strict Mode,严格模式) :必须完美对称。进来的网卡必须和反向路由查询出的出口网卡完全一致,否则丢弃。 -
2(Loose Mode,松散模式) :只要路由表里有路可走 就行。哪怕反向路由算出来的出口是ens192,只要有默认网关能送达源 IP,就允许它从ens160进来。
这种问题可以通过 route 命令来解决吗?
可以,而且在大型网络架构中,用路由解决才是最规范的作法!
为什么呢?因为把 rp_filter 改成 2 属于"见招拆招"的防御降级。如果我们不改 rp_filter,依然坚持保持最安全的 1(严格模式),那我们就必须让数据的"来路"和"回路"完全对称。
既然现在外网流量是从 ens160(192.168.95.x)进来的,那我们只要告诉系统:只要是回给外网的流量,也必须从 ens160 出去!
但是,用普通的 ip route add 或 route add 命令会遇到一个巨大的矛盾:
普通路由的死胡同 ❌
如果我们在普通的路由表里加一条默认路由:
Bash
sudo ip route add default via 192.168.95.253 dev ens160
这时候系统就会有两个默认网关(10.0.0.1 和 192.168.95.253)。Linux 会陷入混乱,或者根据优先级(Metric)只走其中一个。如果选了 192.168.95.253,那原本属于 10.0.0.x 网段的内网业务可能又会断开。
正确的解法:高级路由(策略路由 Policy Routing)
既然不能影响全局的默认网关,我们可以搞"特殊待遇"------根据数据的来源 IP 决定走哪条路。
这就需要用到高级策略路由。步骤如下(不用执行,作为技术储备了解即可):
1. 创建一个独立的全新路由表(比如取名叫 table 100)
在这个表里,我们把默认网关指向 ens160 的网关:
Bash
sudo ip route add default via 192.168.95.253 dev ens160 table 100
2. 制定一条策略规则(Rule)
告诉内核:只要发现发出去的数据包,它的源 IP 是 ens160 上的那张 VIP(192.168.95.69),就必须去查 table 100 这张专门的路由表,而不是全局路由表!
Bash
sudo ip rule add from 192.168.95.69 lookup table 100
💡 策略路由执行后的效果:
外网包从 ens160 进来 \\rightarrow 内核准备回包,源 IP 填 192.168.95.69 \\rightarrow 内核触发 ip rule 规则:"哦!源 IP 是 95.69,请去查 table 100" \\rightarrow 查到 table 100 的默认网关是 192.168.95.253(ens160) \\rightarrow 顺利从 ens160 原路返回。
此时,进出网卡完全一致,即使 rp_filter=1 严格模式也会高高兴兴地放行!
总结:以后遇到类似环境该怎么选?
-
追求快速排长、图省事(中小内网、测试环境) :直接把
rp_filter改为2。这是最推荐的,因为改动极小,不容易把其他正常的业务路由改塌。 -
网络安全要求极高(金融、公网核心业务) :保留
rp_filter=1,老老实实去写高级策略路由(Policy Routing),实现精细化的各网卡原路进出。
bash
sudo vi /etc/sysctl.conf
把光标移到文件最底部,粘贴以下几行(记得修改网卡名称):
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.ens160.rp_filter = 2
net.ipv4.conf.ens192.rp_filter = 2
最后,执行以下命令让其永久生效:
sudo sysctl -p
💡 参数详解:
-p:代表 Load file(加载配置文件)。它会让内核重新读取/etc/sysctl.conf的内容并立即应用,这样下次机器重启,松散模式依然生效。