Moving from ROSv6 to ROSv7

本页记录从 RouterOS v6 到 v7 的迁移,重点介绍关键变化,例如路由表限制提高、新的 /routing/table 和 /routing/rule 菜单、路由处理速度提升,以及策略路由的差异。文中包含配置自定义路由表、多 WAN 配置以及排查 mangle 规则冲突的示例。

从 ROSv6 迁移到 ROSv7

默认情况下,所有路由都与以前一样添加到 "main" 路由表。从配置角度看,最大的区别是路由表限制提高、路由表监控方式不同,以及如何将路由添加到特定路由表(见下一个示例)。 v7 引入了新菜单 /routing/route,它会显示所有地址族的路由以及所有被过滤的路由,并带有全部可能的 route 属性。/ip/route 和 /ipv6/route 菜单用于添加静态路由,为简单起见仅显示基本 route 属性。

有关路由的更深入信息,请参见这篇文章 (IP 路由。

另一个新变化是,最常见的 route print 请求由路由进程处理,与 v6 相比显著提高了速度。

路由表的使用与策略路由

与 v6 的主要区别在于,必须先将路由表添加到 /routing/table 菜单,然后才能在配置中的任何位置引用它。并且,如果打算让路由表将路由推送到 FIB,则应指定 fib 参数。 路由规则配置除菜单位置外相同(以前是 /ip route rule,现在是 /routing/rule)。

让我们考虑一个基本示例:我们希望在名为 myTable 的路由表中将 8.8.8.8 解析到网关 172.16.1.1:

/routing/table/add name=myTable fib
/routing/rule/add dst-address=8.8.8.8 action=lookup-only-in-table table=myTable
/ip/route/add dst-address=8.8.8.8 gateway=172.16.1.1@main routing-table=myTable

除了路由规则,你也可以像 ROSv6 中那样使用 mangle 通过 routing-mark 标记数据包。

当你使用 mangle 设置 routing-mark 时,请注意不要标记 "local" 流量。如果你的规则也标记本地流量,那么路由器的 IP 地址将无法访问,因为默认情况下 mangle 位于列表首位并覆盖本地查找:

[admin@CCR2004_2XS_111] /routing/rule> print
Flags: X - disabled, I - inactive; * - default
 0  * action=mangle

 1  * action=lookup vrf

 2  * action=unreachable vrf

 3  * action=lookup table=local

 4  * action=lookup table=main

例如,一个基本的多 WAN 配置:

/routing/table/add name=myTable fib
/ip/address
add address=192.168.1.1/24 interface=LAN
add address=1.1.1.2/24 interface=WAN1
add address=2.2.2.2/24 interface=WAN2
/ip/route
add gateway=1.1.1.1@main routing-table=myTable
add gateway=2.2.2.1
/ip/firewall/mangle/add in-interface=LAN action=mark-routing new-routing-mark=myTable

从 LAN 接口发出、目的地址为 192.168.1.1 的数据包会被 mangle 规则标记,并由 "myTable" 路由表处理。在该表中,到达 192.168.1.1 的唯一路由是默认路由,这意味着数据包将被转发到 1.1.1.1 网关。

有两种方法可以解决此问题:

  • 通过在 mangle 规则中添加 !dst-address-type=local 来排除 local 被标记。
  • 在 /routing/rule 菜单中,将第一条规则(action=mangle)移到(action=lookup table=local)之下。

使用哪种方法取决于配置的复杂程度。

下一跳查找

考虑一个来自 v6 的示例:

/ip/route/add dst-address=10.0.1.0/24 gateway=10.0.0.1
    scope=50 target-scope=30 comment=A
/ip/route/add dst-address=10.0.2.0/24 gateway=10.0.0.1
    scope=30 target-scope=20 comment=B
/ip/route/add dst-address=10.0.0.0/24 scope=20 gateway=WHATEVER
    comment=C

网关 10.0.0.1 通过 C 使用最小的引用 scope(路由 B 中的 scope 20)递归解析,并且两条路由都是活动的。现在我们同时更改 A 和 B:

/ip/route/set A target-scope=10

突然,对路由 A 应用更新会使路由 B 的网关变为非活动。这是因为在 v6 中每个地址只有一个网关对象。

v7 为每个地址保留多个网关对象,每个 scope 和网关检查的组合对应一个。

当更改某条路由的 target-scope 或网关检查时,ROS v7 不会影响其他路由,而 v6 则会。在 v7 中,target-scope 和网关检查是内部附加到网关、而非附加到路由的属性。

OSPF 配置

OSPFv3 和 OSPFv2 现在合并为单一菜单 /routing/ospf。在撰写本文时,没有默认实例和区域。 要同时启动 OSPFv2 和 OSPF v3 实例,首先需要为每个版本创建一个实例,然后为每个实例添加一个区域。

/routing/ospf/instance
add name=v2inst version=2 router-id=1.2.3.4
add name=v3inst version=3 router-id=1.2.3.4
/routing/ospf/area
add name=backbone_v2 area-id=0.0.0.0 instance=v2inst
add name=backbone_v3 area-id=0.0.0.0 instance=v3inst

此时,你已准备好网络接口上启动 OSPF。对于 IPv6,你可以添加想要运行 OSPF 的接口(与 ROSv6 相同)或 IPv6 网络。在后一种情况下,OSPF 将自动检测接口。以下是一些接口配置示例:

/routing/ospf/interface-template
add network=192.168.0.0/24 area=backbone_v2
add network=2001:db8::/64 area=backbone_v3
add network=ether1 area=backbone_v3

ROSv7 使用模板将接口与模板匹配,并应用匹配模板中的配置。OSPF 的 interface 和 neighbor 菜单包含只读条目,仅用于状态监控。

RouterOS 允许直接通过路由过滤器控制路由的重分发,无需 redistribute 参数。这为你希望重分发哪些协议中的哪些路由提供了更大的灵活性。 例如,假设你只想重分发来自 192.168.0.0/16 网络范围的静态 IPv4 路由。

选项 1:

/routing/ospf/instance
set v2inst out-filter-chain=ospf_out redistribute=static
/routing/filter/rule/add chain=ospf_out rule="if (dst in 192.168.0.0/16) {accept}"

选项 2:

/routing/filter/rule/add chain=ospf_out rule="if (protocol static && dst in 192.168.0.0/16) {accept}"

警告

路由过滤链的默认操作是 "reject"

BGP 配置

与 ROSv6 相比,BGP 配置进行了彻底重新设计。第一个也是最大的区别是,不再有 instance 和 peer 配置菜单。取而代之的是 connection、template 和 session 菜单。 这种结构的目的是严格区分负责连接的参数和 BGP 协议特定的参数。

我们从 Template 开始。它包含所有 BGP 协议相关的配置选项。它可以用作动态 peer 的模板,也可以将相似的配置应用于一组 peer。请注意,这与 Cisco 设备上的 peer group 不同,后者中的组不只是公共配置。

默认情况下有一个 default 模板,需要你设置自己的 AS。

/routing/bgp/template/set default as=65533

信息

从 v7.1beta4 开始,模板参数暴露在 "connection" 配置中。这意味着模板不再是必需的,从而可以更轻松地完成基本 BGP 连接设置,与 ROSv6 中的情况类似。 大多数参数与 ROSv6 类似,只是有些被分组到 output 和 input 部分,使配置更易读,也更容易理解该选项是应用于输入还是输出。如果你熟悉 CapsMan,那么语法是相同的,例如,要指定输出选择链,可以设置 output.filter-chain=myBgpChain。

你甚至可以从另一个模板继承模板参数,例如:

/routing/bgp/template
add name=myAsTemplate as=65500 output.filter-chain=myAsFilter
set default template=myAsTemplate

新路由配置的另一个重要方面是全局 Router ID,它设置 router-id 并将 peer 分组到一个实例中。RouterOS 会添加一个默认 ID,它从任意接口的最高 IP 中选取 instance-id。默认 BGP 模板默认设置为使用 "default" ID。 如果由于任何原因你需要调整或添加新实例,可以在 /routing/id 菜单中完成。

非常有趣的参数是 input.affinity 和 output.affinity;它们允许控制活动会话的输入和输出将在哪个进程中处理:

  • alone - 每个会话的输入和输出在各自的进程中处理,当有大量核心和大量 peer 时,这很可能是最佳选择。
  • afi, instance, vrf, remote-as - 尝试在具有相似参数的进程中运行新会话的输入/输出。
  • main - 在主进程中运行输入/输出(在单核上甚至可能提升性能,在核心数量较少的多核设备上也可能如此)。
  • input - 在与输入相同的进程中运行输出(只能为 output affinity 设置)。

现在我们已经为模板设置好参数,可以添加 BGP 连接了。最小的参数集是 remote.address、template, connect、listen 和 local.role

connect 和 listen 参数指定 peer 是尝试连接并监听远程地址,还是只连接或只监听。在某些配置中,如果 peer 使用多跳连接,还必须配置 local.address(正如 ROSv6 中的 update-source)。

警告

远程 AS 号不是必须指定的。ROS v7 可以从 open 消息中确定远程 ASN。仅当你想要接受来自该特定 AS 的连接时,才需要指定远程 AS。 Peer role 现在是必需参数。对于基本配置,你只需使用 ibgp、ebgp(有关可用 role 的更多信息,请参见相应的 RFC draft)。请记住,目前该草案中描述的能力、团体和过滤尚未实现。

非常基础的 iBGP 配置,监听整个本地网络以接受连接:

/routing/bgp/connection
add remote.address=10.155.101.0/24 listen=yes template=default local.role=ibgp

现在你可以从 /routing/bgp/session 菜单监控所有已连接和已断开 peer 的状态。

所有路由进程的其他有用的调试信息可以从 /routing/stats 菜单监控

[admin@v7_ccr_bgp] /routing/stats/process> print interval=1
Columns: TASKS, PRIVATE-MEM-BLOCKS, SHARED-MEM-BLOCKS, PSS, RSS, VMS, RETIRED, ID, PID, RPID, PROCESS-TIME, KERNEL-TIME, CUR-B>
# TASKS PRIVATE-M SHARED-ME PSS RSS VMS RET ID PID R PROCESS-TI KERN>
0 routing tables 12.2MiB 20.0MiB 18.7MiB 42.2MiB 83.4MiB 8 main 319 0 19s750ms 8s50>
rib >
connected networks >
1 fib 512.0KiB 0 7.4MiB 30.9MiB 83.4MiB fib 384 1 5s160ms 22s5>
2 ospf 1024.0KiB 1024.0KiB 5.9MiB 25.9MiB 83.4MiB 382 ospf 388 1 1m42s170ms 1m31>
connected networks >
3 fantasy 512.0KiB 0 2061.0KiB 5.9MiB 83.4MiB fantasy 389 1 1s410ms 870m>
4 configuration and reporting 40.0MiB 512.0KiB 45.0MiB 64.8MiB 83.4MiB static 390 1 12s550ms 1s17>
5 rip 768.0KiB 0 5.3MiB 24.7MiB 83.4MiB rip 387 1 1s380ms 1s20>
connected networks >
6 /routing/policy/configuration 512.0KiB 256.0KiB 2189.0KiB 6.0MiB 83.4MiB policy 385 1 1s540ms 1s20>
7 BGP service 768.0KiB 0 2445.0KiB 6.2MiB 83.4MiB bgp 386 1 6s170ms 9s38>
8 BGP Input 10.155.101.217 8.8MiB 6.0MiB 15.6MiB 38.5MiB 83.4MiB 20 21338 1 25s170ms 3s23>
BGP Output 10.155.101.217 >
9 Global memory 256.0KiB global 0 0 >
-- [Q quit|D dump|C-z pause|right]

路由过滤与 ROSv6 略有不同。在 BGP 模板中,你现在可以指定 output.filter-chain、output.filter-select、input.filter 以及若干 input.accept-* 选项。

现在 input.accept-* 允许在传入消息被解析并存储到内存之前直接对其进行过滤,从而显著减少内存占用。常规 input 过滤链只能拒绝前缀,这意味着它仍会占用内存,并会在 /routing/route 表中显示为 "not active, filtered"。

一个非常基础的 BGP 输入过滤示例:接受来自 192.168.0.0/16 子网的前缀且不修改任何属性。对于其他前缀,将接收到的 local pref 值减 1,并将 IGP metric 设置为 OSPF ext 中的值。此外,我们将只接受地址列表中的特定前缀以减少内存占用。

/ip/firewall/address-list
add list=bgp_list address=192.168.1.0/24
add list=bgp_list address=192.168.0.0/24
add list=bgp_list address=172.16.0.0/24

/routing/bgp/template
set default input.filter=bgp_in .accept-nlri=bgp_list

/routing/filter/rule
add chain=bgp_in rule="if (dst in 192.168.0.0/16) {accept}"
add chain=bgp_in rule="set bgp-local-pref -1; set bgp-igp-metric ospf-ext-metric; accept"

危险

如果未指定路由过滤链,BGP 将尝试通告它在路由表中能找到的每条活动路由 信息

路由过滤链的默认操作是 reject。

监控通告

RouterOS v7 默认禁用对 BGP 输出的监控。这可以在路由表很大的配置中显著减少资源占用。

要能够看到输出通告,应采取以下几个步骤:

  • 在 BGP 连接配置中启用 "output.keep-sent-attributes"。
  • 从 BGP session 菜单运行 "dump-saved-advertisements"。
  • 从 /routing/stats/pcap 菜单查看已保存的输出。
[admin@arm-bgp] /routing/bgp/connection>  set 0 output.keep-sent-attributes=yes
[admin@arm-bgp] /routing/bgp/session> print
Flags: E - established
 0 E remote.address=10.155.101.183 .as=444 .id=192.168.44.2 .refused-cap-opt=no .capabilities=mp,rr,gr,as4
     .afi=ip,ipv6 .messages=4 .bytes=219 .eor=""
     local.address=10.155.101.186 .as=456 .id=10.155.255.186 .capabilities=mp,rr,gr,as4 .afi=ip,ipv6
     .messages=1 .bytes=19 .eor=""
     output.procid=66 .filter-chain=bgp_out .network=bgp-nets .keep-sent-attributes=yes
     input.procid=66 ebgp
     hold-time=3m keepalive-time=1m uptime=4s30ms

[admin@arm-bgp] /routing/bgp/session> dump-saved-advertisements 0 save-to=test_out.pcap

网络

最后,你可能会注意到 network 菜单不见了,并且可能想知道如何通告你自己的网络。现在网络被添加到防火墙 address-list 中,并在 BGP 配置中引用。 以下是 ROSv6 的网络配置:

/routing bgp network add network=192.168.0.0/24 synchronize=yes
/ip route add dst-address=192.168.0.0/24 type=blackhole

在 v7 中应转换为:

/ip/firewall/address-list
add list=bgp-networks address=192.168.0.0/24

/ip/route
add dst-address=192.168.0.0/24 blackhole

/routing/bgp/connection
set peer_name output.network=bgp-networks

也可以为每个 BGP 网络自动创建一条 blackhole 路由:

/routing/bgp/connection
set peer_name output.network-blackhole=yes

只添加一个网络时需要做更多配置,但当需要处理大量网络时,它更为简洁。v7 甚至允许为每个 BGP 连接指定自己的一组网络。

警告

在 v7 中无法关闭与 IGP 路由的同步(只有当路由表中存在相应的 IGP 路由时,该网络才会被通告)。

路由过滤器

从 ROSv7.1beta4 开始,路由过滤器配置改为类似脚本的配置。规则现在可以使用 "if .. then" 语法,根据 "if" 语句中的条件来设置参数或应用操作。

多个没有 action 的规则会堆叠为一条规则,并像防火墙一样按顺序执行,原因是 "set" 参数的顺序很重要,而每行写一个 "set" 可以让人从上到下更容易理解应用了哪些操作。

例如,匹配静态默认路由并应用 accept 操作可以写在一个配置规则中:

/routing/filter/rule
add chain=ospf_in rule="if (dst==0.0.0.0/0 && protocol static) { accept }"

例如,ROSv6 规则 /routing/filter/add chain=ospf_in prefix=172.16.0.0/16 prefix-length=24 protocol=static action=accept 转换为 ROSv7 后为:

/routing/filter/rule
add chain=ospf_in rule="if (dst in 172.16.0.0/16 && dst-len==24 && protocol static) { accept }"

另一个示例是匹配 172.16.0.0/16 范围中前缀长度等于 24 的前缀,并设置 BGP med 和 prepend 值

/routing/filter/rule
add chain=BGP_OUT rule="if (dst-len==24 && dst in 172.16.0.0/16) { \n
    set bgp-med 20; set bgp-path-prepend 2; accept }"

