ip rule/ip route定义策略路由

ip rule 是 Linux 下的一个命令,用于管理和查看路由策略数据库 (RPDB, Routing Policy Database)。
它允许管理员定义基于各种选择条件(如源地址、目的地址、接口等)的路由规则。
以下是 ip rule 命令的一些常用参数及其解释:

# 常用参数
add:添加一条新的路由规则。
del:删除一条现有的路由规则。
list 或 show:显示当前的路由规则。

参数解释
from [ADDRESS[/MASK]]:指定源地址或源地址范围。只匹配来自这些地址的数据包。可以是单个 IP 地址或 CIDR 范围。
to [ADDRESS[/MASK]]:  指定目的地址或目的地址范围。只匹配发送到这些地址的数据包。可以是单个 IP 地址或 CIDR 范围。
iif [NAME]:		   指定入接口。只匹配从该接口接收到的数据包。接口名例如 eth0。
oif [NAME]:		   指定出接口。只匹配将从该接口发送出去的数据包。接口名例如 eth0。
priority [PREFERENCE]:指定规则的优先级。数值越小优先级越高。规则按优先级顺序进行匹配。规则按从小到大的顺序进行匹配。
table [TABLE_ID]:	   指定路由表。数据包匹配此规则后,将在指定的路由表中查找路由。默认路由表 ID 为 main (254), local (255), default (253) 等。
fwmark [MARK]:		   指定防火墙标记。只匹配带有该标记的数据包。由 iptables 或 nftables 设置的数据包标记。
uidrange [UID-START-UID-END]:匹配数据包的用户 ID 范围。例如, 0-65535。
sport [PORT[/MASK]]:  指定源端口或源端口范围。只匹配来自这些端口的数据包。可以是单个端口或端口范围。
dport [PORT[/MASK]]:  指定目标端口或目标端口范围。只匹配发送到这些端口的数据包。可以是单个端口或端口范围。
tos [TOS]:			   指定服务类型 (Type of Service)。只匹配带有此 TOS 值的数据包。TOS 值用来指定数据包的优先级。
ipproto [PROTOCOL]:   指定 IP 协议。只匹配使用该协议的数据包。例如, tcp, udp, icmp 等。

在方括号内的表达式(“[” 和 “]”之间的字符)是可选的(写命令时要去掉括号)。
在尖括号内的表达式(“<” 和 “>”之间的字符)是必须替换的表达式(而且要去掉尖括号)。
省略号表示该选项可以单个或多个

# 添加规则
ip rule add from 192.168.1.0/24 table 100 priority 100
这条规则表示,来自 192.168.1.0/24 网络的数据包将根据路由表 100 的规则进行处理,优先级为 100。

# 删除规则
ip rule del from 192.168.1.0/24 table 100 priority 100
这条规则表示删除之前添加的规则。

# 显示当前规则
ip rule show
这条命令将显示当前的所有路由规则及其优先级和条件。

#####################################################################
linux中默认有3个路由表,local main default
[root@localhost ~]# cat /etc/iproute2/rt_tables 
#
# reserved values
#
255	local
254	main
253	default
0	unspec
#
# local
#
#1	inr.ruhep

ip route show 默认就是打印的main表,等于ip route show table main
local表是本地路由表,ip route show table local,是系统配置的ip生成的路由信息。

ip route add 是用于向 Linux 内核的路由表中添加路由的命令。
它属于 ip 命令套件的一部分,该套件用于管理网络设备、路由、策略路由和隧道。
ip route add 命令有多种参数,可以配置路由的不同方面。以下是一些常见参数及其解释:

基本语法
ip route add [prefix] via [gateway] dev [device] [additional options]

常用参数及解释
prefix:				指定要添加的目标网络或主机。格式为 IP地址/子网掩码长度,例如 192.168.1.0/24 或 0.0.0.0/0(默认路由)。
via [gateway]:		指定路由数据包的下一跳网关 IP 地址。例如 via 192.168.1.1。这是数据包应通过的中间路由器。
dev [device]:		指定要通过的网络设备接口。例如 dev eth0。这用于指示数据包应发送到的物理或虚拟网络接口。
src [source-address]:	指定用于该路由的数据包的源地址。例如 src 192.168.1.100。这在多源地址环境中非常有用。
metric [value]:		指定路由的优先级(度量值)。度量值越小,优先级越高。用于在多条路由可用时确定使用哪条路由。
table [table_id]:	指定要添加路由的路由表。默认情况下,路由添加到主路由表(table 254)。
scope [scope]:		指定路由的范围。常用范围包括:
	global:			全球范围,适用于整个互联网。
	link:				链路范围,适用于直连网络。
	host:				主机范围,仅适用于特定主机。
