BGP Communities详解:Standard、Large与Extended
BGP standard、large和extended communities的实际工作原理。涵盖流量工程、黑洞路由、选择性通告和优雅关闭,附带BIRD2和FRR配置示例。
BGP Communities详解:Standard、Large与Extended
什么是BGP communities?
BGP communities是附加在路由通告上的32位标签。它们在AS之间传递信号信息,而不改变路由本身。一个community的含义是"以不同方式处理这个前缀"——降低其优先级、对路径做prepend、完全丢弃,或仅向特定peer通告。Communities具有传递性:除非被显式剥离,否则会在BGP会话间传播。目前存在三种类型:standard(RFC 1997)、extended(RFC 4360)和large(RFC 8092)。
Communities解决的是协调问题。没有它们,每个路由策略决定都需要在会话两端进行双边配置。有了communities,你的上游或IX路由服务器读取你的标签并执行你请求的策略。你打一次标签,网络自动执行。
如果你需要先了解BGP会话建立,请参阅BIRD2 BGP Configuration on Linux或FRR BGP Configuration on Linux。
BGP communities有哪三种类型?
它们在大小、编码方式和解决的问题上存在差异。Standard communities可以处理大多数场景,但在4字节ASN下会出现问题。Large communities修复了这一限制。Extended communities服务于特定的控制平面应用。
| 属性 | Standard(RFC 1997) | Large(RFC 8092) | Extended(RFC 4360) |
|---|---|---|---|
| 大小 | 32位 | 96位(3 x 32位) | 64位 |
| 格式 | ASN:value |
ASN:value1:value2 |
type:subtype:value |
| ASN支持 | 仅2字节 | 原生4字节 | 2字节或4字节(取决于类型) |
| BGP属性 | COMMUNITIES (8) | LARGE_COMMUNITIES (32) | EXTENDED COMMUNITIES (16) |
| 主要用途 | 上游信号、流量工程 | 与standard相同,支持4字节ASN | MPLS VPN、EVPN、route targets |
| 普及程度 | 普遍支持 | 2018年后广泛支持 | 特定协议使用 |
Standard communities(RFC 1997)
Standard communities是32位值,写为两个16位整数,用冒号分隔:ASN:value。高16位标识定义该community含义的AS。低16位承载操作或信息。
例如:174:70表示"Cogent:将local preference设为70"。只有Cogent定义174命名空间中70的含义。每个运营商都会发布自己的community定义。
16位ASN字段将standard communities限制为2字节ASN(0-65535)。截至2026年,已分配的ASN超过120,000个,大多数新分配的都是4字节号码。Standard communities无法表示它们。
IANA保留了65535:0到65535:65535的范围用于well-known communities。
Large communities(RFC 8092)
Large communities使用三个32位整数:Global Administrator : Local Data 1 : Local Data 2。Global administrator是定义该community的网络的ASN。两个local data字段由运营商自行定义。
这种格式解决了4字节ASN的问题。一个编号为398465的AS可以定义398465:100:0作为有效的large community。Standard communities无法编码这个值。
三字段结构还支持更丰富的语义。常见模式是ASN:function:parameter——例如,35661:1010:174可以表示"在法兰克福向Cogent(AS174)做一次prepend"。
Large community支持已在BIRD 1.6.3+、BIRD2、FRR 3.0+、OpenBGPD 6.1+、GoBGP、Cisco IOS-XR 6.2.1+和Junos 17.3+中可用。如果你的BGP守护进程是2018年之后发布的,几乎可以确定支持它们。
Extended communities(RFC 4360)
Extended communities是64位值,包含type字段、subtype字段和value。与standard和large communities不同,extended communities具有结构化语义:type和subtype定义了value的解释方式。
你主要在以下场景中遇到extended communities:
- MPLS L3VPN:Route targets(
rt 65000:100)和route distinguishers控制VRF的导入/导出 - EVPN:MAC移动性、ESI标签和路由类型
- BGP Flowspec:流量速率限制和重定向操作
对于AS之间的流量工程,standard和large communities是正确的工具。Extended communities在你运行overlay服务时才相关。本文后续部分聚焦于standard和large communities。
什么是well-known BGP communities?
IANA在保留的65535:*范围内定义了几个well-known community值。每个合规的BGP实现都必须理解这些值。
| Community | 值 | Hex | 行为 | RFC |
|---|---|---|---|---|
NO_EXPORT |
65535:65281 |
0xFFFFFF01 | 不向本地AS联盟外通告 | 1997 |
NO_ADVERTISE |
65535:65282 |
0xFFFFFF02 | 不向任何BGP peer通告 | 1997 |
NO_EXPORT_SUBCONFED |
65535:65283 |
0xFFFFFF03 | 不向本地AS外通告 | 1997 |
NOPEER |
65535:65284 |
0xFFFFFF04 | 不向双边peer通告 | 3765 |
BLACKHOLE |
65535:666 |
0xFFFF029A | 请求对标记前缀进行黑洞路由 | 7999 |
GRACEFUL_SHUTDOWN |
65535:0 |
0xFFFF0000 | 信号计划性会话关闭,将local-pref设为0 | 8326 |
NO_EXPORT是使用最广泛的。给前缀打上这个标签,你的peer就不会将其再通告到他们的AS边界之外。这就是你控制路由泄漏到第三方的方式。
BLACKHOLE和GRACEFUL_SHUTDOWN在下面的流量工程部分有详细说明。
BGP communities如何实现流量工程?
Communities允许你影响你无法控制的网络中的路由决策。你不能登录上游的路由器修改配置。但你可以用他们同意识别的communities标记你的通告。这就是通过communities实现的BGP流量工程。
Local preference信号如何通过communities工作?
大多数transit运营商提供可以在其网络内设置前缀local preference的communities。更高的local preference意味着"优先选择此路径"。较低的值意味着"仅作为备份使用"。
例如,一个AS为64500的运营商可能定义:
| Community | 效果 |
|---|---|
64500:100 |
正常优先级(默认) |
64500:90 |
较低优先级(备份路径) |
64500:150 |
较高优先级(首选路径) |
当发送给一个上游时标记64500:90,而对另一个保持默认,你就能将入站流量偏向没有备份community的那个上游。这是因为local preference在BGP决策过程中先于AS-path长度被评估。
请查阅你的运营商community文档。上面的值仅作说明。每个运营商定义自己的方案。
BGP prepending通过communities如何工作?
AS-path prepending人为增加路径长度,使远端网络不太倾向于选择该路由。与在自己的路由器上做prepending(会同等影响所有peer)不同,communities允许你有选择性地请求prepending。
一个典型的运营商方案:
| Community | 效果 |
|---|---|
64500:1001 |
向所有peer做1次prepend |
64500:1002 |
向所有peer做2次prepend |
64500:1003 |
向所有peer做3次prepend |
使用large communities时,目标可以更具体:
| Large community | 效果 |
|---|---|
64500:1:174 |
向Cogent(AS174)做1次prepend |
64500:2:174 |
向Cogent(AS174)做2次prepend |
64500:3:0 |
向所有peer做3次prepend |
这种粒度正是large communities取代standard communities用于流量工程的原因。第三个字段编码目标ASN或peer组。
BGP黑洞路由如何通过BLACKHOLE community工作?
黑洞路由告诉上游网络丢弃所有发往标记前缀的流量。它是一种DDoS缓解工具:当一个IP遭受攻击时,你用BLACKHOLE community通告它,上游在流量到达你的网络之前就将其null-route。
RFC 7999为此目的标准化了well-known community 65535:666。
黑洞路由生效的要求:
- **前缀精确度。**通告目标IP的/32(IPv4)或/128(IPv6)。永远不要黑洞整个/24。
- **双边协议。**你的上游必须配置为识别BLACKHOLE community。这不是自动的。请向运营商确认。
- **NO_EXPORT标记。**始终在BLACKHOLE旁附加
NO_EXPORT,防止黑洞传播到直接上游之外。 - **监控。**黑洞路由会丢弃所有流量,包括合法的和恶意的。持续监控,攻击停止后立即撤回通告。
大多数IXP路由服务器也通过65535:666支持黑洞路由。路由服务器将next-hop设为黑洞地址,并在重新分发前添加NO_EXPORT。
如何使用communities进行选择性通告?
选择性通告允许你控制哪些peer或IXP能看到你的前缀。这是"不向...通告"或"仅向...通告"的模式。
常见实现使用deny/allow模型:
| Community | 效果 |
|---|---|
64500:0:0 |
不向任何人通告(全局deny) |
64500:0:174 |
不向Cogent通告 |
64500:8:174 |
仅向Cogent通告(覆盖deny) |
Virtua(AS35661)使用下文参考表中描述的位置感知community方案。
Graceful shutdown如何通过GRACEFUL_SHUTDOWN community工作?
RFC 8326定义了GRACEFUL_SHUTDOWN community(65535:0),用于计划性维护。当你需要关闭一个BGP会话时,用这个community标记你的路由,告诉接收方将local preference降为0,在你断开之前开始优先选择替代路径。
流程:
- 向待维护的peer发送的所有路由添加
GRACEFUL_SHUTDOWNcommunity - 等待收敛(路由转移到替代路径)
- 关闭BGP会话
- 执行维护
- 恢复会话
- 移除community
没有graceful shutdown,关闭会话会导致立即路由撤回。流量会中断直到BGP收敛到替代路径。有了graceful shutdown,流量在会话关闭前逐步转移。
这与多宿主故障转移策略直接相关。
如何在BIRD2中配置BGP communities?
BIRD2在路由对象上使用类型化的community属性。三个相关属性是:
| 属性 | 类型 | Community类型 |
|---|---|---|
bgp_community |
clist(pair list) |
Standard |
bgp_large_community |
lclist(triplet list) |
Large |
bgp_ext_community |
eclist(extended list) |
Extended |
在BIRD2中添加communities
在filter块中使用.add()方法:
filter export_to_upstream {
# Add standard community
bgp_community.add((65535, 666));
# Add large community
bgp_large_community.add((35661, 1010, 174));
# Add multiple communities
bgp_community.add((65535, 65281)); # NO_EXPORT
accept;
}
在BIRD2中匹配communities
用~运算符测试成员关系:
filter import_from_peer {
# Match a specific standard community
if (65535, 666) ~ bgp_community then {
dest = RTD_BLACKHOLE;
accept;
}
# Match a specific large community
if (35661, 9999, 0) ~ bgp_large_community then {
reject;
}
# Match with wildcards using sets
# Any community in the 64500:* range
if bgp_community ~ [(64500, *)] then {
bgp_local_pref = 50;
}
accept;
}
~运算符在左操作数是右操作数的成员时返回true。对于集合匹配,使用pair/triplet模式,*作为通配符。
在BIRD2中删除communities
在入站剥离communities以防止未授权的信号传递:
filter scrub_inbound {
# Remove all communities in our ASN namespace
bgp_community.delete([(35661, *)]);
bgp_large_community.delete([(35661, *, *)]);
# Remove specific well-known community
bgp_community.delete((65535, 666));
accept;
}
BIRD2中的graceful shutdown接收端
function honor_graceful_shutdown() {
if (65535, 0) ~ bgp_community then {
bgp_local_pref = 0;
}
}
filter ebgp_inbound {
honor_graceful_shutdown();
# ... other import filters
accept;
}
将ebgp_inbound作为所有EBGP会话的import filter。当peer发送GRACEFUL_SHUTDOWN community时,local preference被设为0,使你的路由器优先选择任何替代路径。
BIRD2中的黑洞路由触发
protocol static blackhole_triggers {
ipv4 {
table master4;
};
# Announce 203.0.113.5/32 with BLACKHOLE + NO_EXPORT
route 203.0.113.5/32 blackhole;
}
filter export_blackhole {
if dest = RTD_BLACKHOLE then {
bgp_community.add((65535, 666)); # BLACKHOLE
bgp_community.add((65535, 65281)); # NO_EXPORT
# Accept only /32 for blackholes
if net.len = 32 then accept;
}
reject;
}
如何在FRR中配置BGP communities?
FRR使用IOS风格的community-list定义和route-map操作。Communities通过match子句匹配,通过set子句设置。
在FRR中定义community lists
! Standard community list - match specific community
bgp community-list standard BLACKHOLE permit 65535:666
bgp community-list standard GRACEFUL_SHUTDOWN permit 65535:0
bgp community-list standard NO_EXPORT permit no-export
! Large community list
bgp large-community-list standard PREPEND_1X permit 35661:1:0
bgp large-community-list standard NO_ANNOUNCE permit 35661:9:0
FRR支持编号(1-99为standard,100-500为expanded)和命名community lists。命名列表更易维护。
在FRR route-maps中设置communities
route-map EXPORT-TO-UPSTREAM permit 10
set community 65535:666 no-export additive
!
route-map EXPORT-TO-UPSTREAM permit 20
set large-community 35661:1010:174 additive
additive关键字将communities追加到现有集合,而非替换。如果不加它,set community会覆盖所有已有communities。
在FRR route-maps中匹配communities
route-map IMPORT-FROM-PEER permit 10
match community BLACKHOLE
set ip next-hop 192.0.2.1
!
route-map IMPORT-FROM-PEER permit 20
match community GRACEFUL_SHUTDOWN
set local-preference 0
!
route-map IMPORT-FROM-PEER permit 30
! Default: accept everything else
在FRR中剥离communities
route-map SCRUB-INBOUND permit 10
set comm-list OUR_COMMUNITIES delete
set large-comm-list OUR_LARGE_COMMUNITIES delete
!
bgp community-list expanded OUR_COMMUNITIES permit 35661:.*
bgp large-community-list expanded OUR_LARGE_COMMUNITIES permit 35661:.*:.*
这会移除peer可能注入的你ASN命名空间中的所有communities。将此route-map以neighbor <peer> route-map SCRUB-INBOUND in的方式应用。
FRR中的graceful shutdown
FRR提供内置命令:
router bgp 35661
bgp graceful-shutdown
这会自动向所有EBGP peer发送的所有路由添加GRACEFUL_SHUTDOWN community(65535:0)。在计划性维护前使用。
在接收端,应用一个匹配该community并降低local preference的route-map:
route-map HONOR-GSHUT permit 10
match community GRACEFUL_SHUTDOWN
set local-preference 0
!
route-map HONOR-GSHUT permit 20
! Accept everything else at normal preference
BIRD2与FRR community配置对比
| 操作 | BIRD2 | FRR |
|---|---|---|
| 添加standard community | bgp_community.add((ASN, val)) |
set community ASN:val additive |
| 添加large community | bgp_large_community.add((ASN, v1, v2)) |
set large-community ASN:v1:v2 additive |
| 匹配standard community | if (ASN, val) ~ bgp_community |
match community LIST_NAME |
| 匹配large community | if (ASN, v1, v2) ~ bgp_large_community |
match large-community LIST_NAME |
| 按模式删除 | bgp_community.delete([(ASN, *)]) |
set comm-list LIST_NAME delete |
| 通配符匹配 | 集合表达式中的[(ASN, *)] |
使用正则的expanded community-list |
| 应用filter | 协议中import filter name; |
neighbor X route-map NAME in |
BIRD2在filter函数内内联处理community操作。FRR将定义(community-list)和操作(route-map)分离。两种方式都可行。BIRD2的内联语法对于带条件的复杂逻辑更简洁。FRR的分离模型对于简单的匹配-设置策略更具可读性。
Virtua的BGP community值是什么?
Virtua(AS35661)支持standard和large两种BGP communities。Large communities遵循35661:ACTION_LOCATION:TARGET格式。该community方案具有位置感知能力,允许你按POP、按peer类型或按特定peer ASN控制通告。
位置代码
| 代码 | 城市 | 国家 | POP ID |
|---|---|---|---|
| 000 | 巴黎 | 法国 | PAR01FR |
| 001 | 里尔 | 法国 | LIL01FR |
| 010 | 法兰克福 | 德国 | FRA01DE |
| 020 | 阿姆斯特丹 | 荷兰 | AMS01NL |
| 999 | 所有位置 | -- | ALL |
操作communities
| 操作 | Large community格式 | 效果 |
|---|---|---|
| 路由来源 | 35661:0[LOC]:TARGET |
信息性:标识路由学习位置 |
| 1次prepend | 35661:1[LOC]:TARGET |
向目标做1次AS35661 prepend |
| 2次prepend | 35661:2[LOC]:TARGET |
向目标做2次AS35661 prepend |
| 3次prepend | 35661:3[LOC]:TARGET |
向目标做3次AS35661 prepend |
| 仅导出 | 35661:8[LOC]:TARGET |
覆盖deny:仅向目标通告 |
| 不导出 | 35661:9[LOC]:TARGET |
不向目标通告 |
目标选择器
| 目标值 | 含义 |
|---|---|
0 |
指定位置的所有peer |
1 |
仅transit peer |
2 |
仅IX peer |
| 特定ASN | 单个peer(例如174代表Cogent) |
优先级规则
当多个communities冲突时,Virtua按以下顺序评估(最高优先级在前):
35661:8[LOC]:ASN-- 显式允许特定peer35661:9[LOC]:ASN-- 拒绝特定peer35661:9[LOC]:1或35661:9[LOC]:2-- 拒绝peer组(transit或IX)35661:9[LOC]:0-- 拒绝该位置所有peer35661:9999:0-- 全局拒绝(不向任何地方通告)
Virtua communities使用示例
在法兰克福除Cogent外全部通告:
# BIRD2
bgp_large_community.add((35661, 9010, 174));
! FRR
route-map EXPORT permit 10
set large-community 35661:9010:174 additive
仅向所有位置的IX peer通告:
# BIRD2
bgp_large_community.add((35661, 9999, 1)); # deny all transit
! FRR
route-map EXPORT permit 10
set large-community 35661:9999:1 additive
向巴黎所有peer做2次prepend:
# BIRD2
bgp_large_community.add((35661, 2000, 0));
! FRR
route-map EXPORT permit 10
set large-community 35661:2000:0 additive
更多关于Virtua BGP设置的信息,请参阅BGP Bring Your Own IP on a VPS。
如何验证路由上的BGP communities?
在BIRD2中验证
birdc show route for 203.0.113.0/24 all
在输出中查找BGP.community和BGP.large_community属性:
203.0.113.0/24 unicast [upstream1 2026-03-19] * (100) [AS64500i]
via 198.51.100.1 on eth0
Type: BGP univ
BGP.community: (65535,666) (65535,65281)
BGP.large_community: (35661,0010,174)
BGP.as_path: 64500
在FRR中验证
vtysh -c "show ip bgp 203.0.113.0/24"
输出包含Community:行:
BGP routing table entry for 203.0.113.0/24
65535:666 no-export
Large Community: 35661:0010:174
使用外部工具验证
仅从你的网络内部无法看到communities。使用外部looking glass来验证互联网其他部分看到的内容:
- bgp.tools:搜索你的前缀并查看"Communities"标签页。显示全球多个收集器看到的communities。
- RIPE Stat:"BGP Looking Glass"组件显示来自RIPE RIS收集器的community属性。
- NLNOG Looking Glass:从多个AS的NLNOG RING节点查询。
务必从外部验证。一个community可能在你的路由器上正确设置,但被中间网络剥离。
如何处理community安全?
Communities默认具有传递性。路径中的任何网络都可以读取、添加或剥离它们。如果不进行正确过滤,这会带来安全风险。
剥离入站你ASN命名空间的communities
如果peer发送给你一条带有你自己communities标记的路由(例如35661:9999:0),而你不剥离它,你自己的导出filter可能会执行它。这可能导致你完全停止通告该前缀。
始终在import时清洗你自己的community命名空间:
# BIRD2 - apply on every EBGP import filter
bgp_community.delete([(35661, *)]);
bgp_large_community.delete([(35661, *, *)]);
! FRR - apply as inbound route-map on every EBGP neighbor
bgp community-list expanded OUR_COMMS permit 35661:.*
bgp large-community-list expanded OUR_LARGE_COMMS permit 35661:.*:.*
route-map SCRUB-IN permit 10
set comm-list OUR_COMMS delete
set large-comm-list OUR_LARGE_COMMS delete
验证黑洞路由请求
永远不要盲目接受来自任何peer的65535:666。恶意或配置错误的peer可能黑洞你的客户前缀。
接受黑洞路由的规则:
- 仅接受peer被授权发起的前缀的黑洞标记路由
- 在执行黑洞路由前验证RPKI/ROA有效性(参阅RPKI ROA Setup for BGP)
- 将黑洞路由接受的前缀长度限制为/32(IPv4)和/128(IPv6)
- 在重新分发前始终为黑洞路由添加
NO_EXPORT
# BIRD2 - safe blackhole acceptance
filter import_with_blackhole {
if (65535, 666) ~ bgp_community then {
# Only accept /32 for blackhole
if net.len != 32 then reject;
dest = RTD_BLACKHOLE;
bgp_community.add((65535, 65281)); # NO_EXPORT
accept;
}
# ... normal import policy
accept;
}
在适当时剥离导出的communities
在向peer通告路由前,移除他们不应看到或作用的communities:
# BIRD2 - clean export to IX route server
filter export_to_ix {
# Keep well-known communities, remove internal ones
bgp_community.delete([(35661, *)]);
bgp_large_community.delete([(35661, 0, *)]); # Remove informational
# Keep action communities the IX needs to see
accept;
}
Community安全是更广泛路由过滤策略的一部分。完整内容请参阅BGP Route Filtering and Security。
遇到问题?
**Communities未出现在远端looking glass上。**你的上游可能剥离了它们。检查community是否在他们识别的命名空间中。一些运营商默认剥离所有第三方communities。
**黑洞路由不工作。**验证前缀长度(需要/32或/128)。确认你的上游支持RFC 7999。检查是否添加了NO_EXPORT——没有它,黑洞路由可能传播得比预期更远并被剥离。
**Large communities未传播。**较老的BGP实现会静默丢弃未知属性。如果中间AS运行的软件早于RFC 8092支持,large communities会丢失。检查AS path并找出丢弃它们的网络。
**BIRD2 filter语法错误。**Community pairs使用圆括号,不是冒号:(35661, 100)而非35661:100。Large communities是triplets:(35661, 100, 200)。冒号表示法仅用于显示和CLI。
**FRR community-list不匹配。**命名community lists必须与定义时完全一致地引用。检查拼写错误。使用show bgp community-list验证列表内容。
FRR中communities被覆盖而非追加。set community或set large-community中缺少additive关键字会替换所有已有communities。除非你有意覆盖,否则始终使用additive。
检查日志排查BGP会话问题:
# BIRD2
journalctl -u bird -f
# FRR
journalctl -u frr -f
版权所有 2026 Virtua.Cloud。保留所有权利。 本内容为 Virtua.Cloud 团队原创作品。 未经书面许可,禁止复制、转载或再分发。