也可以像这样匹配前缀长度范围

/routing/filter/rule
add chain=BGP_OUT rule="if (dst-len>13 && dst-len<31 && dst in 172.16.0.0/16) { accept }"

现在可以使用过滤规则从团体列表中匹配或设置 communities、large communities 和 extended communities:

/routing/filter/rule
add chain=bgp_in rule="set bgp-large-communities 200001:200001:10 "

如果需要将大量团体集应用于多条规则,则可以定义团体集,并用它们来匹配或设置:

/routing/filter/large-community-set
add set=myLargeComSet communities=200001:200001:10

/routing/filter/rule
add chain=bgp_in rule="append bgp-large-communities myLargeComSet "

由于 route-target 编码在 extended community 属性中,要更改或匹配 RT,你需要操作 extended community 属性,例如:

/routing/filter/rule
add chain=bgp_in rule="set bgp-ext-communities rt:327824:20 "

RPKI

RouterOS 实现了 RTR 客户端。你连接到服务器,服务器会发送路由有效性信息。然后可以使用该信息,通过 "rpki-validate" 在路由过滤器中针对某个组验证路由,并且在过滤器中还可以使用 "match-rpki" 来匹配确切状态。

更多信息请参阅 RPKI 文档。

RIP 配置

要启动 RIP,应先配置实例。你可以在其中选择哪些路由将由 RIP 重分发,以及是否重分发默认路由。

/routing/rip/instance
add name=instance1 originate-default=never redistribute=connected,static

然后应配置 interface-template。在 ROS 版本 7 中不需要像版本 6 那样定义网络。

/routing/rip/interface-template
add interfaces=ether1 instance=instance1

现在一台路由器上的基本配置已完成。RIP 邻居路由器应以类似方式配置。

在 ROS v7 中,只有当有路由需要发送和/或接收时,邻居才会出现。

ROSv6 中的 prefix list 已被弃用,现在所有过滤都必须由路由过滤器完成。