☰
BFE mod_header 规则配置完全指南:请求/响应 Header 与 Cookie 的灵活操控
2026/10/10 13:59:38 网站建设 项目流程
  • 后端
  • 网络/通信
  • 云原生

【免费下载链接】bfe

A modern layer 7 load balancer from baidu

项目地址:https://gitcode.com/gh_mirrors/bf/bfe
点击查看免费下载

mod_header.data是 BFE(百度自研的七层负载均衡器)中mod_header模块的规则配置文件,用于按产品(product)维度定义请求头、响应头以及 Cookie 的增删改查动作。本文以该文件为骨架,结合仓库源码(bfe_modules/mod_header/与conf/mod_header/)深入讲解其配置结构、全部模块动作、参数校验规则、变量插值机制与热加载原理,读完即可独立编写并校验一套可上线的 header 规则。

一、文件定位与作用

mod_header是 BFE 内置的 HTTP 头部处理模块,它在请求被路由定位之后(HandleAfterLocation)与响应返回之前(HandleReadResponse)分别注入过滤器,对进出流量做头部改写(见 mod_header.go)。

与模块相关的配置分为两层:

文件作用仓库示例
mod_header.conf模块基础配置:规则文件路径、是否禁用默认头、调试日志开关conf/mod_header/mod_header.conf
mod_header.data模块规则配置:按产品定义 header/cookie 动作(本文主题)conf/mod_header/header_rule.data

注意:mod_header.conf中Basic.DataPath默认指向mod_header/mod_header.data(见 conf_mod_header.go),实际部署时可指向任意文件名(仓库默认配置即为mod_header/header_rule.data)。

二、配置结构与字段说明

mod_header.data是一个 JSON 文件,顶层结构为{ "Version": ..., "Config": { "<产品名>": [规则列表] } }。各字段含义如下:

配置项类型含义是否必填补充说明生效条件
VersionString配置文件版本号是通常为时间戳,如20190101000000;类型定义见 00-common.md#5-version类型必须符合 Version 定义
ConfigObject各产品的 header 规则是Key 为产品名-
Config{k}String产品名是--
Config{v}Array该产品的 header 规则列表是--
Config{v}[]Object单条 header 规则是--
Config{v}[].CondString规则匹配条件是语法见 condition_grammar.md必须是合法的 Condition 表达式
Config{v}[].LastBoolean匹配后是否停止执行后续规则否默认false-
Config{v}[].ActionsArray匹配后要执行的动作列表是--
Config{v}[].Actions[].CmdString动作名称是取值见下文"模块动作"-
Config{v}[].Actions[].ParamsArray动作参数列表否参数个数与含义随动作而定,元素类型为 String-

源码中与之一一对应的数据结构定义在 header_rule_load.go:HeaderRuleFile(Cond/Actions/Last)、HeaderConfFile(Version/Config),以及加载后的运行时结构HeaderRule/HeaderConf。

规则级校验(HeaderRuleCheck)

HeaderConfLoad在解码 JSON 后会先做整体校验(header_rule_load.go),随后逐产品、逐规则调用HeaderRuleCheck(header_rule_load.go):

  • Cond为空 → 报错no Cond;
  • Actions为空(nil 或空切片)→ 报错no Actions;
  • 任一 Action 非法 → 报错并携带索引,如Actions:<err>;
  • Last未设置 → 报错no Last。

对应测试用例见 header_rule_load_test.go,其中构造了abnormalTypeNilCondition、abnormalTypeNilActions、abnormalTypeEmptyActions、abnormalTypeNilLast四类异常场景验证报错逻辑。

三、模块动作(Actions)详解

mod_header共提供 13 个动作,覆盖请求头、响应头、请求 Cookie、响应 Cookie 四个方向。参数个数与格式在加载期即被严格校验(见 action.go 的ActionFileCheck)。

动作说明参数参数要求(源码校验)
REQ_HEADER_SET设置请求头(已存在则覆盖)HeaderName, HeaderValue必须 2 个
REQ_HEADER_ADD追加请求头(不覆盖已有值)HeaderName, HeaderValue必须 2 个
REQ_HEADER_DEL删除请求头HeaderName必须 1 个
REQ_HEADER_RENAME重命名请求头OriginalHeaderName, NewHeaderName必须 2 个
RSP_HEADER_SET设置响应头HeaderName, HeaderValue必须 2 个
RSP_HEADER_ADD追加响应头HeaderName, HeaderValue必须 2 个
RSP_HEADER_DEL删除响应头HeaderName必须 1 个
RSP_HEADER_RENAME重命名响应头OriginalHeaderName, NewHeaderName必须 2 个
REQ_HEADER_MOD修改请求头(scheme_set / query_add)scheme_set/query_add, HeaderName, ...3 或 4 个,见下
RSP_HEADER_MOD修改响应头(scheme_set / query_add)scheme_set/query_add, HeaderName, ...3 或 4 个,见下
REQ_COOKIE_SET设置请求 CookieCookieName, CookieValue必须 2 个
REQ_COOKIE_DEL删除请求 CookieCookieName必须 1 个
RSP_COOKIE_SET设置响应 CookieName, Value, Domain, Path, Expires(RFC1123), MaxAge(int), HttpOnly(bool), Secure(bool)必须 8 个且类型正确
RSP_COOKIE_DEL删除响应 CookieName, Domain, Path必须 3 个

