BGP 协议是什么:工作层次、端口号与机房里的用法
BGP 协议全称 Border Gateway Protocol(边界网关协议),是互联网上各个自治系统(AS)之间交换路由的协议,现行版本 BGP-4 由 RFC 4271 定义。它基于 TCP,邻居之间通过 179 端口建立会话,按封装位置算应用层,作用却是为网络层选路。机房常说的“BGP 机房”,就是用这个协议把自有 IP 段同时宣告给多家运营商。
BGP 协议的全称是 Border Gateway Protocol,中文叫边界网关协议。它解决的问题是:互联网由几万个独立运营的网络组成,每个网络叫一个自治系统(AS),各有一个 AS 号;这些网络之间需要互相告知“我这里有哪些 IP 段”“去某个 IP 段要经过哪些 AS”,BGP 就是交换这些信息的标准协议。现行的 BGP-4 由 RFC 4271 定义。两台 BGP 路由器先建立一条到对方 TCP 179 端口的连接,再在这条连接上交换路由,所以 BGP 协议是基于 TCP 的;按 TCP/IP 的封装位置它属于应用层,但它的工作是为网络层的转发提供路由。IDC 行业所说的“BGP 机房”“BGP 线路”,是用这个协议实现的一种多运营商接入方式,而协议本身在每一个公网 IP 的背后都在工作。
BGP 协议的作用,以及它工作在第几层
作用:在 AS 之间交换“去哪、怎么走”
BGP 是一种路径向量协议,传递的每条路由都包含一个目的前缀和一组路径属性,例如:
前缀 203.0.113.0/24 下一跳 198.51.100.2 AS_PATH 64496 64500 Origin IGP
意思是:去往 203.0.113.0/24,把包交给 198.51.100.2;这条路先经过 AS 64496,最终到达宣告这个段的 AS 64500。围绕这样的路由,BGP 做四件事:
- 宣告:每个 AS 把自己持有的地址段告诉邻居,邻居再一层层传出去,全网就知道了这个段在哪里。
- 记录路径:路由每经过一个 AS,就在 AS_PATH 前面加上这个 AS 的号码。
- 按策略选路:同一个前缀从多个邻居学到时,按属性和本地策略选一条,不看链路带宽和延迟。运营商之间“走不走这条路、优先走谁”的商业关系,正是通过 BGP 策略落实的。
- 防环:收到的 AS_PATH 里已经有自己的 AS 号,就丢弃这条路由。
落到 IDC 的日常里,就是多运营商接入、出入方向的流量调度、线路故障时撤销路由自动绕行,以及被攻击时用团体属性通知上游丢弃发往某个 IP 的流量(黑洞路由)。
工作在第几层:报文在应用层,作用在网络层
BGP 报文装在 TCP 里,所以按封装算应用层。教材里常把几种路由协议放在一起对比:
| 路由协议 | 承载方式 | 按封装算哪一层 |
|---|---|---|
| RIP | UDP 520 | 应用层 |
| OSPF | 直接封装在 IP 里,协议号 89 | 网络层 |
| IS-IS | 直接封装在数据链路层上,不经过 IP | 在 OSI 里属于网络层协议 |
| BGP | TCP 179 | 应用层 |
但 BGP 本身不转发任何业务数据包,它只算出路由、装进路由表,真正按目的 IP 转发的是网络层。所以也常说它是网络层的控制面协议,两种说法并不矛盾。选 TCP 的好处是可靠传输交给了 TCP,BGP 不用自己做确认和重传:会话建立时交换一次完整路由,之后只发增量变化。代价是 TCP 不会主动告诉 BGP 对端已经失效,所以 BGP 要定时发 KEEPALIVE 探活。
BGP 协议端口号 179:会话怎么建立、状态怎么看
179 端口与访问控制
两端都监听 TCP 179,哪一端先发起都可以:发起方用一个随机高位端口连到对方的 179。所以在运行 BGP 的 Linux 上,看到的连接可能是“本地 179、对端随机端口”,也可能反过来;双方同时发起时,按 RFC 4271 保留 Router ID 较大的一方发起的那条。
# Linux 上运行 FRR、BIRD 时,查看 BGP 的 TCP 连接
ss -tnp '( sport = :179 or dport = :179 )'
# 抓 BGP 报文,-v 会解码出 OPEN、UPDATE、KEEPALIVE
tcpdump -i eth0 -nn -v 'tcp port 179'
179 端口直接决定路由,要按邻居地址严格放行。下面只允许运营商的互联地址 198.51.100.2 访问,第二条放行本端主动发起时对方从 179 回来的包:
iptables -A INPUT -p tcp -s 198.51.100.2 --dport 179 -j ACCEPT
iptables -A INPUT -p tcp -s 198.51.100.2 --sport 179 -j ACCEPT
iptables -A INPUT -p tcp --dport 179 -j DROP
协议层面还有三道常用防护:eBGP 默认 TTL 为 1,邻居必须直连,用环回地址等非直连方式建邻居要显式配置多跳;GTSM(RFC 5082)让发送方把 TTL 设为 255,接收方只收 TTL 不低于门限的报文,远处伪造的报文经过多跳后 TTL 不够而被丢弃,门限的配置方式以设备文档为准;TCP MD5 认证(RFC 2385)让两端用共享密钥为每个 TCP 段计算摘要,对不上的段直接丢弃,后继标准是 TCP-AO(RFC 5925)。
五种报文与保持时间
| 报文 | 类型号 | 作用 |
|---|---|---|
| OPEN | 1 | 会话建立时交换版本、AS 号、保持时间、Router ID 和支持的能力(如 IPv6、4 字节 AS) |
| UPDATE | 2 | 宣告新路由或撤销旧路由,携带路径属性 |
| NOTIFICATION | 3 | 出错时发送,携带错误码,发完立即断开会话 |
| KEEPALIVE | 4 | 只有 19 字节的报文头,定时发送,证明自己还在 |
| ROUTE-REFRESH | 5 | 请求对方重发路由,改了入方向策略不用断开会话(RFC 2918) |
保持时间在 OPEN 里协商,取两端配置中较小的值,KEEPALIVE 间隔一般是它的三分之一。思科、华为默认 60 秒发一次 KEEPALIVE、保持时间 180 秒;RFC 4271 建议的保持时间是 90 秒。超过保持时间没收到对方任何报文,就发出错误码为 4(保持计时器超时)的 NOTIFICATION 并断开会话。
六个会话状态
display bgp peer(华为)、show bgp summary(思科、FRR)里的 State 一列,显示的就是会话所处的状态:
| 状态 | 含义 | 长时间停在这里的常见原因 |
|---|---|---|
| Idle | 初始状态,或出错后等待重试 | 邻居被管理性关闭;收到的路由条数超限被断开;配置不完整 |
| Connect | 正在发起 TCP 连接 | 与 Active 来回切换,说明 TCP 179 建不起来 |
| Active | TCP 连接失败,等对方连入并定时重试 | 对端地址不通;对端没把本端配成邻居;179 被 ACL 或防火墙拦截;非直连 eBGP 没配多跳;源地址与对端配置的邻居地址不一致 |
| OpenSent | TCP 已建立、已发 OPEN,等对方的 OPEN | 通常一闪而过;任一方不认可 OPEN 里的参数,会发 NOTIFICATION 断开,会话退回 Idle |
| OpenConfirm | OPEN 校验通过,等对方的 KEEPALIVE | 通常一闪而过 |
| Established | 会话建立,开始交换路由 | 正常状态 |
最常见的误读是 Active:它不是“活跃”,而是连接没建起来、还在重试。AS 号配错是另一类典型故障:TCP 能连上,但对方校验 OPEN 时发现 AS 号与配置不符,回一个 NOTIFICATION(OPEN 报文错误,子码 Bad Peer AS)后断开,会话反复建立又断开,设备日志里能看到这条通知。下面的示例里,第一个邻居 State/PfxRcd 列是数字,表示已建立并收到 912340 条路由;第二个显示 Active,表示没有建立:
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
198.51.100.2 4 64496 128734 1021 884512 0 0 3d02h 912340
198.51.100.6 4 64497 0 0 1 0 0 never Active
AS 号与 eBGP、iBGP 的区别
AS 号是 BGP 区分网络的依据。2 字节 AS 号共 65536 个(0–65535,0 和 65535 保留),其中 64512–65534 为私有号(RFC 6996),64496–64511 留作文档示例(RFC 5398);4 字节 AS 号(RFC 6793)把空间扩展到约 42 亿,4200000000–4294967294 为私有号。国内运营商的骨干网各有自己的 AS,例如中国电信 163 骨干网 AS4134、CN2 AS4809,中国联通 AS4837,中国移动 AS9808。
邻居在不同 AS 之间叫 eBGP,在同一个 AS 内部叫 iBGP,两者行为差别很大:
| 对比项 | eBGP | iBGP |
|---|---|---|
| 邻居在哪里 | 不同 AS 之间,如机房与运营商 | 同一 AS 内部,如机房的两台边界路由器 |
| 默认 TTL | 1,要求直连 | 不要求直连,通常用环回地址建邻居,靠 IGP 保证可达 |
| AS_PATH | 发出时加上本 AS 号 | 不改变 |
| 下一跳 | 改成自己的地址 | 默认保持不变,需要时配置 next-hop-self |
| 防环方式 | 检查 AS_PATH 里有没有自己的 AS | 从 iBGP 邻居学到的路由不再传给其他 iBGP 邻居 |
| LOCAL_PREF | 不传给外部邻居 | 在 AS 内传递,统一出口选择 |
| 管理距离(思科默认) | 20 | 200 |
iBGP 的防环规则带来规模问题:每台路由器都要和其他所有路由器建立 iBGP 会话,n 台需要 n(n−1)/2 条,10 台就是 45 条、20 台是 190 条。规模稍大的网络会用路由反射器(RFC 4456)把会话数降下来。
BGP 常用属性:四类属性各管什么
RFC 4271 把路径属性分成四类:公认必遵属性每条 UPDATE 都必须带,所有实现都必须认识;公认任意属性必须认识,但可以不带;可选过渡属性不认识也要原样传给下一个 AS;可选非过渡属性不认识就丢弃、不往下传。
| 属性 | 类别 | 含义 | 在机房里怎么用 |
|---|---|---|---|
| ORIGIN | 公认必遵 | 路由怎么进入 BGP:IGP(i,network 宣告)、EGP(e,已淘汰)、Incomplete(?,重分发引入) | 用 network 宣告自有地址段,起源为 IGP |
| AS_PATH | 公认必遵 | 经过的 AS 列表 | 防环;人为重复添加本 AS 号(prepend),让某个方向显得更远,影响入方向流量 |
| NEXT_HOP | 公认必遵 | 去往该前缀的下一跳地址 | iBGP 收到的下一跳不可达时,这条路由不可用 |
| LOCAL_PREF | 公认任意 | AS 内部的出口优先级,越大越优先 | 指定某类目的地址优先从某家运营商出去 |
| ATOMIC_AGGREGATE、AGGREGATOR | 公认任意、可选过渡 | 标记路由经过聚合,并记录聚合者 | 很少需要关心 |
| COMMUNITY | 可选过渡 | 给路由打标签,对方按标签执行策略(RFC 1997) | 让上游对被攻击的 IP 做黑洞;公认团体 NO_EXPORT 限制路由不传出 AS |
| MED | 可选非过渡 | 建议邻居 AS 从哪个入口送流量进来,越小越优先 | 与同一家运营商有多条互联时使用 |
选路时,路由器按固定顺序逐项比较这些属性;思科的 Weight、华为的协议首选值这类厂商私有值排在最前面,只在本台设备上生效。
BGP 和 OSPF 有什么区别:IGP 与 EGP 的分工
OSPF、IS-IS 属于内部网关协议(IGP),负责一个 AS 内部的路由;BGP 是外部网关协议(EGP),负责 AS 之间的路由:
| 对比项 | OSPF(IGP) | BGP(EGP) |
|---|---|---|
| 用在哪里 | 一个 AS 内部,如机房的核心与汇聚之间 | AS 之间,如机房与运营商;大型网络内部也用 iBGP 传外部路由 |
| 算法 | 链路状态:每台路由器掌握全网拓扑,用 SPF 算最短路径 | 路径向量:只知道邻居告诉它的路径和属性 |
| 选路依据 | 开销(cost),通常由接口带宽换算 | 路径属性和策略,不看带宽和延迟 |
| 邻居发现 | 组播自动发现 | 手工指定邻居地址 |
| 路由规模 | 几百到几万条 | 完整的 IPv4 互联网路由表已在百万条量级 |
| 故障检测 | 默认几十秒,配合 BFD 可到亚秒级 | 默认保持时间 180 秒,通常要配 BFD |
| 常见故障 | 区域号、网络类型、MTU 不一致,邻居起不来 | AS 号、邻居地址、TTL 配错;出口策略错误造成路由泄露 |
机房里两者配合使用:OSPF 在内部传播各设备的环回地址和互联地址,保证边界路由器之间互相可达;iBGP 跑在环回地址之间,传递从运营商学到的外部路由;eBGP 负责与各家运营商交换路由。外部的大量路由不要引入 OSPF,否则内部设备的路由表和 CPU 都会被拖垮。
“BGP 机房”和 BGP 协议是什么关系
单线机房同样离不开 BGP 协议:它的地址段由运营商用自己的 AS 宣告,再经运营商之间的 BGP 会话传到其他网络,只是机房自己不运行 BGP。行业里说的“BGP 机房”“BGP 多线”,指机房自己成为一个 AS、直接参与 BGP:
- 持有自己的 AS 号和地址段,对外宣告的 IPv4 段至少是 /24;
- 与两家以上运营商各建 eBGP 会话,把同一个地址段宣告给每一家;
- 从每家运营商接收路由,回包按路由表从对应线路出去;某条线路断开时,会话中断、路由撤销,流量自动改走其他线路。
用本文的术语说,BGP 机房就是一个多宿主的 AS。行业里另有一种“静态 BGP”,机房与运营商之间一般不跑 BGP 会话,而是按运营商地址库写静态路由分流;这是行业叫法,不是协议里的概念,各家实现也不完全相同。想知道一个 IP 属于哪种接入,查宣告它的起源 AS 是运营商的还是机房自己的,再看这个 AS 有几家上游。
在机房里怎么落地
BGP 以前缀为单位宣告,而 IPv4 在公网上能被普遍接受的最长前缀是 /24,机房持有一个 /22 时,往往要拆成 4 个 /24 分别宣告、分别调度。Toplink DCIM 的 IP 地址管理按 CIDR 录入地址段,大段可以自动拆分为多个 /24 分别管理,管理粒度和宣告粒度一致;每个段可以按线路分组、打标签,“BGP 多线”和“电信单线”的地址分开归类,用量比例图上哪条线路的地址快用完了一目了然;还没宣告或预留的段可以锁定,开通服务器时不会被自动分配出去。宣告管的是地址段在公网上的去向,段内每个地址由谁使用,还要在接入侧管住:客户在服务器上私自配置一个不属于自己的地址,流量照样能发出去。在交换机管理里给接入端口开启源地址校验和 ARP 绑定后,交换机只放行源地址登记在该端口名下的流量,冒用的地址发不出包。
常见问题
BGP 和 BGP-4 是一回事吗?
现在说 BGP 指的就是 BGP-4。BGP 最早在 1989 年发布(RFC 1105),1994 年的第 4 版开始支持 CIDR 无类路由,2006 年由 RFC 4271 重新定义。之后 IPv6、4 字节 AS 号等能力都靠扩展加入,版本号没有再变。
BGP 能代替 OSPF 做机房内部路由吗?
大型数据中心里可以:RFC 7938 描述了在 Leaf-Spine 架构中完全用 eBGP 做内部路由的做法,每台或每组交换机一个私有 AS 号。普通 IDC 机房的规模用不上,内部仍以 OSPF 或静态路由为主。
服务器上能跑 BGP 吗?
能。FRR、BIRD 等开源软件可以在 Linux 上运行 BGP,常见用途是把负载均衡的 VIP 或 Anycast 地址宣告给机房交换机。前提是机房同意与这台服务器建立会话,并在交换机上限定它只能宣告哪些前缀。