proto [protocol]:	指定路由协议。常用协议包括:
	static:	静态路由。
	kernel:	由内核生成的路由。
	boot:		在系统启动时添加的路由。
	dhcp:		由 DHCP 获取的路由。
	onlink:		强制将目标视为直接连接,即使没有相关 ARP 条目。这在某些需要绕过常规 ARP 检查的情况下有用。
	nexthop:	指定多个下一跳以实现负载均衡或冗余。例如:

ip route add 192.168.1.0/24 nexthop via 192.168.1.1 dev eth0 weight 1 nexthop via 192.168.1.2 dev eth1 weight 2
weight:指定每个下一跳的权重,用于流量分配。

示例
添加到特定网络的路由:
ip route add 192.168.2.0/24 via 192.168.1.1 dev eth0
将发往 192.168.2.0/24 网络的数据包通过 192.168.1.1 网关,并使用 eth0 接口。


添加默认路由:
ip route add default via 192.168.1.1
将所有未知目的地的数据包发送到 192.168.1.1 网关。


添加主机路由:
ip route add 192.168.1.10/32 dev eth0
将发往 192.168.1.10 的数据包通过 eth0 接口。


添加带度量值的路由:
ip route add 192.168.2.0/24 via 192.168.1.1 dev eth0 metric 100
添加到 192.168.2.0/24 网络的路由,度量值为 100。


添加到特定路由表:
ip route add 192.168.2.0/24 via 192.168.1.1 dev eth0 table 100
将路由添加到 ID 为 100 的路由表。

非对称路由

ubuntu双网卡,网卡1为一个网段(192.168.1.10),网卡2为另一个网段(192.168.2.10),网卡2不配置网关,通过网卡2的ip连接服务器ssh服务,为什么可以连接?

在 Ubuntu 系统中,如果有两个网卡 (NICs),每个网卡连接到不同的网络,并且只有一个网卡配置了网关,那么通过未配置网关的网卡进行连接时,数据包的返回路径可能会通过配置了网关的网卡返回。
这通常被称为 “异路由” 或 “非对称路由”。

# 解释

网卡1 (eth0): IP 192.168.1.10/24, 网关 192.168.1.1
网卡2 (eth1): IP 192.168.2.10/24, 没有配置网关

# 连接过程
从外部网络的某个主机 (IP 192.168.6.20) 尝试通过 eth1 (192.168.2.10) 连接到服务器的 SSH 服务。
外部主机发送一个 SSH 请求到 192.168.2.10。这个数据包到达 eth1 并被处理。
服务器收到数据包并生成响应。

# 数据包的返回路径
由于 eth1 没有配置网关,默认情况下,服务器会根据其路由表决定如何返回数据包。
路由表中通常有一个默认网关指向 eth0 的网关 192.168.1.1。
如果没有特定路由指向 192.168.6.20,服务器会通过 eth0 上的默认网关将响应包发回。

可以使用 ip route show 查看路由表:
输出如下:

default via 192.168.1.1 dev eth0 proto static metric 100 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10 metric 100 
192.168.2.0/24 dev eth1 proto kernel scope link src 192.168.2.10 metric 100 

在这种配置中,没有明确的路由指向 192.168.6.20,默认路由通过 192.168.1.1。

# 解决办法,策略路由
将从192.168.2.10发出的数据从192.168.2.1网关发送出去。

ip rule add from 192.168.2.10/32 table 100
ip route add default via 192.168.2.1 dev eth1 table 100

这样配置后两个网卡都可以用,并且实现了源进源出。

注意:
在linux发行版中要注意rp_filter内核参数,像centos默认会设置为1,严格模式,禁止进出路径不一致,而ubuntu默认为2,宽松模式,即数据包只要能回即可。

此问题对应华为usg防火墙中的源进源出。

