34.2.网关和路由 =============== *路由* 是允许一个系统查找到另一个系统的网络路径的机制。\ *路由* 是一对定义的地址,表示“目标”和“网关”。路由指示在尝试到达指定目标时,通过指定的网关发送数据包。有三种类型的目标:单个主机、子网和“默认”。如果没有其他路由适用,则使用“默认路由”。还有三种类型的网关:单个主机、接口(也称为链路)和以太网硬件地址(MAC)。已知路由存储在路由表中。 本节提供路由基础知识的概述。然后,它演示了如何将 FreeBSD 系统配置为路由器,并提供了一些故障排除技巧。 34.2.1.路由基础 --------------- 要查看 FreeBSD 系统的路由表,请使用 `netstat(1) `__\ : .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % 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`` 字段被设置为与互联网直接连接的系统。读取这个条目时,要确认 ``Flags`` 栏中显示网关是可用的(UG)。 一台本身作为通往外部世界的网关的机器,其默认路由将是互联网服务提供商(ISP)的网关机器。 - **localhost** 第二条路由是 ``localhost`` 路由。在 ``Netif`` 栏中为 ``localhost`` 指定的接口是 **lo0**\ ,也被称为回环设备。这表明这个目的地的所有流量都应该是内部的,而不是通过网络发送出去。 - **MAC address** 以 ``0:e0:`` 开头的地址是 MAC 地址。FreeBSD 会自动识别本地以太网上的任何主机,即本例中的 ``test0``\ ,并通过以太网接口 **re0** 为该主机添加一条路由。这种类型的路由有一个超时时间,在 ``Expire`` 一栏中可以看到,如果主机在特定的时间内没有回应,就会使用这个路由。当这种情况发生时,到这个主机的路由将被自动删除。这些主机是使用路由信息协议(RIP)确定的,它根据最短路径确定计算到本地主机的路由。 - **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`` 属性。\ `常见的路由表标志 `__ 总结了其中一些标志及其含义: **表 29. 经常看到的路由表标志** ==== ====================================================================== 标志 意义 ==== ====================================================================== U 路由处于活动状态(up)。 H 路由目标是单个主机。 G 将此目标的任何内容发送到此网关,该网关将从那里确定将其发送到何处。 S 此路由是静态配置的。 C 基于此路由克隆新路由,供计算机连接到。这种类型的路由通常用于本地网络。 W 路由是根据局域网(克隆)路由自动配置的。 L 路由涉及对以太网(链路)硬件的引用。 ==== ====================================================================== 在 FreeBSD 系统上,可以通过指定默认网关的 IP 地址在 **/etc/rc.conf** 中定义默认路由: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session defaultrouter="10.20.30.1" 也可以使用以 ``route`` 手动添加路由: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # route add default 10.20.30.1 请注意,手动添加的路由将无法在重新启动后继续运行。有关手动操作网络路由表的详细信息,请参阅 `route(8) `__\ 。 34.2.2.使用静态路由配置路由器 ----------------------------- FreeBSD 系统可以配置为网络的默认网关或路由器,如果它是双宿主系统。双宿主系统是驻留在至少两个不同网络上的主机。通常,每个网络都连接到一个单独的网络接口,但 IP 别名可用于将多个地址(每个地址位于不同的子网上)绑定到一个物理接口。 为了让系统在接口之间转发数据包,必须配置 FreeBSD 为路由器。互联网标准和良好的工程实践会阻止 FreeBSD 项目默认启用此功能,但是可以通过将此行添加到 **/etc/rc.conf** 来将其配置为在引导时启动: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session 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。可以使用软件包或 port 安装 `net/quagga `__ 以支持 BGP 和 OSPF 路由协议。 请思考以下网络: .. figure:: .././img/assets/static-routes.png 静态路由 在这种情况下,\ ``RouterA`` 是一台 FreeBSD 机器,它作为一个路由器连接到互联网的其他地方。它的默认路由设置为 ``10.0.0.1``\ ,允许它与外部世界连接。\ ``RouterB`` 已经配置为使用 ``192.168.1.1`` 作为默认网关。 在添加任何静态路由之前,\ ``RouterA`` 的路由表看起来是这样的: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % 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`` 没有通往 ``192.168.2.0/24`` 网络的路由。下面的命令使用 ``192.168.1.2`` 作为下一跳,将 ``Internal Net 2`` 网络添加到 ``RouterA`` 的路由表中: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # route add -net 192.168.2.0/24 192.168.1.2 现在,\ ``RouterA`` 可以到达 ``192.168.2.0/24`` 网络上的任何主机。然而,如果 FreeBSD 系统重新启动,路由信息将不会持续存在。如果静态路由需要持久化,请将其添加到 **/etc/rc.conf** 中。 .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # 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/24`` 和 ``192.168.1.0/24`` 网络添加静态路由的例子。 .. raw:: latex \diilbookstyleinputcell .. code:: shell-session 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" 34.2.3.故障排除 --------------- 当一个地址空间被分配给一个网络时,服务运营商就会配置他们的路由表,这样网络的所有流量就会被发送到网站的链接上。但是,外部站点如何知道将其数据包发送到网络的 ISP? 有一个系统跟踪所有分配的地址空间,并定义它们与互联网骨干网的连接点,或在全国和世界各地传输互联网流量的主干线。每台骨干机都有一套主表的副本,将特定网络的流量导向特定的骨干运营商,并从那里沿着服务运营商的链条向下延伸,直到到达特定网络。 服务运营商的任务是向骨干站点宣传他们是连接点,因此是一个站点的向内路径。这就是所谓的路由传播。 有时,路由传播有问题,一些站点无法连接。也许最有用的命令是 ``traceroute``\ ,它能试图找出路由中断的地方。它在 ``ping`` 失败时很有用。 当使用 ``traceroute`` 时,包括要连接的远程主机的地址。输出将显示尝试路径上的网关主机,最终要么到达目标主机,要么因为缺乏连接而终止。更多信息,请参考 `traceroute(8) `__\ 。 34.2.4.多播的注意事项 --------------------- FreeBSD 原生支持多播应用程序和多播路由。多播应用程序不需要任何特殊配置即可在 FreeBSD 上运行。对多播路由的支持要求将以下选项编译到定制内核中: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session options MROUTING 多播路由守护程序 mrouted 可以使用软件包或 port `net/mrouted `__ 进行安装。此守护程序实现 DVMRP 多播路由协议,并通过编辑 **/usr/local/etc/mrouted.conf** 进行配置,以便设置隧道和 DVMRP。安装 mrouted 还会安装 map-mbone 和 mrinfo,以及它们相关的手册页。有关配置示例,请参阅这些内容。 **注意** 在许多多播安装中,DVMRP 已在很大程度上被 PIM 协议所取代。有关详细信息,请参阅 `pim(4) `__\ 。