BIRD3.0手册(一)介绍与架构

本系列日志对BIRD3.0用户手册进行中文化,旨在自学及便利他人对BIRD的使用。需要注意的是,相比官方文档,内容做了个人觉得必要的精简。

1.介绍

1.1 什么是BIRD

BIRD这个名字实际上是BIRD Internet Routing Daemon(BIRD互联网路由守护进程)的首字母缩写。
(译者按:这种“递归缩略词”构词法,类似的还有GNU、WINE)

BIRD是一款互联网路由守护进程,用来支持当今互联网中使用或计划在不久的将来使用的所有路由技术,并拥有一个清晰、可扩展的架构,可以轻松地集成新的路由协议。
BIRD支持包括但不限于下列特性:

  • 支持IPv4和IPv6协议
  • 多路由表
  • 边界网关协议(BGPv4)
  • 路由信息协议(RIPv2,RIPng)
  • 开放最短路径优先协议(OSPFv2,OSPFv3)
  • Babel路由协议
  • IPv6主机路由通告
  • 在单个主机上不同路由表之间交换路由的虚拟协议
  • 能在线控制和检查守护进程状态的CLI
  • 柔性重配置
  • 一种路由过滤的强大语言

BIRD采用GPL分发。

1.2 安装BIRD

在较新的装有GNU开发工具(GCC、binutils、m4、make)及Perl的类UNIX系统上,可以如下这样简单安装BIRD:

1
2
3
4
5
./configure
make
make install
vi /usr/local/etc/bird.conf
bird

可以使用./configure --help来获取配置选项列表,其中最重要的选项是--with-protocols=用于排除不使用的路由协议来生成稍小一些的BIRD可执行文件,以及--prefix=用来将BIRD安装到/usr/local以外的位置。
(译者按:实际上很多linux发行版的软件源中是含有BIRD的,可以使用如sudo apt install bird3直接安装)

1.3 运行BIRD

你可以向bird传入若干命令行选项:

-c 配置名
  使用给定的配置文件来替代prefix/etc/bird.conf
-d
  输出调试信息到stderr,并在前台运行bird
-D 调试日志文件名
  输出调试信息到指定文件
-f
  前台运行bird
-g group
  使用组ID,详见下一节
-h, –help
  显示bird命令行选项
-l
  在当前工作目录而非默认系统位置读取配置文件和通信socket。但由-c,-s指定的路径有更高优先级
-p
  只校验配置文件并退出。当配置文件有效时返回0
-P PID文件名
  使用给定的文件名创建一个PID文件
-R
  启动后进行优雅重启恢复
-s 通信socket名
  使用给定的socket文件名与客户端通信,默认是prefix/var/run/bird.ctl
-u user
  丢弃特权而使用用户ID,详见下一节
–version
  显示bird版本
BIRD根据配置将其工作日志记入日志文件或syslog。

1.4 特权

作为守护进程,BIRD会使用一些特权操作(如设置路由表和使用原始socket)。
传统上BIRD以root权限执行运行,这可能会引发安全问题。推荐的方式是使用权限限制(通过-u-g选项)。该情况下,BIRD虽然以root权限执行,但会将其用户和组ID更改为非特权ID,同时利用Linux capabilities机制(CAP_NET_* capabilities)仅保留所需的权限。需注意控制socket是在特权被丢弃前创建的,配置文件在之后才读取。该权限限制功能在BIRD的BSD移植版中并未实现。
建议使用新建的专用用户账户作为非特权用户,组的选项也类似,但同一组中的用户可以使用birdc来控制BIRD。
最后,也可以使用外部工具在权限首先环境中运行BIRD,这可能需要些配置,给予BIRD标准库、读取配置文件和创建控制套接字的权限,以及CAP_NET_* capabilities。

2.架构

2.1 路由表

BIRD的核心是路由表。BIRD有多个独立的路由表,每个只包含一种网络类型(nettype 见后文)的路由。有两个默认的路由表:master4用于IPv4路由,master6用于IPv6路由。其他的路由表则必须被显式配置。
这些路由表并不是内核的转发表。BIRD本身不执行任何转发。如果想要使用BIRD路由表中的路由来转发数据包,可以使用Kernel协议(见下文)来将它们与内核FIB(译者按:转发信息库)进行同步。
每种nettype都为路由定义了一种主键。每个路由源都可以为每个可能的主键提供一个路由;新路由通告会替换掉来自同一源的旧路由,而其他路由保持不变。BIRD总是从已知路由中为每个主键选择一条最佳路由,并将其余路由作为次优保留。当最佳路由被撤销时,BIRD会重新运行最佳路由选择算法来找出当前最佳路由。
全局最佳路由选择算法大致如下:

  1. 比较路由的偏好值(preference)
  2. 比较源协议实例的偏好值
  3. 如果源协议相同(例如都是BGP),则调用该协议自身的路由选择算法
  4. 如果源协议不同(例如BGP和OSPF),则算法结果为未定义

