本页课程原文(点开阅读)

eBGP 跨自治系统路由

课程(6 节,按顺序学)

第 1 课 · BGP 是干什么的

入门 · 约 8 分钟

本课目标:先搞清楚 BGP 和 OSPF 根本不是一类东西,不然后面全是死记硬背。

OSPF 解决「怎么走最快」,BGP 解决「该不该走」

OSPF / ISIS 这类 IGP 关心的是最短路径,它假设整张网都是自己人,所有链路信息都往外泛洪。

BGP 面对的是完全不同的问题:互联网上有几万个自治系统(AS),分属不同公司,彼此不信任、有商业关系。这时候要解决的不是「哪条路最短」,而是「我愿不愿意帮你转发流量」、「我希望别人从哪个入口进来」。

所以 BGP 是路径矢量 + 策略协议:它不算最短路,它按一堆属性(AS_PATH / LOCAL_PREF / MED …)来做策略选路。

三个关键差异

① 邻居必须手工配。OSPF 发 Hello 自动发现邻居;BGP 要你一条条 peer 命令写出来,而且底层是一条 TCP 179 连接。拓扑上连着线 ≠ 有 BGP 邻居。

② BGP 自己不算路,完全依赖 IGP。BGP 只负责「这个前缀的下一跳是谁」,至于怎么走到那个下一跳,得靠 IGP。所以 下一跳不可达 = 路由无效。

③ 只传最优路由。BGP 对每个前缀只把自己选中的那一条通告给邻居,不像 OSPF 那样把整个链路状态数据库都同步出去。

AS 号那点事

AS 号原来是 2 字节(1~65535),现在扩展到 4 字节。
· 公有 AS:向 APNIC 之类的注册机构申请,全球唯一,上互联网必须用公有的。
· 私有 AS:64512 ~ 65534,企业内部随便用,但不能出现在互联网的 AS_PATH 里(ISP 会帮你剥掉)。

AS 号相同就是 iBGP,不同就是 eBGP —— 这一句话决定了后面所有行为差异。

动手:看最简的两个 AS

加载「最简 eBGP」拓扑:AS100 的 R1 和 AS200 的 R2 直连,各自 network 一条前缀。
去「拓扑与邻居」页确认两件事:
① 邻居状态是 Established(不是这个状态,后面什么都别看);
② 画布上两台设备之间有一条会话线。

真机上对应 display bgp peer —— 这也是所有 BGP 排障的第一步。

实验重点

  • BGP 是路径矢量 + 策略协议,不算最短路
  • 邻居必须手工配,底层是 TCP 179
  • BGP 依赖 IGP 让下一跳可达,下一跳不可达路由就无效
  • AS 号相同=iBGP,不同=eBGP

第 2 课 · eBGP 邻居为什么起不来

排障 · 约 12 分钟

本课目标:把「邻居卡在 Active / OpenSent」这类问题一次搞清楚。

状态机只要记住三个卡点

完整状态:Idle → Connect → Active → OpenSent → OpenConfirm → Established。

· 卡 Idle:邻居地址配错了,或者根本没有到对端的路由。
· 在 Idle / Active 之间反复跳:TCP 建不起来。最常见三个原因 —— 地址写错、单向可达、eBGP 没配 multihop 却不是直连。
· 卡 OpenSent:TCP 通了但 Open 报文校验没过。要么 remote-as 写错,要么 Router-ID 冲突。

只有到 Established 才会开始交换路由。

eBGP 为什么默认必须直连

eBGP 发出的 TCP 报文 TTL 默认是 1,只够走一跳。这是有意设计的安全措施:防止有人从很远的地方伪造 eBGP 会话。

两种情况会打破这个前提:
① 两台设备不直连(中间隔了设备);
② 用 Loopback 建会话 —— 即使物理直连,从接口到 Loopback 在设备内部还要再算一跳。

解决都是同一个命令:peer x.x.x.x ebgp-max-hop 2(思科叫 ebgp-multihop)。

动手:故意把邻居搞坏

