Ciliumcilium-dbg bpf policy add命令详解:直接写入 BPF Policy 映射的策略注入指南
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
导读
cilium-dbg bpf policy add是 Cilium 数据面调试工具链中用于直接向指定 Endpoint 的 BPF Policy Map 添加或更新策略条目的低层命令。与通过 Kubernetes CiliumNetworkPolicy(CNP)等高层 API 下发策略不同,该命令绕过控制面,直接操作 eBPF 内核映射,适合内核开发调试、故障排查和自动化脚本场景。读完本文,你将掌握该命令的完整语法、参数语义、底层 BPF 映射寻址规则,以及它与策略删除、列表查看命令的配合用法。
命令概览与适用场景
cilium-dbg是 Cilium 附带的调试工具(其生成的 CLI 参考文档位于 Documentation/cmdref/cilium-dbg_bpf_policy_add.md)。bpf policy子命令组的定位是 "Manage policy related BPF maps"(cilium-dbg/cmd/bpf_policy.go),其下的add子命令用于向策略映射写入条目。
适用场景主要包括:
- Datapath 级调试:验证某条策略在 BPF 映射层面是否生效、键值编码是否正确;
- 故障排查:当高层 API 下发的策略未按预期生效时,直接检查并修正映射内容;
- 脚本化注入:在测试环境或自动化流程中快速构造策略状态;
- 开发验证:配合
cilium-dbg bpf policy get/list/delete验证策略生命周期。
需要强调的是,这是一条调试命令,正常运行时应优先使用 Cilium 的 Kubernetes CRD 或命令行 API 管理策略,直接修改 BPF 映射不会反向同步到控制面状态。
命令语法与参数说明
命令的基本语法为:
cilium-dbg bpf policy add <endpoint id> <traffic-direction> <identity> [port/proto] [flags]从源码看,其 Cobra 定义(cilium-dbg/cmd/bpf_policy_add.go)为:
Use: "add <endpoint id> <traffic-direction> <identity> [port/proto]", Short: "Add/update policy entry", PreRun: requireEndpointID, Run: func(cmd *cobra.Command, args []string) { common.RequireRootPrivilege("cilium bpf policy add") updatePolicyKey(parsePolicyUpdateArgs(log, cmd, args, isDeny, cookie), true) },位置参数
| 参数 | 含义 | 说明 |
|---|---|---|
<endpoint id> | Endpoint ID 或保留标签名 | 数值 ID(如123),或保留身份名(如host),用于定位目标策略映射 |
<traffic-direction> | 流量方向 | 仅接受ingress或egress(大小写不敏感),由parseTrafficString校验 |
<identity> | 对端安全身份 ID(NumericIdentity) | 32 位无符号整数,表示与哪个身份之间的通信策略 |
[port/proto] | 可选的 L4 端口与协议 | 形如80/tcp、443/udp,省略表示所有端口 |
Flags(本命令专属)
--cookie uint32 Sets policy log cookie --deny Sets deny mode -h, --help help for add--deny:将条目置为deny 模式(默认 allow),对应源码中isDeny布尔变量(cilium-dbg/cmd/bpf_policy_add.go);--cookie:设置策略日志 cookie(uint32),用于审计日志关联,对应源码cookie变量(cilium-dbg/cmd/bpf_policy_add.go)。
继承自父命令的全局 Flags
| Flag | 说明 |
|---|---|
--config string | 配置文件(默认$HOME/.cilium.yaml) |
-D, --debug | 启用调试消息 |
-H, --host string | 服务端 API URI |
--log-driver strings | 日志端点(如syslog) |
--log-opt map | 日志驱动选项(如format=json) |
此外,命令通过requireEndpointID前置检查确保 Endpoint ID 参数非空,并在Run中调用common.RequireRootPrivilege("cilium bpf policy add")强制要求 root 权限才能执行——因为直接操作 BPF 映射属于特权操作。
参数解析的内部实现
参数解析由 cilium-dbg/cmd/helpers.go 中的parsePolicyUpdateArgs/parsePolicyUpdateArgsHelper完成,其核心步骤可拆解如下。
1. 校验流量方向
parseTrafficString(cilium-dbg/cmd/helpers.go)将参数小写化后与ingress/egress匹配,否则返回Invalid方向并报错。
2. 解析 Endpoint ID 并定位 BPF 映射
endpointToPolicyMapPath(cilium-dbg/cmd/helpers.go)决定目标映射路径,存在两条分支:
- 数值 Endpoint ID:解析为 16 位无符号整数,映射名形如
cilium_policy_v3_00123(bpf.LocalMapName(policymap.MapName, id)补零格式化); - 保留身份名:如
host,通过identity.GetReservedID解析为保留身份 ID,映射名形如cilium_policy_v3_reserved_1。
最终经bpf.MapPath得到 BPF 文件系统中的完整路径。映射名前缀cilium_policy_v3_定义于 pkg/maps/policymap/policymap.go,其版本号_v3_对应策略身份聚合的语义变更,每次 BPF 格式或语义变更都必须重命名以保证新旧映射隔离。
3. 解析身份与 L4 信息
identity参数解析为 32 位NumericIdentity;- 若提供了
[port/proto],通过parseL4PortsSlice解析端口与协议:协议省略时(如仅写1)会遍历u8proto.ProtoIDs展开为全部协议;未指定 L4 参数时,默认使用端口0与协议0(ANY),表示全端口通配。
4. 组装参数对象
解析结果封装为PolicyUpdateArgs(cilium-dbg/cmd/helpers.go),包含路径、方向、身份、端口、协议集合、isDeny与cookie六个字段,随后交给updatePolicyKey执行实际映射写入。
映射写入过程与键值编码
updatePolicyKey(cilium-dbg/cmd/helpers.go)负责真正的写入:
policyMap, err := policymap.OpenPolicyMap(log, pa.path) ... for _, proto := range pa.protocols { u8p := u8proto.U8proto(proto) entry := fmt.Sprintf("%d %d/%s", pa.label, pa.port, u8p.String()) mapKey := policymap.NewKeyFromPolicyKey( policyTypes.KeyForDirection(pa.trafficDirection). WithIdentity(pa.label).WithPortProto(proto, pa.port)) mapEntry := policymap.NewEntryFromPolicyEntry(mapKey, policyTypes.MapStateEntry{Cookie: pa.cookie}.WithDeny(pa.isDeny)) if err := policyMap.Update(&mapKey, &mapEntry); err != nil { Fatalf("Cannot add policy key '%s': %s\n", entry, err) } }几个值得注意的实现细节:
- OpenPolicyMap 不做透明初始化:源码注释明确说明,即使映射缺失也不触发重建,因为
OpenOrCreate在映射属性变更时会引发更严重的问题(pkg/maps/policymap/policymap.go 表明该函数"仅用于cilium-dbg bpf policy工具"); - 多个协议展开写入:当协议未指定时,
protocols切片包含多个协议值,循环会依次为每个协议写入独立条目; - 键的构建:
KeyForDirection(...).WithIdentity(...).WithPortProto(...)链式构造 LPM 键(pkg/policy/types/types.go),方向编码在最高位,端口支持按前缀长度通配; - 值的编码:
MapStateEntry{Cookie: ...}.WithDeny(...)(pkg/policy/types/entry.go)将 deny 语义编码进Precedence字段——deny 条目的优先级字段被设置为precedenceByteDeny,从而在 datapath 查表时获得高于普通 allow 条目的优先级; - 端口字节序:
NewKeyFromPolicyKey(pkg/maps/policymap/policymap.go)使用byteorder.HostToNetwork16将端口转为网络字节序,这是 BPF 映射跨架构一致性的关键。
常用命令示例
基础用法
# 为 Endpoint 123 添加 ingress 方向、身份 12345 的允许策略(所有端口) cilium-dbg bpf policy add 123 ingress 12345 # 指定端口与协议:允许身份 12345 通过 TCP 80 端口 ingress cilium-dbg bpf policy add 123 ingress 12345 80/tcp # 只写端口不写协议:等价于对 TCP/UDP/SCTP 等全部协议生效 cilium-dbg bpf policy add 123 ingress 12345 80 # egress 方向示例 cilium-dbg bpf policy add 123 egress 12345 443/udpdeny 模式与 cookie
# 添加 deny 条目并附加策略日志 cookie cilium-dbg bpf policy add 123 ingress 12345 --deny --cookie 0x010203--deny对应测试用例中以isDeny: true、cookie: 0x010203组合验证的路径(cilium-dbg/cmd/helpers_test.go)。
配合查看与删除
# 查看某个 Endpoint 的当前策略条目 cilium-dbg bpf policy get 123 # 删除刚才添加的条目(注意 delete 语法不含 traffic-direction 参数) cilium-dbg bpf policy delete 123 12345 80/tcpbpf policy delete与add共享parsePolicyUpdateArgs解析逻辑,仅将updatePolicyKey的add参数置为false转而执行DeleteKey(cilium-dbg/cmd/bpf_policy_delete.go),因此两者参数语义保持一致。
测试验证与行为边界
仓库在 cilium-dbg/cmd/helpers_test.go 中提供了针对参数解析的表格驱动测试,覆盖的关键场景即上文各示例的依据:
| 输入 | 预期结果 |
|---|---|
host ingress 12345 | 映射cilium_policy_v3_reserved_1,方向 ingress,端口 0,协议ANY |
123 egress 12345 1/tcp | 映射cilium_policy_v3_00123,方向 egress,端口 1,协议TCP |
123 ingress 12345 1 | 端口 1,协议展开为全部协议 |
123 invalid 12345 | 解析失败(非法方向) |
123 invalid 1/udt | 解析失败(非法协议) |
测试同时验证了--deny与--cookie的传递。这些用例从侧面印证了命令的行为边界:方向只能是 ingress/egress,协议必须是已注册的 IP 协议名,非法输入会在写入前被拒绝。
使用注意事项
- 需要 root 权限:命令通过
RequireRootPrivilege强制检查,非 root 用户无法执行; - 直接修改 BPF 映射属于低层操作:不会同步到 Cilium 控制面状态,重启或策略重新下发后可能被覆盖,仅作调试用途;
- 映射版本敏感:
cilium_policy_v3_前缀与当前 datapath 程序版本强绑定,跨版本混用可能导致键值解释不一致; - 保留身份映射:当第一个参数使用
host等保留名时,写入的是全局保留身份的策略映射(如cilium_policy_v3_reserved_1),而非某个具体 Endpoint 的映射,使用前需确认意图。
延伸阅读
- 命令的权威 CLI 参考:
cilium-dbg bpf policy add(Documentation/cmdref/cilium-dbg_bpf_policy_add.md)及父命令 Documentation/cmdref/cilium-dbg_bpf_policy.md; - 策略映射底层实现:pkg/maps/policymap/policymap.go;
- 策略键值类型定义:pkg/policy/types/types.go、pkg/policy/types/entry.go;
- 参数解析与写入逻辑:cilium-dbg/cmd/helpers.go。
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考