文章目录
- 概述
- 1、带via
- 1.1 添加路由前的初始状态
- 1.2. 执行添加路由的命令
- 1.3. 添加路由后的状态
- 2、不带 via (使用设备接口),直连
- 3、带via还是不带via ?
- 4、dev xx的作用
- 4.1 命令中带via时,建议不带 dev eth0 (让系统自动判断)
- 4.2 命令中带via,可以手动强制指定 dev eth0 (但不建议)
- 4.3 不带via时,必须指定dev
- 4.4 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 这条直连路由怎么来的
- 3.3.1 如果没有这条路由,会发生什么?
概述
什么时候带via ,什么时候不带via,什么时候带dev,什么时候不带dev?
特性 | 带 via (网关路由) | 不带 via (接口路由 / 直接路由) |
---|---|---|
命令示例 | ip route add 10.10.10.0/24 via 192.168.1.1 | ip route add 10.10.10.0/24 dev eth1 |
语义 | “要去往 10.10.10.0/24,请把包发给网关 192.168.1.1,让它去处理。” | “要去往 10.10.10.0/24,请直接从 eth1 接口发出去。” |
下一跳 | 一个具体的网关 IP 地址 (192.168.1.1) | 一个本机的物理/逻辑接口 (eth1) |
使用场景 | 目标网络不在本机直接连接的网段,需要另一个路由器中转。 | 目标网络直接连接在指定的接口上。 |
ARP 请求 | 会对网关 IP (192.168.1.1) 发起 ARP 请求,获取其 MAC 地址。 | 会对目标 IP (如 10.10.10.5) 直接发起 ARP 请求,获取其 MAC 地址。 |
常见用途 | 访问其他子网、设置默认网关、复杂网络拓扑。 | 点对点链接、某些 VPN 配置、连接没有网关的简单网络。 |
路由必须是直连或下一跳之一!
添加路由模版是 ip route add SrcIp [via NextJumpIp] [dev ethxx]
:
- 当via不为空时,表示通过下一跳路由方式发送消息;
- 当via为空时,通过直连方式发送消息;
- 当via不为空时,系统会根据内核生成的路由来自动匹配eth,此时dev eth可以省略;
- 当via为空时,此时必须手动指定eth,因为此时系统没法自动生成eth
1、带via
假设我们有一台 Linux 服务器,配置如下:
IP 地址: 192.168.1.100/24
接口: eth0
现在我们需要访问 10.10.10.0/24
网络。
1.1 添加路由前的初始状态
首先,我们查看当前的路由表:
route -n
首先,我们查看当前的路由表:
输出可能类似于:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
解读:
-
默认路由:所有目标 (0.0.0.0) 的流量都发往网关
192.168.1.1
,通过eth0
接口。 -
本地网络路由:发往
192.168.1.0/24
网络的流量直接连接(简称直连路由),不需要网关 (0.0.0.0 表示“在本机网络上”),通过 eth0 接口。
此时,路由表中没有去往 10.10.10.0/24
网络的路由。
1.2. 执行添加路由的命令
现在我们添加一条静态路由,指明如何去往 10.10.10.0/24 网络:
sudo ip route add 10.10.10.0/24 via 192.168.1.1
这条命令的意思是:“要去往 10.10.10.0/24
这个网络,请将数据包下一跳发送到网关 192.168.1.1
1.3. 添加路由后的状态
再次查看路由表,确认更改已生效:
route -n
输出现在会变成:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 eth0
10.10.10.0 192.168.1.1 255.255.255.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
列 | 值 | 含义 |
---|---|---|
Destination | 10.10.10.0 | 目标网络地址。这条路由规则适用于所有要发往 10.10.10.0 这个网络的数据包。 |
Gateway | 192.168.1.1 | 网关地址。这是命令中 via 关键字后面的参数。它明确指出,数据包不是直接发往最终目标,而是必须先交给这个网关设备。 |
Genmask | 255.255.255.0 | 网络掩码。它与 Destination 一起定义了目标网络的范围是 10.10.10.0 到 10.10.10.255 (/24)。 |
Flags | UG | 路由标志。U (Up) 表示路由有效;G (Gateway) 表示该路由使用了网关 。这是一个关键标志,它明确告诉我们这是一条需要经过网关的路由 。 |
Iface | eth0 | 出站接口。数据包为了到达网关 192.168.1.1,最终会从哪个物理或虚拟接口发出。系统根据网关地址 192.168.1.1 属于 192.168.1.0/24 网络,自动判断 出应该使用 eth0 接口。 |
在系统的内核路由表中创建了一条新的、显式的静态路由规则。该规则规定:所有目的地为 10.10.10.0/24 网络的数据包,其下一跳应被转发至 IP 地址为 192.168.1.1 的网关路由器。这条路由使用了网关(由 Flags 中的 G 标识),并且数据包将通过 eth0 网络接口送出,以抵达该网关。
带来的结果:现在,当你尝试访问 10.10.10.5 时,系统不会再感到困惑或将流量错误地发送到默认网关(如果默认网关不知道 10.10.10.0/24 在哪,通信就会失败),而是会精确地将数据包首先发送给 192.168.1.1,由它来负责后续的路由工作。
2、不带 via (使用设备接口),直连
情况:10.10.10.0/24
网络直接连接在本机的第二个网卡 eth1
上。也就是说,本机 eth1
的 IP 地址可能就是 10.10.10.100/24
,或者这是一个点对点链路不需要 IP。
添加路由:
sudo ip route add 10.10.10.0/24 dev eth1
含义
:“告诉系统,所有发给10.10.10.0/24
的数据包,直接从eth1
接口扔出去,让它们在那个网络里自己广播寻找目标主机。”
数据包流向 (Ping 10.10.10.5):
1、系统查看路由表,匹配到这条规则。
2、系统检查出站接口是 eth1
。
3、系统直接对目标 IP 10.10.10.5 发起 ARP 请求(如果它是局域网地址且缓存里没有),询问 10.10.10.5 的 MAC 地址。
4、构造一个数据包:
-
目标 IP: 10.10.10.5 (最终目标)
-
目标 MAC: 11:22:33:44:55:66 (主机 10.10.10.5 的 MAC 地址)
5、数据包从 eth1
发出,交换机将其直接送达目标主机 10.10.10.5
。
3、带via还是不带via ?
选择 via 还是 dev 的核心,在于回答一个问题:“目标网络相对于本机的位置在哪里?”
1、 何时使用 via(经过网关)
条件: 当目标网络 (10.10.10.0/24
) 与本机的任何一个接口都不在同一个IP网段时。
-
逻辑:目标网络是“远程”网络,本机不知道如何直接到达。需要先将数据包交给一个知道如何去的“向导”(网关路由器)。
-
系统行为:系统会先查看路由表,找到 via 指定的网关IP,然后再通过一次路由查询,找出到达这个网关IP应该使用哪个接口(即利用那条自动生成的 proto kernel 路由)。
-
命令结构:ip route add <远程网络> via <网关IP>
-
示例:本机IP是 192.168.1.100/24,要访问 10.10.10.0/24。
# 正确:目标网络是远程的,需要经由网关sudo ip route add 10.10.10.0/24 via 192.168.1.1# 系统会自动为这条路由加上 `dev eth0`,因为它通过查询发现网关 192.168.1.1 在 eth0 的网段上。
一个简单的判断方法:如果你能 ping
通那个网关,就用 via
。如果目标网络直接插在你的网卡上,就用 dev。
4、dev xx的作用
4.1 命令中带via时,建议不带 dev eth0 (让系统自动判断)
sudo ip route add 10.10.10.0/24 via 192.168.1.1
是如何自动补足eth0
的?
系统的决策过程:
1、解析命令:“好的,有一条去往 10.10.10.0/24
的路由,下一跳是 192.168.1.1
。”
2、寻找出口:“现在,我需要知道如何到达这个网关 192.168.1.1
本身。”
3、查询路由表:系统查看现有的路由表,寻找能匹配 192.168.1.1
的路由。它找到了:
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 //ip link 命令能看到src属性,
这条路由的意思是:“192.168.1.1 在 192.168.1.0/24 网络里,而这个网络直接连在我的 eth0
接口上。”
这条路由是添加 eth0网卡的时候,自动带入的
4、确定接口:“完美!那么要到达网关 192.168.1.1,我就从 eth0 接口把包发出去。” 因此,最终的路由表条目中,Iface
列会自动填充为 eth0
。
优点:灵活。如果后来网络变更,网关 192.168.1.1 的地址移到了另一个接口(比如 eth1),系统会自动重新计算路径,仍然使用正确的接口。这是推荐和常用的方式
。
4.2 命令中带via,可以手动强制指定 dev eth0 (但不建议)
命令:
sudo ip route add 10.10.10.0/24 via 192.168.1.1 dev eth0
系统的决策过程:
-
解析命令:“好的,有一条去往 10.10.10.0/24 的路由,下一跳是 192.168.1.1,并且你明确命令我必须从 eth0 接口出去。”
-
服从指令:系统不会再去查询如何到达 192.168.1.1。它会无条件地信任你的指令,直接将数据包从 eth0 接口扔出去,并期望网关 192.168.1.1 就在 eth0 的另一端。
风险与用途:
- 风险:不灵活且可能错误。如果网关 192.168.1.1 实际上并不在 eth0 的网络上(例如,eth0 的IP被改成了 10.0.0.100/24),数据包就无法送达网关,导致这条路由失效。因为系统不会尝试从其他接口(如正确的 eth1)发送。
用途:用于一些特殊或明确的网络拓扑。例如:
-
网关有多个IP地址,你需要指定从哪个网络的接口出去。
-
测试或调试时,强制流量走特定路径。
-
某些策略路由的复杂配置。
4.3 不带via时,必须指定dev
当via为空时,此时必须手动指定eth,因为此时系统没法自动生成eth
结论
-
99% 的情况下
,非直连时,你应该使用sudo ip route add 10.10.10.0/24 via 192.168.1.1
(不带 dev
)。让系统的路由逻辑自动为你选择正确的出站接口,这是一种更智能、更不易出错的方式。 -
只有在你知道确切的需要并且有充分的理由强制流量从一个特定接口发出时,才使用 dev 参数。绝大多数标准网络配置都不需要手动指定它。
4.4 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 这条直连路由怎么来的
这触及了Linux网络栈自动配置的根本机制。
这条路由是从哪里来的?
这条路由不是由任何手动命令ip route add
创建的。它是由内核自动生成和维护的
,其来源可以追溯到您为网络接口配置IP地址的那一刻。
具体过程如下:
1、配置IP地址:当您为网卡 eth0
分配IP地址 192.168.1.100
和子网掩码 255.255.255.0 (/24)
时,无论是通过DHCP、netplan、NetworkManager还是手动的 ip addr add
命令,例如:
sudo ip addr add 192.168.1.100/24 dev eth0
2、内核触发路由添加:内核的网络栈监听到这个配置变化。它理解到:“eth0
接口现在属于 192.168.1.0/24
这个网络。”
3、自动创建路由:根据这个信息,内核自动在路由表中添加一条路由,其逻辑是:
“任何目标地址在 192.168.1.0/24
网络范围内的数据包(即从 192.168.1.1 到 192.168.1.254),都是我的‘本地邻居’。它们和我在同一个广播域(二层网络)里,我不需要把它们发给任何路由器
(网关)。我只需要从 eth0 接口直接发出去,然后通过ARP广播找到它们的MAC地址即可。”
4、路由条目解读:
-
192.168.1.0/24:目标网络。
-
dev eth0:从哪个接口发出。
-
proto kernel:协议为内核。这明确标识了此路由是由内核自动生成的。
-
scope link:作用域为链路。这意味着这条路由仅在此网络链路(即 eth0 连接的局域网)内有效。
-
src 192.168.1.100:当向这个目标网络发送数据时,优先使用 192.168.1.100 作为源IP地址。
3.3.1 如果没有这条路由,会发生什么?
答案是:网络通信会出现严重问题,系统将无法与本地网络中的任何其他设备通信。
如果这条路由不存在,系统会变得“愚蠢”:
1、无法访问本地邻居:您尝试 ping 同一局域网内的另一台电脑 192.168.1.50。
2、 错误的路由决策:系统查看路由表,发现没有精确匹配 192.168.1.50 的路由。于是它fall back(回退)到默认路由(default via …)。
3、 数据包被错误转发:系统认为:“要去往 192.168.1.50,我得把包发给默认网关 192.168.1.1。”
4、结果:
-
如果网关配置正确:网关收到这个目标是 192.168.1.50 的包,会发现这个IP就在它连接的同一个局域网里,于是它会把包再送回到这个局域网(这被称为“发夹弯转发”)。虽然最终可能能通,但路径极其低效,增加了网关的负担,而且ARP等过程可能无法正常工作。
-
如果网关不处理:网关可能直接丢弃这个不该由它转发的数据包,导致ping不通。
简单来说,没有这条路由,你的电脑就“意识”不到它和其他机器在同一个房间里,反而会觉得所有机器都在“外面”,需要由“门卫”(网关)来引见。这显然是错误和低效的。
什么情况下会没有这条路由?
这种情况非常罕见,通常意味着配置异常或错误:
-
完全手动的极简配置:在非常特殊的环境(如路由器或防火墙)中,管理员可能会删除所有自动生成的路由,然后只添加绝对必需的路由。但这不是正常操作。
-
配置错误:使用 ip addr add 时只添加了IP地址而没有指定掩码(虽然这通常会被拒绝),或者使用了不兼容的网络配置脚本。
-
接口状态异常。
如何验证它是自动生成的?
您可以很容易地证明这一点:
删除 eth0 的IP地址:
sudo ip addr del 192.168.1.100/24 dev eth0
查看路由表,你会发现 192.168.1.0/24 dev eth0 … 这条路由自动消失了
。
重新添加IP地址:
sudo ip addr add 192.168.1.100/24 dev eth0
再次查看路由表,你会发现那条路由又自动出现了
。
结论:
这条 proto kernel scope link
路由是Linux网络正常工作的基石
。它使得本地局域网通信成为可能,也是系统能够智能地判断“如何到达网关”的根本前提。没有它,自动识别出站接口的功能将完全失效。