除个数校验外,还有几类更细化的约束:

  • 任意参数为空串即报错(empty Params),见 action.go;
  • Cookie 类型强校验:RSP_COOKIE_SET的Expires必须能被time.Parse(time.RFC1123, ...)解析,MaxAge必须为整数,HttpOnly/Secure必须为布尔串,否则加载失败(action.go);
  • 未识别的 Cmd 直接报错invalid cmd:%s(action.go)。

REQ/RSP_HEADER_MOD 的两种子命令

REQ_HEADER_MOD与RSP_HEADER_MOD不是简单的"覆盖",而是对头部值做结构化改写(action.go 的checkHeaderModParams与 action.go 的modHeaderValue):

  1. scheme_set:改写 URL 的协议头。

    • 参数:[scheme_set, HeaderName, scheme],共 3 个;
    • 仅支持Referer/Location两个头部;
    • scheme仅允许http/https;
    • 底层实现setScheme只替换http:///https://前缀后的 scheme 部分(action.go)。
    • 典型场景:["scheme_set", "Location", "https"]将 301 跳转的 Location 强制改为 https。
  2. query_add:在 URL 中追加 query 参数。

    • 参数:[query_add, HeaderName, key, value],共 4 个;
    • 同样仅支持Referer/Location;
    • 底层实现addQuery解析 URL 后追加key=value,已有 query 时用&拼接(action.go)。

注意:HEADER_MOD只在目标头部已存在且值非空时才生效;若头部不存在则直接跳过(action.go)。

四、动作的底层实现

所有 header 类动作最终收敛到 4 个原子操作(action_header.go):

底层函数行为对应动作
headerSeth.Set(key, value):插入或覆盖SET
headerAddh.Add(key, value):追加(保留多值)ADD
headerDelh.Del(key):删除DEL
headerRename先读原值Set(newKey, val)再Del(originalKey)RENAME

processHeader会把动作前缀REQ_/RSP_裁掉后分发到HeaderActionDo(action.go),并自动用textproto.CanonicalMIMEHeaderKey规范化头部名(如x-bfe-vip→X-Bfe-Vip)。RENAME在目标新头部已存在或原头部不存在时会跳过,避免覆盖已有值。

Cookie 动作的实现见 action_cookie.go:请求 Cookie 的 SET/DEL 会重建整个Cookie头并同步req.CookieMap;响应 Cookie 通过操作Set-Cookie头实现,SET 与 DEL 都会以(Name, Path, Domain)三元组判断目标 Cookie 是否存在,存在才覆盖/删除。

五、Header 值变量插值

动作参数值支持两种特殊写法(见 action.go 的preProcessParams与 action.go 的getHeaderValue):

  • %变量名:运行时替换为当前请求的对应信息;
  • %%变量名:转义为字面量%变量名(不做替换)。

可用的变量(注册于 action_header_var.go 的VariableHandlers映射)按类别整理如下:

类别变量
客户端信息bfe_client_ip、bfe_client_port、bfe_cip(client ip 别名)、bfe_request_host
连接与会话bfe_session_id、bfe_log_id、bfe_vip(虚拟 IP)、bfe_bip(负载均衡器 IP)、bfe_rip(BFE 本机 IP)、bfe_server_name
后端信息bfe_cluster、bfe_backend_info(格式ClusterName:..,SubClusterName:..,BackendName:..(addr))
TLS/协议bfe_ssl_resume、bfe_ssl_cipher、bfe_ssl_version、bfe_ssl_ja3_raw、bfe_ssl_ja3_hash、bfe_protocol、bfe_http2_fingerprint
客户端证书client_cert_serial_number、client_cert_subject_title、client_cert_subject_common_name、client_cert_subject_organization、client_cert_subject_organizational_unit、client_cert_subject_province、client_cert_subject_country、client_cert_subject_locality
地理信息(依赖 mod_geo)bfe_client_geo_country_iso_code、bfe_client_geo_subdivision_iso_code、bfe_client_geo_city_name、bfe_client_geo_latitude、bfe_client_geo_longitude

一个参数值中还可以混合普通文本与变量(如"__bsi=%bfe_ssl_info;max-age=3600"),splitParam会将其切分为多个片段再拼接(action.go)。若%后跟的变量名未注册,加载期即报错。

六、完整配置示例

原文档给出的完整示例(路径前缀为/header时,注入请求头X-Bfe-Log-Id、X-Bfe-Vip,并给响应加X-Proxied-By: bfe,且匹配后停止后续规则):