通常,路由表只是从整个网络的条目列表中选择一条路由。可选地,这些条目列表可以保持完全排序(根据偏好值或某些协议相关的度量)。详见3.3中sorted表选项。

2.2 路由和网络类型

BIRD处理多种类型路由。其中一些是典型的IP路由,另一些更适合描述为转发规则。不管这个差异我们都统称为路由。
每条路由由一些属性组成(更多详见5.5路由属性一节),所有路由共有的属性是:

  • 告知我们该路由的路由器IP地址
  • 源协议实例
  • 路由偏好值
  • 协议定义的可选属性

其他属性则取决于网络类型。其中一些是主键的一部分,用🔑标记。
IPv4和IPv6路由
传统路由,配置关键字是ipv4ipv6

  • 🔑路由目的地(带长度的IP前缀)
  • 路由下一跳(见下文)

IPv6源特定路由
同时包含目的前缀和源前缀的IPv6路由。用于源特定路由(SSR),也称为源地址依赖路由(SADR),参阅RFC8043。目前主要限于Babel协议。配置关键字是ipv6 sadr

  • 🔑路由目的地(带长度IP前缀)
  • 🔑路由源(带长度IP前缀)
  • 路由下一跳(见下文)

VPN IPv4和IPv6路由
带有VPN路由甄别符(参见RFC4364)的IPv4和IPv6路由。配置关键字是vpn4vpn6

  • 🔑路由目的地(带长度IP前缀)
  • 🔑路由区分符(依据RFC4364
  • 路由下一跳

IPv4和IPv6的路由源授权(ROA)
这些条目可用于验证BGP路由的路由来源。一个ROA条目指定了可以由某个AS号码(ASN)发起的多个前缀。关键字是roa4roa6

  • 🔑带长度IP前缀
  • 🔑匹配前缀的最大长度
  • 🔑ASN

IPv4和IPv6的Flowspec
Flowspec规则是种防火墙和流量控制规则,主要通过BGP分发。这些规则可以帮助运营商在各种网络攻击耗尽全部带宽前将其扼杀在萌芽。配置关键字是flow4flow6

  • 🔑带长度IP前缀
  • 🔑流定义数据
  • 流动作(根据RFC5575内部编码为BGP community)

MPLS交换规则
MPLS路由控制MPLS转发,如果IP路由控制IP转发一样。支持MPLS的路由协议会同时生成带标签的IP路由和相应的MPLS路由。配置关键字是mpls

  • 🔑MPLS标签
  • 路由下一跳

路由下一跳
这本身不是一种网络类型。如前面所述,路由下一跳是许多网络类型共有的一个复杂属性。每个下一跳都有其分配的设备(可从其IP地址推断或显式设置)。它也可能有一个IP地址和MPLS标签栈(可独立拥有其中一个或两者皆有)。最大MPLS标签栈深度在编译时被设置为8个标签。
每条路由(当有资格拥有下一跳时)都可以有多个下一跳。这种情况下,每个下一跳也有自己的权重。

2.3 协议和通道(Protocols & channels)

BIRD协议(protocol)是路由的一个生产者消费者抽象类。每个协议都可以运行在多个实例中,其中一端通过通道(channel)绑定到路由,另一端则绑定到指定的监听套接字(如BGP)、接口(如Babel、OSPF、RIP)、API(如Kernel、Direct),或者不绑定任何东西(如Static、Pipe)。
此外还有两种没有任何通道的协议——BFD和Device。这两个都为其他协议提供服务。
每个协议都通过一个通道连接到一个路由表。一些协议(如OSPF、RIP)只支持一个通道。而一些协议(如BGP、Direct)则支持多个通道。每个通道都有两个过滤器(filter),可以用来接受、拒绝和修改路由。导出过滤器(export filter)用于从路由表中传递到协议的路由,而导入过滤器(import filter)则用于反方向的路由。

2.4 优雅重启(Graceful restart)

当BIRD在重启或崩溃后启动时,它会像全新启动一样,以一种不协调的方式重新填充路由表。在某些情况下,这可能不切实际,因为如果转发平面(即内核路由表)保持完好,那么它与BIRD的同步过程会在协议收敛之前暂时中断数据包的转发。
优雅重启是一种可以帮助解决此问题的机制。通常,它工作方式是:启动各个协议,让它们重新填充路由表,同时延迟路由的传播,直到协议确认它们已经收敛。请注意,优雅重启行为必须为所有相关协议进行配置,并且需要协议的特定支持(目前已在Kernel和BGP协议中实现)。它通过-R选项在特定启动时被激活。
一些协议(如BGP)可以在有意中断和崩溃后都进行优雅重启。而其他协议(如OSPF)则只能在有意中断后进行。对于计划内的优雅重启,BIRD必须通过graceful restart命令来关闭,而不是常规down命令。通过这种方式,路由邻居会受到计划内优雅重启的通知,并在BIRD关闭后,路由会保持在内核表中。

2.5 MPLS

多协议标签交换(MPLS)是一种网络技术,它工作在IP路由之下、链路层(如以太网)之上,具体描述见RFC3031
在常规IP转发中,数据包目的地址在每一跳都会被独立检查,路由表中最长前缀匹配的路由会被选中,然后数据包被相应处理。通常在IP转发方面,边界路由器和内部路由器之间没有区别。
但在MPLS转发中,当数据包进入网络时,会根据目的地址、入口接口和其他因素被分类到某个转发等价类(FEC)中,然后一个带有标识该FEC的MPLS标签的头部被附加到数据包上,数据包随之被转发。在内部路由器中,只检查MPLS标签,从MPLS路由表中选择匹配的MPLS路由,然后相应处理数据包。MPLS标签的具体值仅具有本地意义,并且可能在不同跳之间变化(此即为标签交换)。当数据包离开网络时,MPLS头部会被移除。
MPLS的优势在于,除了目的地址之外的其他因素可以被计入考虑,并在整个网络中得到一致的应用。例如,可以将具有多个重叠私有地址范围的IP流量混合在一起,或者为特定流量定义特定路径。另一个优势是,内部路由器的MPLS转发可以比IP转发简单得多,因为它使用更简单的精确匹配来进行MPLS路由选择,而不是最长前缀匹配算法。其缺点是信令方面增加了额外的复杂性。更多详见RFC3031
支持MPLS的路由协议不仅分发IP路由信息,也分发标签。因此,它们会生成带标签的路由,这些路由代表了贯穿MPLS域的标签交换路径(LSP)。这类路由像常规无标签路由一样,拥有IP前缀及下一跳地址,但还有个本地MPLS标签(在路由属性mpls_label中)和一个出站MPLS标签(作为下一跳的一部分)。它们被存储在常规IP路由表中。
带标签的路由用于在路由协议之间交换路由信息以及用于入口(IP->MPLS)转发,但它们不直接用于MPLS转发。取而代之的是,我们使用MPLS路由,这些路由以本地MPLS标签作为主键,并存储在MPLS路由表中。
在BIRD中整个过程通常是:一个支持MPLS的路由协议(如BGP)接收到包含远端标签的路由信息,它会生成一条带有mpls_policy属性的路由,该属性指定了期望的MPLS标签策略,这样的路由随后通过导入过滤器(该过滤器可以修改MPLS标签策略或分配一个静态标签),当它被接受时,一个本地MPLS标签会(根据标签策略)被选择出来并附加到该路由上,从而生成一条带有标签的路由。当一个新的MPLS标签被分配时,支持MPLS的协议会自动生成相应的MPLS路由。当所有使用特定本地MPLS标签的带标签的路由都被撤销时,相应的MPLS路由也会被撤销。
在BIRD中,MPLS有三个重要概念:MPLS域、MPLS表和MPLS通道。MPLS域代表一个独立的标签空间,所有支持MPLS的协议都与某个MPLS域相关联。它负责标签管理,处理来自支持MPLS的协议的标签分配请求。MPLS表就是用于存放MPLS路由的路由表。路由器通常有一个MPLS域和一个MPLS表,并通过内核(Kernel)协议将MPLS路由导出到内核FIB。
MPLS通道使协议能够支持MPLS,它们负责跟踪活跃的FEC(及相应分配的标签),为带标签的路由选择FEC和本地标签,并维护带标签的路由与MPLS路由之间的对应关系。
需注意,本地标签是分配给各个支持MPLS的协议的,因此无法在不同协议之间共享本地标签。

最后,一个图总结一下这部分核心内容