4、基于AS路径的过滤:AS_PATH Filter配置、正则表达式匹配AS_PATH、实战案例:拒绝来自特定AS的路由
好,咱们继续往下聊。上一节我们讲了前缀列表,那是基于路由的前缀信息做过滤。但很多时候,我们关心的不是路由长什么样,而是这条路由是从哪儿来的。说白了,就是它的“出身”——AS路径。
我经常跟团队里的新人说,AS_PATH是BGP路由的“身份证”。你只要会读这张身份证,就能知道这条路由经历了哪些AS,有没有绕路,是不是从某个你不信任的地方来的。今天我们就专门聊聊怎么基于AS_PATH做过滤。
核心要点:AS_PATH Filter 配合正则表达式,可以精确匹配路由的传播路径。这是BGP策略控制中最灵活、也最考验功底的手段之一。
4.1 为什么需要AS_PATH过滤?
先问个问题:你愿意接收一个来自竞争对手AS的路由吗?或者,你愿意让某个已知有路由劫持历史的AS的路由进入你的网络吗?
答案显然是否定的。但BGP本身不会帮你做这个判断。它只会老老实实地把路由传给你,至于你收不收,那是你的事。
我记得有一次,帮一个客户排查网络问题。他们的出口带宽经常被莫名其妙地占满,查了很久才发现,是某个上游运营商把一条来自某小型ISP的默认路由传了过来。那个ISP的AS号我们根本不认识,但因为没有做AS_PATH过滤,这条路由就这么大摇大摆地进来了。后来我们加了一条过滤规则,世界清净了。
所以,AS_PATH过滤的核心场景就两个:
- 拒绝特定AS的路由:比如你不信任AS 65001,那就直接把它拦在外面。
- 控制路由优先级:比如你希望优先走AS_PATH更短的路径,或者拒绝经过某些中转AS的路由。
4.2 AS_PATH Filter 的基本配置
在华为设备上,AS_PATH Filter的配置其实不复杂。它本质上是一个编号规则,里面定义了一组正则表达式。然后你在BGP视图下调用这个规则。
先看一个最简单的例子:拒绝所有来自AS 65001的路由。
# 第一步:定义AS路径过滤规则
ip as-path-filter 1 deny ^65001_
# 第二步:在BGP视图下应用
bgp 100
peer 10.0.0.2 as-path-filter 1 import
这里解释一下:^65001_ 这个正则表达式的意思是:匹配以“65001”开头,后面跟一个空格或行尾的AS_PATH。说白了,就是这条路由的第一个AS(也就是起源AS)是65001。
嗯,这里要注意:_ 在BGP正则里是个特殊符号,它代表“空格、行首、行尾或逗号”。你可以把它理解成一个万能的分隔符。
4.3 正则表达式匹配AS_PATH——这才是重头戏
正则表达式是AS_PATH过滤的灵魂。我见过不少工程师,配置命令背得滚瓜烂熟,但一到写正则就抓瞎。其实没那么可怕,你只要掌握几个核心符号就够了。
| 符号 | 含义 | 示例 | 匹配结果 |
|---|---|---|---|
^ |
匹配行首 | ^65001 |
AS_PATH以65001开头 |
$ |
匹配行尾 | 65001$ |
AS_PATH以65001结尾 |
_ |
匹配分隔符(空格、逗号、行首、行尾) | _65001_ |
AS_PATH中包含65001 |
. |
匹配任意单个字符 | 6500. |
匹配65000-65009 |
* |
匹配前面的字符0次或多次 | 6500.* |
匹配6500开头的任意AS |
+ |
匹配前面的字符1次或多次 | 6500+ |
匹配6500、65000等 |
| |
逻辑或 | 65001|65002 |
匹配65001或65002 |
[] |
字符集 | 6500[1-3] |
匹配65001、65002、65003 |
有了这张表,大部分场景你都能应付了。我个人的习惯是,先在脑子里把AS_PATH写出来,比如 100 200 300,然后想清楚我要匹配哪个位置,再动手写正则。
小技巧:在华为设备上,你可以用 display bgp routing-table regular-expression ^65001_ 来测试你的正则表达式是否写对了。这个命令会直接显示所有匹配的路由,非常方便。
4.4 实战案例:拒绝来自特定AS的路由
好了,理论说完了,咱们来一个完整的实战案例。假设场景是这样的:
- 你的AS是AS 100
- 你对端EBGP邻居是AS 200,IP是10.0.12.2
- 你发现AS 65001经常发布一些不稳定的路由,你决定拒绝所有来自AS 65001的路由
注意,这里有个坑:AS 65001可能直接是你的邻居,也可能是经过多跳传过来的。所以我们的过滤要覆盖两种情况。
配置如下:
# 定义AS路径过滤规则
# 拒绝起源AS为65001的路由
ip as-path-filter 10 deny ^65001_
# 拒绝AS_PATH中包含65001的路由(经过的也算)
ip as-path-filter 20 deny _65001_
# 允许所有其他路由
ip as-path-filter 10 permit .*
ip as-path-filter 20 permit .*
# 在BGP视图下应用
bgp 100
peer 10.0.12.2 as-path-filter 10 import
peer 10.0.12.2 as-path-filter 20 import
这里我用了两个filter,为什么?因为 ^65001_ 只匹配起源AS,而 _65001_ 匹配路径中任意位置的AS。两个都加上,双重保险。
我曾经遇到过一个问题:只写了 ^65001_,结果AS 65001的路由通过AS 300中转了一下,变成了 300 65001,就没被拦住。后来加上 _65001_ 才彻底解决。你想想看,这种坑是不是很隐蔽?
警告:使用 _65001_ 时要小心。如果你的AS_PATH中有类似 650010 这样的AS号,它也会被匹配到,因为 _65001_ 匹配的是子串。建议在AS号前后加上明确的分隔符,或者使用更精确的写法,比如 _65001_ 其实已经包含了分隔符,但如果你要匹配精确的AS号,可以用 ^65001$|_65001_ 这种组合。
4.5 用SVG梳理一下核心逻辑
说了这么多,我画了一张图,帮你把AS_PATH过滤的整个流程串起来。从路由进入,到正则匹配,再到最终的动作,一目了然。
这张图其实就讲了三件事:路由来了,我们看它的AS_PATH,然后用正则去比对。比对上了就拒绝,没比对上就放行。简单吧?但就是这简单的逻辑,能解决很多复杂的问题。
4.6 几个容易踩的坑
最后,我把自己这些年踩过的坑总结一下,你遇到了可以少走弯路:
- 正则写得太宽泛:比如用
.*65001.*,结果把AS 650010也给拦了。记住,_是你的好朋友。 - 忘记加permit规则:AS_PATH Filter默认是隐式拒绝的。如果你只写了deny,没写permit .*,那所有路由都会被拒绝。我刚开始学的时候犯过这个错,结果BGP邻居一建立,路由全没了,吓出一身冷汗。
- 在错误的视图下应用:import和export方向别搞反了。import是过滤从邻居收到的路由,export是过滤发给邻居的路由。搞反了的话,你本来想拦别人的路由,结果把自己的路由拦住了。
- 忽略AS_SET的情况:在某些聚合场景下,AS_PATH里会出现AS_SET,用大括号括起来,比如
{65001 65002}。这时候正则要写成_{65001 65002}_才能匹配。这个比较少见,但遇到了会很头疼。
好了,关于AS_PATH过滤,今天就聊到这儿。你只要把正则的几个核心符号记住,再配合实战多练练,很快就能上手。这东西说白了就是个熟能生巧的活儿。
公众号:蓝海资料掘金营,微信deep3321