在「拓扑与邻居」页选中那个 eBGP 邻居:
① 把 remote-as 改成一个错的数字 → 看它卡在 OpenSent,并读诊断信息;
② 改回来,然后勾上「用 Loopback 建会话」但不加 multihop → 看它掉到 Active;
③ 把 ebgp-max-hop 改成 2 → 恢复 Established。
故障要自己造一遍才记得住。

实验重点

  • Idle/Active 反复跳 = TCP 建不起来(地址/可达性/multihop)
  • 卡 OpenSent = AS 号写错 或 Router-ID 冲突
  • eBGP 报文 TTL=1,非直连或用 Loopback 都要配 ebgp-max-hop
  • 只有 Established 才会有路由

第 3 课 · eBGP 通告路由时改了什么

入门 · 约 12 分钟

本课目标:看清 AS_PATH 和 NEXT_HOP 的变化 —— 这是 eBGP 的全部精髓。

两个必改的属性

eBGP 把一条路由通告给邻居时:

① AS_PATH 最前面插入自己的 AS 号。
所以 AS_PATH 读起来是从右到左的经过顺序,最左边是最近的一跳。
它有两个作用:选路(越短越优)、防环(收到含自己 AS 号的直接丢)。

② NEXT_HOP 改成自己在这条链路上的地址。
很好理解:对方要把包发给我,当然得指向我这条链路的接口地址。

两个不传的属性

· LOCAL_PREF 不发给 eBGP 邻居。它是纯粹的 AS 内部属性,表达「我这个 AS 更愿意从哪里出去」,跟别人无关。对方收到后按自己的默认值(100)处理。

· MED 默认不跨越第二个 AS。AS200 告诉 AS100「从我这个入口进来更好」,AS100 再往 AS300 传的时候会把 MED 清掉,因为那个建议对 AS300 没意义。

在纸上推一遍属性变化

拿 AS100(R1) → AS200(R2) → AS300(R3) 这条链,自己推一遍 8.8.8.0/24 的属性:

R1 发出 AS_PATH=[100]    NEXT_HOP=R1 的接口地址
R2 收到 AS_PATH=[100]    NEXT_HOP=R1
R2 发出 AS_PATH=[200,100]  NEXT_HOP=R2 的接口地址 ← 两个都改了
R3 收到 AS_PATH=[200,100]  NEXT_HOP=R2

三条规律自己验证一下:
① AS_PATH 每过一个 AS,就在最左边插入自己的 AS 号 —— 所以最左边是最近经过的
② NEXT_HOP 每过一个 eBGP 邻居就改成自己(iBGP 内部传递时不改,这是 iBGP 那个 tab 里「下一跳不可达」的根源)
③ LOCAL_PREF 根本不出 AS,R3 收到的报文里没有这个属性

★ 在真机上验证:display bgp routing-table 8.8.8.0 就能看到这两个属性。

实验重点

  • eBGP 通告:AS_PATH 加自己的 AS,NEXT_HOP 改成自己
  • AS_PATH 从右到左是经过顺序,最左边最近
  • LOCAL_PREF 不出 AS;MED 默认不跨第二个 AS

第 4 课 · AS_PATH 防环与 prepend 控流量

进阶 · 约 10 分钟

本课目标:理解 BGP 唯一的跨 AS 防环手段,以及怎么反过来利用它。

防环:收到含自己 AS 号的路由就丢

BGP 跨 AS 传播时没有 TTL、没有序列号、也没有链路状态数据库,判环全靠 AS_PATH:

eBGP 邻居收到一条路由,发现 AS_PATH 里已经有自己的 AS 号,说明这条路由是从自己这里出去又绕回来了 → 直接丢弃。

特例:MPLS VPN 的 Hub-Spoke 场景确实需要绕回去,这时用 peer allow-as-loop 放开限制。

prepend:让别人不爱走你这条路

AS_PATH 越短越优,那反过来 —— 我故意把自己的 AS 号多加几遍,别人看到这条路径很长就不选它了。

命令形态(华为 route-policy):

route-policy LONG permit node 10
 apply as-path 100 100 100 additive