{ "Version": "20190101000000", "Config": { "example_product": [ { "cond": "req_path_prefix_in(\"/header\", false)", "actions": [ { "cmd": "REQ_HEADER_SET", "params": [ "X-Bfe-Log-Id", "%bfe_log_id" ] }, { "cmd": "REQ_HEADER_SET", "params": [ "X-Bfe-Vip", "%bfe_vip" ] }, { "cmd": "RSP_HEADER_SET", "params": [ "X-Proxied-By", "bfe" ] } ], "last": true } ] } }

仓库自带的默认配置见 conf/mod_header/header_rule.data(对example_product的/header路径设置响应头X-Proxied-By: bfe),对应的基础配置文件为 conf/mod_header/mod_header.conf,其中DataPath = mod_header/header_rule.data指向规则文件。

更多实用写法

  • 按域名/条件区分处理:cond可写任意合法 Condition,如req_host_in("example.com")、req_path_prefix_in("/api", true)、req_tag_in("tag1")等,语法参考 condition_grammar.md;
  • 一条规则多动作:Actions数组内按顺序执行,如先REQ_HEADER_DEL再REQ_HEADER_ADD;
  • 同值多头部:REQ_HEADER_ADD用于保留多值场景,REQ_HEADER_SET用于覆盖场景。

七、匹配执行逻辑与 Last 语义

mod_header对每个产品维护两张规则表(请求方向/响应方向),由classifyRules依据动作前缀REQ_/RSP_在加载期拆分(header_rule_load.go)。

运行时匹配逻辑位于DoHeader(mod_header.go):

for _, rule := range *ruleList { if rule.Cond.Match(req) { HeaderActionsDo(req, headerType, rule.Actions) if rule.Last { break // 停止执行后续规则 } } }

即:规则按数组顺序依次求值,命中则执行其全部动作;Last: true时命中后立即跳出,不再评估后面的规则(默认false继续向后匹配)。这与主流网关的"首匹配 + 短路"策略一致,可用来做"先特殊后兜底"的分层规则。

执行顺序上还有一个重要细节(mod_header.go):

  1. 先应用产品名为global(常量GlobalProduct)的全局规则;
  2. 再应用当前产品request.Route.Product的专属规则;
  3. 因此产品专属规则的 HEADER_SET 会覆盖 global 规则设置的同一头部,而 ADD 动作则会叠加。

另外,请求方向处理时若DisableDefaultHeader未开启,模块还会先写入默认头(X-Forwarded-For、X-Real-IP等),其开关见 mod_header.conf 文档。

八、加载、校验与热更新

加载流程

HeaderConfLoad(filename)的完整链路(header_rule_load.go):

  1. 打开并解码 JSON 文件;
  2. HeaderConfCheck校验 Version/Config 存在;
  3. ProductRulesCheck→RuleListCheck→HeaderRuleCheck逐层校验;
  4. ruleConvert用condition.Build(cond)把 Condition 字符串编译为可执行的condition.Condition,并把ActionFile转换为运行时Action(含头部名规范化、参数预处理);
  5. classifyRules按请求/响应方向拆表,存入ProductRules。

热更新机制

mod_header在初始化时注册了web_monitor.WebHandleReload回调(mod_header.go),因此可通过 BFE 的 Web Monitor 接口触发loadConfData重新加载规则文件(mod_header.go)。加载成功后调用HeaderTable.Update整体替换规则表,读路径使用读写锁保护(header_table.go),支持无中断热更新——这是线上流量场景下调整 header 策略的标准手段。

校验兜底

规则文件的合法性在加载期已被完整校验(Cond、Actions、Last、参数个数、Cookie 类型、变量名、scheme_set/query_add的约束等),任何一项不满足都会导致加载失败并返回带上下文的错误信息(如HeaderRule:0, Actions:...),配合mod_header.conf中的Log.OpenDebug可输出请求改写前后的完整头部对比日志。

九、小结

围绕mod_header.data,本文完整覆盖了:

  • 配置骨架:Version+Config{产品: [规则]},以及Cond/Last/Actions的语义与必填约束;
  • 13 个动作:请求/响应头与 Cookie 的 SET/ADD/DEL/RENAME/MOD,含参数个数与类型校验;
  • 变量插值:%bfe_log_id、%bfe_vip等 30+ 内置变量;
  • 运行机制:global 优先、产品覆盖、Last短路、按 REQ/RSP 方向拆表执行;
  • 运维能力:加载校验 + Web Monitor 热更新。

如需进一步了解模块基础配置,可阅读 mod_header.conf 文档;规则 Condition 的完整语法见 condition_grammar.md。生产环境建议先在 tests/integration 的测试样例中验证规则行为,再通过热更新接口灰度上线。

  • 后端
  • 网络/通信
  • 云原生

【免费下载链接】bfe

A modern layer 7 load balancer from baidu

项目地址:https://gitcode.com/gh_mirrors/bf/bfe
点击查看免费下载

相关推荐

上一篇:深度解析Linux内核GICv3中断控制器:ITS翻译表技术揭秘与实战配置
下一篇:实战部署ComfyUI Docker镜像:GPU云环境与本地开发的最优配置指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询