首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux路由表和策略路由

Linux路由表和策略路由

作者头像
YaoQi
发布2025-07-14 18:51:45
发布2025-07-14 18:51:45
39600
代码可运行
举报
运行总次数:0
代码可运行

Linux的网络功能异常强大,包含了完整的路由功能,一台Linux主机配置多个网卡连上不同的网络,经过配置就能当路由器使用。

路由表

路由表是一组路由规则,通常以表格格式查看,用于确定通过网络传输的数据包将被定向到何处。

Linux系统支持多张路由表,可以使用策略选择使用不同的路由表。

路由表的编号

路由表都有一个数字编号,取值范围1 到 2^32-1,如果想用字符串引用,可以在 /etc/iproute2/rt_tables中定义(路由表是否存在与此文件无关,只是数字编号和字符的对应关系定义),Linux系统中一般已经预定义了一些路由表及名称:

这里几个编号是保留的,我们自定义路由表不应使用。

local表由系统内核管理和生成,我们不应编辑。

main表是主要的路由表,一般的配置就在这里。

default表一般为空,是历史原因为兼容某些程序保留的。

查看系统中有哪些路由表:

代码语言:javascript
代码运行次数:0
运行
复制
# 显示出所有的表名或表ID

# 支持-P perl正则表达式的环境
ip -d route show table all | grep -Po 'table \K[^\s]+' | sort -u
# 支持-E 参数,扩展正则表达式的环境
ip -d route show table all | grep -Eo 'table [^\s]+' | awk '{print $2}' | sort -u 

# 只显示表ID加-N参数,并不是所有ip命令都支持
ip -d -N route ......
图片
图片

如图所示,有个编号200的路由表,它并没有名字。

参数解释:

ip参数 -d detail 显示细节;-N number 数字化显示,不进行易读译,就显示路由表ID而不是名称了

grep参数 -P PCRE格式的正则;-o 只显示匹配的部分,而不显示整行;

perl格式正则 \K 代表重置匹配的起点,也就是前边要有'table '但其并不出现在结果中;[^\s]+匹配至少一个非空白字符

sort参数 -u  unique,去重;

路由表的内容

查看:ip -d route show table main

(table main可以省略,默认就是它)

图片
图片

上图所展示信息的意义可以通过man ip-route查看,这里做简单的介绍。

第1列 指记录类型(Type)

unicast 指单播路由,按前缀最长匹配。除此之外可能的值还有local、broadcast、anycast、multicast、throw、unreachable、blackhole、 prohibit等。

第2列

目标IP或网络。default指默认路由0.0.0.0/0; 带掩码的指一个网段的路由;还有到特定IP的路由。

后边的是成对出现的配置项和配置值:

via 指定下一级路由器的地址,也就是网关地址;

dev 指发送数据的设备名;

proto 指配置的路由的协议或方法,dhcp是由dhcp服务配置的,kernel是由内核配置的,static是手工配置的等;

scope 指到目标的距离,globle代表到目标需要至少一个路由器(hop)中转、link代表目标在本地网络上,也就是在一个网段是直连的、host代表目标在本机上;

src 发往目标时,如果程序没有手动绑定源IP,则使用路由条目的src值;

metric 到目标的成本,值低的优先选择,成本可能由跳数,延迟,带宽,稳定性等相关数据生成。

下边解释下这几条记录:

unicast default via 172.29.127.253 dev eth0 proto dhcp scope global src 172.29.114.8 metric 100

这是个单播路由,default表明其为默认路由,也就是如果匹配不上表里的其他记录,就按这条走;数据会通过eth0接口发给网关 172.29.127.253 ,如果是本机生成的数据包,源IP建议为172.29.114.8;此条路由是DHCP服务生成的,走这条路的成本是100。

unicast 172.29.112.0/20 dev eth0 proto kernel scope link src 172.29.114.8

单播路由,目标IP属于172.29.112.0/20的走此配置;如果是本机生成的数据包,源IP建议为172.29.114.8;通过eth0设备发出;内核生成的此记录;

删除路由条目

首先ip route show table <table_name> 查看条目

然后ip route del <对应条目复制过来> 即可

多路径路由

如果设备有多个出口,可以使用多路径路由(Multipath Routing):

ip route add default scope global nexthop via 172.16.0.2 dev enp0s8 weight 1 nexthop via 10.0.2.1 dev enp0s3 weight 2

