31.2. 网关和路由

Contributed by Coranth Gryphon.

要让网络上的两台计算机能够相互通讯, 就必须有一种能够描述如何从一台计算机到另一台计算机的机制, 这一机制称作 路由选择(routing)路由项 是一对预先定义的地址: 目的地(destination)网关(gateway)。 这个地址对所表达的意义是, 通过 网关 能够完成与 目的地 的通信。 有三种类型的目的地址: 单个主机、 子网、 以及 默认。 如果没有可用的其它路由, 就会使用 默认路由, 有关默认路由的内容, 将在稍后的章节中进行讨论。 网关也有三种类型: 单个主机, 网络接口 (也叫 链路 (links)) 和以太网硬件地址 (MAC 地址)。已知路由存储在路由表中。

本节概述了路由基础知识。然后演示如何将 FreeBSD 系统配置为路由器,并提供一些故障排除提示。

31.2.1. 路由基础概念

使用 netstat(1) 查看路由表:

% netstat -r
Routing tables

Internet:
Destination      Gateway            Flags     Refs     Use     Netif Expire
default          outside-gw         UGS        37      418       em0
localhost        localhost          UH          0      181       lo0
test0            0:e0:b5:36:cf:4f   UHLW        5    63288       re0     77
10.20.30.255     link#1             UHLW        1     2421
example.com      link#1             UC          0        0
host1            0:e0:a8:37:8:1e    UHLW        3     4601       lo0
host2            0:e0:a8:37:8:1e    UHLW        0        5       lo0 =>
host2.example.com link#1            UC          0        0
224              link#1             UC          0        0

此示例中的条目含义如下所示:

default

此表中的第一个路由指定default路由。当本地系统需要与远程主机建立连接时, 它会检查路由表以决定是否有已知的路径存在。 如果远程主机属于一个我们已知如何到达 (克隆的路由) 的子网内,那么系统会检查看沿着那个接口是否能够连接。

如果目标与路由表中的条目不匹配, 或者所有已知路径都失败, 则系统将使用默认路由的条目。对于局域网上的主机, 默认路由中的Gateway字段设置为直接连接到 Internet 的系统。读取此条目时, 请验证Flags列指示网关可用 (UG)。

如果您正为某台本身就做为网关连接外界的机子配置默认路由的话, 那么该默认路由应该是您的互联网服务商 (ISP)那方的网关机子。

localhost

这里的路由表中给出的用于 localhost 的接口 (Netif 列) 是 lo0, 也就是大家熟知的 回环设备。 它表示所有以此为 目的地 的通信都留在本机, 而不通过 LAN 发出, 因为这些流量最终会回到起点。

MAC address

接着出现的是以 0:e0: 开头的地址。这些是以太网硬件地址,也称为 MAC 地址。 FreeBSD 会自动识别在同一个以太网中的任何主机 (如 test0), 并为其新增一个路由, 并通过那个以太网接口 ── ed0 直接与它通讯 (译者注:那台主机)。与这类路由表相关的也有一个超时项 (Expire列),当我们在指定时间内没有收到从那个主机发来的信息, 这项就派上用场了。这种情况下,到这个主机的路由就会被自动删除。 这些主机被使用一种叫做RIP(路由信息协议--Routing Information Protocol)的机制所识别,这种机制利用基于最短路径选择 (shortest path determination)的办法计算出到本地主机的路由。

subnet

FreeBSD 也会为本地子网添加子网路由(10.20.30.255 是子网 10.20.30 的广播地址,而 example.com 是这个子网相联的域名)。 名称 link#1 代表主机上的第一块以太网卡。 您会发现,对于它们没有指定另外的接口。

这两个组(本地网络主机和本地子网)的路由是由守护进程 routed(8) 自动配置的。如果它没有运行, 那就只有被静态定义 (例如,明确输入的) 的路由才存在了。

host

host1 行代表我们的主机,它通过以太网地址来识别。 因为我们是发送端,FreeBSD知道使用回环接口 (lo0) 而不是通过以太网接口来进行发送。

两个 host2 行是我们使用 ifconfig(8) 别名 (请看关于以太网的那部分就会知道我们为什么这么做) 时产生的一个实例。在 lo0 接口之后的 => 符号表明我们不仅使用了回环 (因为这个地址也涉及了本地主机),而且明确指出它是个别名。 这类路由只有在支持别名的主机上才能显现出来。 所有本地网上的其它的主机对于这类路由只会简单拥有 link#1

224

最后一行 (目标子网224) 用于处理多播――它会覆盖到其它的区域。

最后,每个路由的不同属性可以在 Flags 列中看到。下边是个关于这些标志和它们的含义的一个简表:

表 31.1. 常见路由表标记
命令用途
UUp: 路由处于活动状态。
HHost: 路由目标是单个主机。
GGateway: 所有发到目的地的网络传到这一远程系统上, 并由它决定最后发到哪里。
SStatic: 这个路由是手工配置的,不是由系统自动生成的。
CClone: 生成一个新的路由, 通过这个路由我们可以连接上这些机子。 这种类型的路由通常用于本地网络。
WWasCloned: 指明一个路由――它是基于本地区域网络 (克隆) 路由自动配置的。
LLink: 路由涉及到了以太网硬件。

您可以通过 /etc/rc.conf 文件设定默认路由:

defaultrouter="10.20.30.1"

也可以直接在命令行使用 route(8)

# route add default 10.20.30.1

请注意,手动添加的路由将无法在重新启动后继续使用。要了解关于如何手工维护网络路由表的进一步细节, 请参考 route(8) 联机手册。