这是控制入向流量最常用的手段。为什么不用 MED?因为 MED 只在同一个邻居 AS 内部有效,而 AS_PATH 谁都会比。

口诀:LOCAL_PREF 管出、AS_PATH prepend 管入。

动手:加载「双归多路径」拓扑看一眼

去拓扑与邻居页加载「双归多路径」:AS100 的 R1 从三个方向学到 8.8.8.0/24。

然后自己推一遍谁会赢 —— 按 12 条规则的顺序往下走,在第一条能分出高低的规则上就停:
① 先比 LOCAL_PREF(大的赢)。都一样就往下。
② 再比 AS_PATH 长度(短的赢)。
③ 还平就比 Origin、MED、eBGP 优于 iBGP……

★ 想验证 prepend 的效果,在真机上给某条加 route-policy 里的 apply as-path 100 100 additive,把 AS_PATH 拉长两跳,结果就会翻转。

实验重点

  • AS_PATH 是 BGP 唯一的跨 AS 防环机制
  • prepend 拉长 AS_PATH 可以让别人不走你这条路
  • LOCAL_PREF 管出向,AS_PATH prepend 管入向

第 5 课 · 选路 12 条规则怎么用

进阶 · 约 18 分钟

本课目标:学会「从上往下逐条比」,而不是死记规则表。

先记住正确的看法

规则是有顺序的,一旦某一条分出高低,后面的就不看了。

新手最常犯的错:一看到 AS_PATH 不一样就断定是 AS_PATH 决定的。但如果 LOCAL_PREF(第 3 条)已经分出高低,根本轮不到 AS_PATH(第 5 条)。

所以正确的做法是:从第 1 条开始往下走,每一条先看是不是所有候选取值都相同(相同就跳过),不同就淘汰差的,剩一条就结束。

全部 12 条,按顺序列出来

① 丢弃 NEXT_HOP 不可达的路由(有效性检查,路由表里没有 * 就是卡在这一条)
② Preferred-Value 大者优先(华为私有,只在本设备生效,不传给任何邻居)
③ Local_Pref 大者优先(默认 100,只在 AS 内部传递,控制本 AS 出向流量)
④ 本地起源优先(手工聚合 > 自动聚合 > network > import-route > 从对等体学到)
⑤ AS_Path 短者优先(prepend 自己的 AS 号能让别人不爱走你这条路,控制入向流量)
⑥ Origin:IGP > EGP > Incomplete(network 发布的是 IGP,import-route 引入的是 Incomplete)
⑦ MED 小者优先(默认只在同一个邻居 AS 的路由之间比,是给邻居 AS 的建议)
⑧ eBGP 优于 iBGP(直接从外面学的比在 AS 内部转了一手的优)
⑨ 到 NEXT_HOP 的 IGP 开销小者优先(热土豆路由:尽快把流量扔出本 AS)
⑩ Cluster_List 短者优先(RR 场景,反射次数少的优先)
⑪ Originator_ID / Router-ID 小者优先(没有技术优劣,纯粹为了让全网结果一致)
⑫ 对等体地址小者优先(最后的平局打破,走到这里说明前面 11 条完全一样)

★ 这份清单和顺序跟后端的选路引擎完全一致——不是简化版,真机上 display bgp routing-table <前缀> 报的「第几条规则」就是照这个顺序数的。

最常用的四条

上面 12 条里,实际工作能调的、也最常考的就四条:

第 3 条 LOCAL_PREF(越大越优,默认 100)—— 控制本 AS 出向。只在 AS 内传,所以是 AS 内部统一意志。

第 5 条 AS_PATH(越短越优)—— prepend 拉长可控制入向。

第 7 条 MED(越小越优,默认 0)—— 给邻居 AS 的建议,控制入向。⚠️ 默认只比较来自同一个邻居 AS 的路由。

第 8 条 eBGP 优于 iBGP —— 直接从外面学的比内部转一手的优。

MED 的那个前提最容易忽略

MED 默认只在来自同一个邻居 AS 的路由之间比较。