反向路径检查rp_filter

# ip为自动获取时的路由表
[root@localhost ~]# ip route show
default via 192.168.11.1 dev ens33 proto dhcp src 192.168.11.68 metric 100 
default via 192.168.12.1 dev ens36 proto dhcp src 192.168.12.28 metric 101 
192.168.11.0/24 dev ens33 proto kernel scope link src 192.168.11.68 metric 100 
192.168.12.0/24 dev ens36 proto kernel scope link src 192.168.12.28 metric 101 

# ip为固定时的路由表
[root@localhost ~]# nmcli connection modify Wired\ connection\ 1 ipv4.method manual ipv4.addresses 192.168.11.68/24 ipv4.gateway 192.168.11.1 ipv4.dns 114.114.114.114 connection.autoconnect yes
[root@localhost ~]# nmcli connection modify Wired\ connection\ 2 ipv4.method manual ipv4.addresses 192.168.12.28/24 ipv4.gateway 192.168.12.1 ipv4.dns 114.114.114.114 connection.autoconnect yes
把网卡down再up查看
[root@localhost ~]# ip route show
default via 192.168.11.1 dev ens33 proto static metric 100 
default via 192.168.12.1 dev ens36 proto static metric 101 
192.168.11.0/24 dev ens33 proto kernel scope link src 192.168.11.68 metric 100 
192.168.12.0/24 dev ens36 proto kernel scope link src 192.168.12.28 metric 101 

可以看到不管自动还是手动指定ip默认路由是从192.168.11.1网关走。

本机电脑ip为 192.168.6.100,本机和目标机器通过三层交换机连接。

本机ping 192.168.11.68是通的,但是ping 192.168.12.28不通。
原因就是因为almalinux(ID_LIKE=”rhel centos fedora”)默认开启反向路径检查 – Reverse Path Filtering(rp_filter)

# 查看内核参数
[root@localhost ~]# sysctl -a |grep -w rp_filter
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.ens33.rp_filter = 1
net.ipv4.conf.ens36.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1

rp_filter是Linux Kernel以及众多网络设备采用的一种保护机制,以用来检查收到的数据包的原地址是否可路由。
开启rp_filter功能时,当服务器收到一个数据包之后,将此数据包的源地址和目的地址对调后也就是构建的响应数据包,
通过查找路由表之后发现响应包依然从收到数据包的网卡发送回去,则表示此消息通过了rp_filter的检测。

此内核参数有3个值:
0 关闭反向路由校验
1 严格模式,对每一个进来的数据包,如果反向路由不是通过收到数据的包接口,校验失败后收到的数据包丢弃
2 宽松模式,对每个进来的数据包,校验源地址是否可达,如果反向路由可以通过任何接口到达,那么校验成功,否则校验失败后数据包丢失

# 测试开关脚本
[root@localhost ~]# cat rp.sh
if [ "$1" == "stop" ]; then
	sysctl -w net.ipv4.conf.all.rp_filter=0
	sysctl -w net.ipv4.conf.default.rp_filter=0
	sysctl -w net.ipv4.conf.ens33.rp_filter=0
	sysctl -w net.ipv4.conf.ens36.rp_filter=0
	sysctl -w net.ipv4.conf.lo.rp_filter=0
else
	sysctl -w net.ipv4.conf.all.rp_filter=1
	sysctl -w net.ipv4.conf.default.rp_filter=1
	sysctl -w net.ipv4.conf.ens33.rp_filter=1
	sysctl -w net.ipv4.conf.ens36.rp_filter=1
	sysctl -w net.ipv4.conf.lo.rp_filter=1
fi
[root@localhost ~]# bash rp.sh stop

当关闭检查时(设置为0),2个ip都可以ping通了,也可以通过这2个ip连接ssh服务。

在不同的linux发行版中,此值可能不同。在ubuntu系统中,此值默认为2,即宽松模式。

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
目前RFC3704推荐启用严格模式以防止DDos攻击对IP欺骗的攻击。
如果使用非对称路由或其他复杂的路由,则推荐使用宽松模式。

非对称路由
非对称路由是指发送和接收数据包时,分别使用了主机和目的地设备之间两条不同的路径。
参考:https://blog.csdn.net/chiyuwei1766/article/details/50706306