图片
图片

注:但这并不能让流量按weight比重分配,因为这个是基于路由的,且路由是有缓存的,只是在查路由表的时候起作用。

策略路由

路由表只是根据目标IP来选择路由。而Linux支持依据源地址、ToS(Type of Service)标签, fwmark (firewall mark,数据包在内核中的数据结构上的一个标签), 还有数据包传入的接口名等选择路由表,这就是策略路由。

这些策略被保存在 routing policy database(RPDB)中,查看当前的策略:

ip rule show

图片
图片

第一条策略,从任意地址过来的数据包,查local路由表,没有匹配的记录就查下一条策略;下一条策略也是所有的数据包查main路由表,main路由表一般会有默认路由肯定会匹配上,所以下一跳default路由表的策略一般就没机会了。

上边这个策略是Linux默认的初始策略,如果有特殊需要我们可以添加自定义策略。

添加删除策略

图片
图片

命令的格式是 ip rule { add | del } SELECTOR ACTION

SELECTOR用于筛选流量,ACTION用于执行动作。

SELECTOR最前边可以加not取反。

容易理解的筛选参数有:from(源IP),to(目的IP)、iif(输入网卡)、sport(源端口)、dport(目的端口)、ipproto(协议类型tcp、udp)等。

fwmark,是firewall mark的意思。通过iptables或nftable等防火工具,用一定的规则给数据打标签,然后路由规则使用这个标签区分流量,也就是说防火能区分的流量,路由就能区分。

uidrange,使用用户ID范围匹配流量。不过要注reverse path filter参数要配置散模式 net.ipv4.conf.tun1.rp_filter=2。

tostype of service)或 dsfield TOS

IP数据包头有一组Differentiated Services Code Point (DSCP)标记,此项就是根据这个标记来区分数据流量。这个Service类型简单来说就是标记此流量承载的服务是低延迟的,高吞吐的,高可靠的等等。

ACTION主要是:

table, 指定路由表名。

protocol, 谁安装的此规则。比如zebra

nat, 指定nat地址

realm,为此流量打上realm编号标签(SRC/DST),用法不详。

goto , 跳转到某个规则

还有两个 SUPPRESSOR 抑制器用于ACTION:

suppress_prefixlength NUMBER

          拒绝前缀长度小于等于NUMBER的。

suppress_ifgroup GROUP

拒绝使用属于接口组group的设备的路由决策。

其他参数:

type, 指定类型,默认是unicast

priority, 指定规则优先级编号,设置或查询rule用。

删除策略

代码语言:javascript
代码运行次数:0
运行
复制
ip rule show
ip rule del <对应条目复制过来>
或
ip rule del priority 32764  # 按优先级编号删除

示例:

图片
图片

如果上图,服务器有两个接口eth1、eth2,通过两个ISP连接到互联网,我们想让ISP1过来的流量从eth1返回,ISP2过来的流量从eth2返回。过来好说,关键是返回。返回的时候,目标IP是对方的IP,并不能提前按目的IP写好路由,这时候就需要按源IP写路由了。

首先给ISP1和ISP2对应两个路由表id:

代码语言:javascript
代码运行次数:0
运行
复制
echo -e "100 ISP1\n200 ISP2" >> /etc/iproute2/rt_tables
图片
图片

ISP1路由表配置ISP1为默认出口:

代码语言:javascript
代码运行次数:0
运行
复制
ip route add default via 100.0.0.1 table ISP1
ip route add 100.0.0.0/24 dev eth1 src 100.0.0.109 table ISP1

ISP2路由表配置ISP2为默认出口:

代码语言:javascript
代码运行次数:0
运行
复制
ip route add default via 200.0.0.1 table ISP2
ip route add 200.0.0.0/24 dev eth2 src 200.0.0.209 table ISP2

然后写策略路由:

代码语言:javascript
代码运行次数:0
运行
复制
ip rule add from 100.0.0.109 table ISP1
ip rule add from 200.0.0.209 table ISP2

总结:

Linux系统可以使用IP数据包的各种信息生成策略,选择不同的路由表,不同的路由表按目的地址做不同的出口规划,最终实现了对路由的精准的自定义规划。

参考资料:

https://lartc.org/lartc.html

http://linux-ip.net/html/routing-tables.html

http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-30.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漫跑的小兔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档