欢迎光临散文网 会员登陆 & 注册

Linux 路由三大件

2023-08-15 16:31 作者:补给站Linux内核  | 我要投稿

对于 Linux 网络,好奇心强的同学一定思考过两个问题:

  • 当我们发出一个包的时候,Linux 是如何决策该从哪个网卡(假设有多个网卡)、哪个下一跳发出这个包,用什么 IP 作为 source......

  • 当 Linux 收到一个包时,又是如何决定往哪里送的,是发送给本地程序、其他虚拟接口,还是转发到其他机器......

今天,我们就来分析这两个问题的核心所在:路由。

我们学习计算机网络的时候,一般都会了解到基于目的地址(cidr)的路由(ip route),但是在 Linux 2.0 之后,RPDB (Routing Policy DataBase)诞生了,引入了更丰富的路由策略(ip rule)。除此以外,我们还可以通过 iptables 来操纵数据包,作为路由策略实施的依据,间接地影响路由过程。

至此,我们就认识了 Linux 路由的三大件。那么,三大件分别是什么原理,又是是如何交互的呢?且看下文分析。

注:虽然 Linux 提出了 nftables 来替换 iptables,但 iptables 仍然是事实上的标准

RPDB

首先我们来看看 RPDB,RPDB 由两部分组成,一个是 rule 列表,一个是 routing table 列表。

rule

ip rule 命令可以展示所有的 rule,每个 rule 由 selector(依据什么特征选择包) 和对应 action(对包做什么) 组成。

selector 主要有几种类型:

  • 出/入接口的 index,如 eth0、eth1

  • fwmark: 包携带的标记

  • Tunnel id

  • src/dst addr/port

  • type of service

  • priority

  • ......

action 主要由几种类型:

  • 传递给特定的 route

  • 跳转到其它的 rule

  • Drop/reject 这个包

  • ......

routing table

routing table 最开始只有一个,RPDB 后引入了多个(可以通过 cat /etc/iproute2/rt_tables 查看),默认有三个:

  • local,dst 为本地或者广播地址的路由

  • main,默认的路由

  • default,一般为空,为后处理预留空间

ip route 命令默认展示的是 main table,ip route show table local 形式可以展示其它 table。

routing table 里面每个 route 代表了 dst 为某个/些/类地址 的数据包应该 通过哪个渠道 转发。route 由几部分组成:

  • types

    • unicast,单播,最常见

    • unreachable,丢包并返回 ICMP 消息

    • blackhole, 默默丢包

    • ......

  • socpe,目标地址的范围: cat /etc/iproute2/rt_scopes,默认有三个

    • link,只在本设备有效,通常是直连

    • host,只在本机有效

    • global,全局有效,可传播,是默认值

    • ......

  • proto,路由由谁创建和维护: /etc/iproute2/rt_protos,默认有三个

    • kernel,内核创建,长期有效

    • boot,临时的

    • static,手动创建,override 动态路由(由路由协议维护entry)

    • ......

  • preference,优先级,一般都是数字越小,优先级越高

  • dev,通过的设备名字,如 eth0

  • nexthop,下一跳

  • src,设置发出包的 src ip

  • ......

RPDB 运行逻辑

参考 fib_lookup 函数:如果你没有动过 RPDB,那么直接用 mian table 进行路由查找(fib_table_lookup)了;如果动过,则通过 __fib_lookup/fib_rules_lookup 进行 rule 匹配,匹配逻辑为:

  • 无论是出还是入方向的每个包,都会遍历所有 rule,按照 priority,由 0 开始

  • 第一个匹配的 rule 会执行 action

  • 如果 action 是 lookup route table,则用对应 table 进行路由查找(fib_table_lookup),如果查找失败,则继续执行下一个 rule

  • 如果没有任何 rule 匹配,则报错

路由查找逻辑为:

  • 最长前缀匹配(也是被认为最精准的)的 route 被选中

  • 如果有多个匹配,则 preference、tos/dscp、自然顺序都会被进行考虑,最后仅剩一个匹配

  • 如果没有匹配,则返回 rule 匹配,继续检查下一个 rule

iptables

iptables 主要用于包过滤、修改和 NAT。再次拿出下面这张神图,来阐释它五大表和五大链,及其生效顺序和范围:

原图:https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg



【文章福利】小编推荐自己的Linux内核技术交流群:【749907784】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)     


三大件的交互过程

了解了各自原理之后,我们当然想知道它们是怎么交互的。上面那张图实际上已经阐释了他们之间的交互,不过下面这张图能看得更清晰:

原图:http://www.adminsehow.com/2011/09/iptables-packet-traverse-map/

实践

这是一个完全没动过的环境:

我们现在来设计一个需求:源端口为 30300 的包,默默丢弃;源端口为 30301 的包,丢弃并报错;源端口为 30302 的包,用新的 route table 转发。
先看看实施前的结果,用 taobao.com 来测试

虽然实现这个需求有很多方式,但是我这里为了演示三大件的交互而选择了下面的这种方式:

首先需要标记这三种类型的包,由于是本地发包,我们采用 mangle output

iptables -t mangle -L 展示,iptables -t mangle -F 清理。

然后增加相应的 route table

以及 rule

结果发现 30302 依然能通,但是 30300 和 30301 都超时了,没看出来返回的错误。
采用 traceroute 的 tcp 模式作为测试工具则能够看出一些差别。

ip rule add from all fwmark 2 unreachable 对应结果也确实符合期望



原文作者:九零后程序员



Linux 路由三大件的评论 (共 条)

分享到微博请遵守国家法律