代码改变世界

Linux 的路由功能

2019-01-25 15:39  云物互联  阅读(4137)  评论(0编辑  收藏  举报

目录

前文列表

《Networking 基本术语/概念》

路由器 Router

路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。路由工作在 OSI 参考模型第三层 —— 网络层的数据包转发设备。路由器通过转发数据包来实现网络互连。虽然路由器可以支持多种协议(如 TCP/IP、IPX/SPX、AppleTalk 等协议),但是在我国绝大多数路由器运行 TCP/IP 协议。路由器通常连接两个或多个由 IP 子网或点到点协议标识的逻辑端口,至少拥有 1 个物理端口。路由器根据收到数据包中的网络层地址以及路由器内部维护的路由表决定输出端口以及下一跳地址,并且重写数据链路层数据包头实现转发数据包(源 IP 和目标 IP 不发生变化,在网络的每一段传输时,源 MAC 和目标 MAC 发生变化,进行重新封装)。路由器通过动态维护路由表来反映当前的网络拓扑,并通过网络上其他路由器交换路由和链路信息来维护路由表。路由器连接着多个不同的网段,连接到同一路由器上的不同网段会被分割成不同的广播域,广播域之间的数据包转发需要路由器来完成。虽然具有 VLAN 功能的交换机也可以分割广播域,但是各广播域之间的通信交流仍然需要借助于路由器。

路由 Routing

路由(Routing)是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程。路由通常与桥接(Bridging)来对比,它们的主要区别在于桥接发生在 OSI 参考模型的第二层(数据链路层),而路由发生在第三层(网络层)。这一区别使二者在传递信息的过程中使用不同的信息(IP vs MAC),从而以不同的方式来完成其任务。

静态路由与动态路由

有两种方式来构建路由表

  • 静态路由:在每个路由器(或自己的计算机)上添加到各个网络的路由,适合规模较小的网络或网络不怎么变化的情况。
  • 动态路由:配置路由器使用路由协议(RIP、EIGRP、OSPF 等)自动的构建路由表,适合规模较大的网络,能够针对网络的变化自动选择最佳路径。

通过路由实现的全网通信示例

在这里插入图片描述

  1. 要实现全网通信,也就是网络中任意两个节点都可以通信,就要求每个路由器的路由表中必须有到所有网段的路由。
  2. 对于路由器来说,它只知道与自己直接相连的网段,对于没有直连的网络,则需要人工添加到这些网段的路由。如 R1 路由器直接与 A、B 两个网段相连,R1 会自动生成 A、B 网段的路由表,所以 R1 天然就知道数据包如何在在 A、B 网段之间进行转发。但 R1 没有与直接 C、D 网段相连,A、B 网段发出的数据包无法被 R1 转发至 C、D 网段,此时就需要手动添加 C、D 网段的路由到 R1(如上图所示)。此时 A 网段(192.168.0.2/24)访问 C 网段(172.16.1.2/24),R1 就知道该数据包应该被转发至 R2 的网关 172.16.0.2/24,R2 在根据目标地址(172.16.1.2/24)转发至 R3。
  3. “下一跳” 指的是数据包下一步转发给哪个路由器,应该为目标路由器的入口地址。对于点到点链路而言,“下一跳” 地址可以被写成目标网络的出口(如 serial 2/0),因为 PPP 协议,数据帧从一端发出,接收端只有一个;但对于路由器而言,因为路由器之间是一个以太网连接,这种情况下添加路由器,只能写下一跳地址,而不能写路由器的出口,因为路由器的出口连的是以太网,它无法知道该将数据包发给该以太网中的哪个路由器。
  4. 路由器只关心到某个 网段 如何转发数据包,所以添加路由时一定要是某个网段的地址,而不能是某个特定地址的路由,即一定要确保 IP 地址的主机位全是 0。如果要让路由器转发到一个 IP 地址的路由,子网掩码要写成 4 个 255。如:R1(config)#ip route 192.168.1.3 255.255.255.255 172.16.0.2

在这里插入图片描述

简单来说,每个 Router 都会连接多个 NET,如果当前 Router 没有这个 NET,那么 Router 就应该将数据包 下一跳 到连接这个 NET 的 Router 上,之间可能隔着多个 Routers。

Linux 作为路由器

Linux 本身就具备路由功能,有下述两种开启方式:

  1. 临时开启
echo "1" > /proc/sys/net/ipv4/ip_forward
  1. 永久开启
# vim /etc/sysctl.conf
net.ipv4.ip_forward=1

然后执行指令 sysctl -p 即时生效。

开启了路由功能之后的 Linux 服务器就相当于一个 Router,Linux 服务器的路由表就相当于 Router 的路由表,Linux 服务器上的网卡就相当于 Router Interface 常被作为 Gateway,数据包会根据路由表规则在这些 “网卡” 中选择下一跳。

  1. 开启 NAT
iptables -t nat -A POSTROUTING -j MASQUERADE

NOTE:对于 Router 所有数据包都是 SNAT,所以不需要配置 DNAT 规则。

route 指令

命令行下输入 route -nnetstat -rn,就可以打印本机的路由表:

[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.18.22.1     0.0.0.0         UG    0      0        0 br-ex
172.18.22.0     0.0.0.0         255.255.255.0   U     0      0        0 br-ex
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 o-hm0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
字段 说明
Destination 目的网段(或目的主机),0.0.0.0(或 default)表示默认路由
Gateway 网关地址,0.0.0.0 或 * 表示当前路由记录对应的 Destination 跟本机处于同一个网段,通信时不需要经过网关
Genmask 地址掩码,当路由项为默认路由时会设置为 0.0.0.0,当路由项为主机路由时会设置为 255.255.255.255
Flags 标志,含义参考表格后面的解释
Metric 跃点,到达指定网络所需的中转数(不在 Linux Kernel 中使用)
Ref 引用,路由项引用次数(不在 Linux Kernel 中使用)
Use 使用,路由项被路由软件查找的次数(不在 Linux Kernel 中使用)
Iface 接口

Flags 含义:

  • U - 路由是活动的
  • H - 目标是个主机
  • G - 需要经过网关
  • R - 恢复动态路由产生的表项
  • D - 由路由的后台程序动态地安装
  • M - 由路由的后台程序修改
  • ! - 拒绝路由

路由表项的类型

根据子网掩码的特征,可以将路由分为三种类型

  • 默认路由(0.0.0.0):当主机不能在路由表中查找到目标主机的 IP 地址或网络路由记录时,数据包就被发送到默认路由(默认网关)上。Flags 字段为 G。e.g. 默认路由是 IP 地址为 192.168.1.1 的路由器。
Destination    Gateway       Genmask Flags     Metric    Ref    Use    Iface
-----------    -------     ------- -----      ------    ---    ---    -----
default       192.168.1.1     0.0.0.0    UG       0        0     0    eth0
  • 主机路由(255.255.255.255):是路由表项中指向单个 IP 地址或主机名的记录。Flags 字段为 H。e.g. 本地主机通过 IP 地址 192.168.1.1 的路由器到达 IP 地址为 10.0.0.10 的主机。
Destination    Gateway       Genmask Flags     Metric    Ref    Use    Iface
-----------    -------     -------            -----     ------    ---    ---    -----
10.0.0.10     192.168.1.1    255.255.255.255   UH       0    0      0    eth0
  • 网络路由(特定的网段,e.g. 255.255.255.0):代表主机可以到达的网络。Flags 字段为 N。e.g. 本地主机将发送到网络 192.19.12 的数据包转发到 IP 地址的 192.168.1.1 的路由器。
Destination    Gateway       Genmask Flags    Metric    Ref     Use    Iface
-----------    -------     -------         -----    -----   ---    ---    -----
192.19.12     192.168.1.1    255.255.255.0      UN      0       0     0    eth0

ip route 指令

使用 ip route show 查看路由表项:

[root@localhost ~]# ip route show | column -t
default           via  172.18.22.1  dev    br-ex
172.18.22.0/24    dev  br-ex        proto  kernel  scope  link  src  172.18.22.200
192.168.0.0/24    dev  o-hm0        proto  kernel  scope  link  src  192.168.0.96
192.168.122.0/24  dev  virbr0       proto  kernel  scope  link  src  192.168.122.1

解释

  • 默认路由,没有匹配路由项的数据包全部通过设备 br-ex 转发至网关 172.18.22.1
default via 172.18.22.1 dev br-ex
  • 目的网段为 172.18.22.0/24 的数据包通过设备 br-ex 转发,该路由项由内核自动创建,直连,数据包源 IP 为 172.18.22.200,不需要经过网关(主机就处于该网段)。
172.18.22.0/24 dev br-ex proto kernel scope link src 172.18.22.200
  • 目的网段为 10.15.150.0/24 的数据包通过设备 enp0s3 转发至网关 192.168.150.253,该路由项为 static 静态路由,由手动创建,到达指定网络需要的转发的跳数为 1。
10.15.150.0/24  via  192.168.150.253  dev  enp0s3  proto  static  metric  1

路由表类型

Linux 中可以自定义 1~252 个路由表,其中系统自身维护了 4 个路由表:

[root@localhost ~]# cat /etc/iproute2/rt_tables
#
# reserved values
#
255	local
254	main
253	default
0	unspec
#
# local
#
#1	inr.ruhep
  • 0: 系统保留表。
  • 253 defulte table:没特别指定的默认路由都放在该表。
  • 254 main table:没指明路由表的所有路由都放在该表。
  • 255 locale table:保存本地接口地址,广播地址、NAT 地址。该由系统维护,用户不得更改。

查看指定的路由表项目:

ip route list table table_number

e.g.

[root@localhost ~]# ip route list table local

broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 172.18.22.0 dev br-ex proto kernel scope link src 172.18.22.200
local 172.18.22.1 dev br-ex proto kernel scope host src 172.18.22.200
local 172.18.22.200 dev br-ex proto kernel scope host src 172.18.22.200
broadcast 172.18.22.255 dev br-ex proto kernel scope link src 172.18.22.200
broadcast 192.168.0.0 dev o-hm0 proto kernel scope link src 192.168.0.96
local 192.168.0.96 dev o-hm0 proto kernel scope host src 192.168.0.96
broadcast 192.168.0.255 dev o-hm0 proto kernel scope link src 192.168.0.96
broadcast 192.168.122.0 dev virbr0 proto kernel scope link src 192.168.122.1
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1

添加默认路由

ip route add default via 172.18.22.1 dev br-ex

NOTE:当 Linux 上物理网卡(e.g. eth0)挂载到了 Linux Bridge(e.g. br-ex)上之后,默认路由的设备应该为 Bridge 设备,因为此时的物理网卡 IP 无效了。

添加静态路由

ip route add [目的网段] via [网关] dev [接口] [table <table_number>]

e.g. 目标网段为 10.15.150.0/24 的数据包通过接口 enp0s3 转发到网关 192.168.150.253。

ip route add 10.15.150.0/24 via 192.168.150.253 dev enp0s3

删除静态路由

ip route del [目标网段]

e.g.

ip route del 10.15.150.0/24