31.2.2. 设定路由器使用静态路由

Contributed by Al Hoang.

如果一个 FreeBSD 系统是一个双宿主系统, 则可以被配置为网络的默认网关或路由器。双宿主系统是指至少驻留在两个不同的网络上的主机。通常情况下, 每一个网络都连接到一个独立的网络接口上, 虽然可以使用 IP 别名来绑定多个地址, 每个地址都在不同的子网上, 并将其绑定到一个物理接口上。

网络路由器只是一个将数据包从一个接口转发到另一个接口的系统。 互联网标准和良好的工程实践阻止了 FreeBSD 计划在 FreeBSD 中把它置成默认值。您在可以在 rc.conf(5) 中改变下列变量的值为 YES,使这个功能生效:

gateway_enable="YES"          # Set to YES if this host will be a gateway

现在若需启用路由将sysctl(8) 变量――net.inet.ip.forwarding 设置成 1。如果您要临时地停止路由, 您可以把它重设为 0

路由器中的路由表需要有路由才知道将数据传向何处。路由可以手动添加(静态路由),也可以使用路由协议动态获取。静态路由适用于小型网络,本节介绍如何为小型网络添加静态路由。

注意:

对于大型网络而言,静态网络的扩展较为复杂。FreeBSD 附带标准BSD路由守护进程 routed(8),提供路由协议RIP、版本 1 和 2 以及IRDP。可以使用 package 或 ports 安装net/zebraBGPOSPF路由协议的支持。

请考虑以下网络:

在这个场景中,RouterA是一台FreeBSD机器,它作为一个路由器连接到Internet的其他部分。它的默认路由设置为 10.0.0.0.1, 这使得它可以与外部世界连接。RouterB已经被配置为使用192.168.1.1作为其默认网关。

在添加任何静态路由之前,RouterA上的路由表如下所示:

% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif  Expire
default            10.0.0.1           UGS         0    49378    xl0
127.0.0.1          127.0.0.1          UH          0        6    lo0
10.0.0.0/24        link#1             UC          0        0    xl0
192.168.1.0/24     link#2             UC          0        0    xl1

使用当前的路由表,RouterA 是不能到达我们的内网――Internal Net 2 的。它没有到 192.168.2.0/24 的路由。 一种可以接受的方法是手工增加这条路由。以下的命令会把 Internal Net 2 网络加入到 RouterA 的路由表中,使用192.168.1.2 做为下一个跳跃:

# route add -net 192.168.2.0/24 192.168.1.2

现在 RouterA 可以访问 192.168.2.0/24 网络上的主机。如果您重启系统,路由信息就会消失。 处理附加的静态路由的方法是把它放到 /etc/rc.conf

# Add Internal Net 2 as a persistent static route
static_routes="internalnet2"
route_internalnet2="-net 192.168.2.0/24 192.168.1.2"

配置变量 static_routes 是一串以空格隔开的字符串。每一串表示一个路由名字。变量route_internalnet2包含该路由名称的静态路由。

前边已经提到, 可以把多个静态路由的名称, 放到 static_routes 里边。 接着我们就来建立多个静态路由。 下面几行所展示的, 是在一个假想的路由器上增加 192.168.0.0/24192.168.1.0/24 之间静态路由的例子:

static_routes="net1 net2"
route_net1="-net 192.168.0.0/24 192.168.0.1"
route_net2="-net 192.168.1.0/24 192.168.1.1"

31.2.3. 故障排除

当您得到一个分配给您的网络的地址空间时, ISP(网络服务商)会设置它们的路由表, 这样指向您子网的数据就会通过 PPP 连接下传到您的网络。 但是其它跨越国界的网络是如何知道将数据传给您的 ISP 的呢?

有一个系统(很像分布式 DNS 信息系统), 它一直跟踪被分配的地址空间, 并说明它们连接到互联网骨干(Internet backbone)的点。 骨干(Backbone) 指的是负责全世界和跨国的传输的主要干线。 每一台骨干主机(backbone machine)有一份主要表集的副本, 它将发送给特定网络的数据导向相应的骨干载体上(backbone carrier), 从结点往下遍历服务提供商链,直到数据到达您的网络。

服务提供商的任务是向骨干网络广播,以声明它们就是通向您的网点的连接结点 (以及进入的路径)。这就是路由传播。

有时候,路由传播会有一个问题,一些网络无法与您连接。 或许能帮您找出路由是在哪里中断的最有用的命令就是 traceroute(8)了。当您无法与远程主机连接时, 这个命令一样有用(例如 ping(8) 失败)。

traceroute命令将以您想连接的主机的名字作为参数执行。 不管是到达了目标,还是因为没有连接而终止, 它都会显示所经过的所有网关主机。更多详细信息请参阅traceroute(8)

31.2.4. 多播路由

FreeBSD 一开始就支持多播应用软件和多播路由选择。 多播程序并不要求FreeBSD的任何特殊的配置, 就可以工作得很好。多播路由需要支持被编译入内核:

options MROUTING

可以从 package 或 ports 安装net/mrouted 多播路由守护进程mrouted。此守护进程实现DVMRP多播路由协议,并通过/usr/local/etc/mrouted.conf进行配置,以便设置隧道和DVMRPmrouted的安装还安装map-mbonemrinfo以及他们的关联人页。有关配置示例,请参阅这些示例。

注意:

在许多多播安装中,DVMRP在很大程度上已被PIM协议所取代。有关详细信息,请参阅pim(4)

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.