举例:R1 从 AS200 学到一条(MED=50),从 AS300 学到一条(MED=10)。很多人以为选 MED=10 那条 —— 错,这两条来自不同 AS,根本不比 MED,会继续往下走到第 8、9 条。

要跨 AS 比,得配 compare-different-as-med(一般不建议开)。
「双归多路径」预置拓扑里 AS200 有两台设备,正好是 MED 真正生效的场景 ——同一个邻居 AS 的两条路由之间才比 MED。

动手:拿这三道题练一遍

自己判断哪条赢、在第几条规则分出胜负(答案在下面「实验重点」里对):

第 1 题

A: LOCAL_PREF=100  AS_PATH=[200,300]  MED=10
B: LOCAL_PREF=200  AS_PATH=[200,300,400,500]  MED=0

→ B 赢,第 3 条规则就分出来了。LOCAL_PREF 更大,后面 AS_PATH 长、MED 大全都不看了。

第 2 题

A: LOCAL_PREF=100  AS_PATH=[200]      来自 AS200  MED=50
B: LOCAL_PREF=100  AS_PATH=[300]      来自 AS300  MED=10

→ LOCAL_PREF 平、AS_PATH 长度都是 1、Origin 也一样,到 MED 这条 ——但这两条来自不同的邻居 AS,根本不比 MED,会继续往下走到「eBGP 优于 iBGP」「IGP 度量更小」这些规则。
★ 这一题就是上一步说的那个坑。

第 3 题

A: LOCAL_PREF=100  AS_PATH=[200,300]  来自 AS200  MED=50
B: LOCAL_PREF=100  AS_PATH=[200,400]  来自 AS200  MED=10

→ B 赢,第 7 条(MED)分出胜负。两条 AS_PATH 都是 2 跳、而且来自同一个邻居 AS,所以这次真的比 MED,小的赢。

在真机上核对:display bgp routing-table 8.8.8.0 会直接告诉你哪条是 best、以及原因。

实验重点

  • 规则有顺序,先分出高低的那条说话,后面不看
  • LOCAL_PREF 管出向、AS_PATH prepend 和 MED 管入向
  • MED 默认只比较来自同一个邻居 AS 的路由
  • 看选路一定要问:是第几条规则决定的

第 6 课 · 团体属性与排障套路

排障 · 约 10 分钟

本课目标:用团体属性做策略,以及一套能直接照抄的排障流程。

三个知名团体属性

COMMUNITY 是给路由打的标签,本身没有行为,行为由收到的人决定。但有三个是全网公认的:

· no-export:可以在本 AS 内部传,但不能发给 eBGP 邻居(不出本 AS)。
· no-advertise:收到后谁都不能再发。
· no-export-subconfed:联邦场景下不出本子 AS。

自定义团体一般写成 AS:数字,比如 100:666 表示「这是客户路由」,配合 route-policy 做批量策略。

排障流程(照这个顺序走,不要跳)

① 邻居起来了吗 display bgp peer —— 状态必须是 Established。
② 上一跳发了吗 在上游设备上 display bgp routing-table peer <ip> advertised-routes。
③ 本端收到了吗 display bgp routing-table peer <ip> received-routes。
④ 收到了但没生效? 看有没有 *(valid)标记 —— 没有就是下一跳不可达。
⑤ 有效但没选上? display bgp routing-table <前缀>,看是第几条规则输的。

90% 的 BGP 故障在第 ① ② ④ 步就能定位。

★ 记住这五步对应的三张表,问题落在哪张表上就一清二楚:
· 第 ② 步查的是上游的 Adj-RIB-Out(它到底发没发)
· 第 ③④ 步查的是本端的 Adj-RIB-In(收到没有、有效没有)
· 第 ⑤ 步查的是 Loc-RIB(选路的结果)

实验重点

  • no-export 不出本 AS,no-advertise 谁都不发
  • 排障顺序:邻居状态 → 上一跳 Adj-RIB-Out → 本端 Adj-RIB-In → 有效性 → 选路
  • 路由在表里但没有 * 标记 = 下一跳不可达
冀ICP备2026021556号-2|冀公网安备13068302000206号