信息的透传

作为一个HTTP反向代理,BFE除了转发原始的HTTP请求之外,还会通过在HTTP Header中增加字段的方式向后端或用户传递一些额外的信息。

客户端IP地址的透传

需求来源

在经过BFE转发后,RS无法获得原始的客户端IP地址,而只能获得BFE实例的IP地址。

如下图所示,客户端的IP地址为1.2.3.4,在经过BFE转发后,BFE和RS建立了新的TCP连接,RS只能看到BFE的地址10.1.0.1。

problem of client ip

很多应用都需要获取请求原始的IP地址。需要提供机制将原始的IP地址传递到RS。

透传方案

BFE在扩展模块mod_header中默认提供了捎带客户端IP地址和端口的功能。只要在BFE启动时配置加载mod_header,在转发后请求中就会包含这两个信息。

在经过BFE转发后,在请求头部会增加2个字段:

  • X-Real-Ip:用于传递原始的客户端IP地址
  • X-Real-Port:用于传递原始的客户端端口

有些人可能会考虑从“X-Forwarded-For”来获取客户端的IP地址。BFE使用独立定义的“X-Real-Ip”是为了避免“X-Forwarded-For”被伪造。如果请求在到达BFE时已经包含了“X-Real-Ip”字段,BFE会将这个字段的值重写为BFE所见的客户端IP地址,从而避免这个字段被伪造。

其它信息的透传

除了客户端的IP地址和端口外,mod_header也提供对请求中加入其它信息的能力。

租户配置表

在mod_header中,可以对每个租户提供一张配置表,每条配置包括:

  • 匹配的条件:使用“条件表达式”(见“BFE的路由转发机制”)来描述

  • 执行的动作列表:在命中匹配条件后,可以执行1至多个动作

    可执行的动作见下面的介绍。

  • last:如果为true,则直接返回,不再匹配下面的规则

    和“转发表”(见“BFE的路由转发机制”)中“只会命中一次”的机制不同,在mod_header中一个请求可能同时命中多条规则,并执行多条规则对应的动作。在希望继续匹配其它规则的时候,可以将last设置为false。

mod_header conf

可能的动作

在mod_header中,对于请求和响应都可以执行设置、添加或删除操作。

在设置或添加的时候,需要提供头部字段的名称和取值。

动作名称含义参数列表说明
REQ_HEADER_SET设置请求头HeaderName, HeaderValue
REQ_HEADER_ADD添加请求头HeaderName, HeaderValue
REQ_HEADER_DEL删除请求头HeaderName
REQ_HEADER_RENAME重命名请求头HeaderName, HeaderName2
RSP_HEADER_SET设置响应头HeaderName, HeaderValue
RSP_HEADER_ADD添加响应头HeaderName, HeaderValue
RSP_HEADER_DEL删除响应头HeaderName
REQ_HEADER_RENAME重命名响应头HeaderName, HeaderName2

例子

下面是mod_header配置的一个例子。

针对example_product这个租户,只配置了一条规则。如果命中规则,则顺序执行3个动作,对请求头做2次设置,对响应头做1次设置。

在请求头中透传信息时,用户可以根据自己的需要来设置头部字段的名称。

{
    "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
            }
        ]
    }
}

内置变量

在上面的例子中,在设置"X-Bfe-Log-Id"和"X-Bfe-Vip"时,使用了内置的变量。在mod_header中还提供了其它内置变量,可以在设置Header时使用。

变量名含义依赖条件
%bfe_client_ip客户端IP
%bfe_client_port客户端端口
%bfe_request_host请求Host
%bfe_session_id会话ID
%bfe_log_id请求ID需要启用mod_logid
%bfe_cip客户端IP (CIP)
%bfe_vip服务端IP (VIP)
%bfe_server_nameBFE实例地址
%bfe_cluster目的后端集群
%bfe_backend_info后端信息
%bfe_ssl_resume是否TLS/SSL会话复用
%bfe_ssl_cipherTLS/SSL加密套件
%bfe_ssl_versionTLS/SSL协议版本
%bfe_ssl_ja3_rawTLS/SSL客户端JA3算法指纹数据
%bfe_ssl_ja3_hashTLS/SSL客户端JA3算法指纹哈希值
%bfe_protocol访问协议
%client_cert_serial_number客户端证书序列号
%client_cert_subject_title客户端证书Subject title
%client_cert_subject_common_name客户端证书Subject Common Name
%client_cert_subject_organization客户端证书Subject Organization
%client_cert_subject_organizational_unit客户端证书Subject Organizational Unit
%client_cert_subject_province客户端证书Subject Province
%client_cert_subject_country客户端证书Subject Country
%client_cert_subject_locality客户端证书Subject Locality