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 已被弃用,现在所有过滤都必须由路由过滤器完成。