配置网关网络拓扑

将外部客户端属性(IP 地址、证书信息)转发到目标工作负载

许多应用程序需要了解源请求的客户端 IP 地址和证书信息才能正常运行。值得注意的案例包括需要填充客户端 IP 的日志和审计工具,以及需要此信息才能正确应用规则集的安全工具(例如 Web 应用防火墙 (WAF))。为服务提供客户端属性的能力长期以来一直是反向代理的基本功能。为了将这些客户端属性转发到目标工作负载,代理使用X-Forwarded-For (XFF) 和X-Forwarded-Client-Cert (XFCC) 头部。

当今的网络性质差异很大,但无论网络拓扑结构如何,对这些属性的支持都是一项要求。无论网络使用基于云的负载均衡器、本地负载均衡器、直接暴露于互联网的网关、服务于许多中间代理的网关还是其他未指定的部署拓扑,都应保留并转发此信息。

虽然 Istio 提供了一个入口网关,但鉴于上述各种架构,无法提供支持将客户端属性正确转发到目标工作负载的合理默认值。随着 Istio 多集群部署模型变得越来越普遍,这一点变得越来越重要。

有关X-Forwarded-For的更多信息,请参阅 IETF 的RFC

配置网络拓扑

XFF 和 XFCC 头部的配置可以通过MeshConfig全局设置为所有网关工作负载,或者使用 Pod 注解按网关进行设置。例如,在使用IstioOperator自定义资源时,在安装或升级期间全局配置

spec:
  meshConfig:
    defaultConfig:
      gatewayTopology:
        numTrustedProxies: <VALUE>
        forwardClientCertDetails: <ENUM_VALUE>

您还可以通过将proxy.istio.io/config注释添加到 Istio 入口网关的 Pod 规范来配置这两个设置。

...
  metadata:
    annotations:
      "proxy.istio.io/config": '{"gatewayTopology" : { "numTrustedProxies": <VALUE>, "forwardClientCertDetails": <ENUM_VALUE> } }'

配置 X-Forwarded-For 头部

应用程序依赖于反向代理来转发请求中的客户端属性,例如X-Forward-For头部。但是,由于 Istio 可以部署在各种网络拓扑中,因此您必须将numTrustedProxies设置为部署在 Istio 网关代理前面的受信任代理的数量,以便能够正确提取客户端地址。这控制着入口网关在X-Envoy-External-Address头部中填充的值,上游服务可以使用此头部可靠地访问客户端的原始 IP 地址。

例如,如果您在 Istio 网关前面有一个基于云的负载均衡器和一个反向代理,请将numTrustedProxies设置为2

使用 X-Forwarded-For 功能与 httpbin 的示例

  1. 运行以下命令以创建一个名为topology.yaml的文件,其中numTrustedProxies设置为2,并安装 Istio

    $ cat <<EOF > topology.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    spec:
      meshConfig:
        defaultConfig:
          gatewayTopology:
            numTrustedProxies: 2
    EOF
    $ istioctl install -f topology.yaml
    
  2. 创建一个httpbin命名空间

    $ kubectl create namespace httpbin
    namespace/httpbin created
    
  3. 为 sidecar 注入设置istio-injection标签为enabled

    $ kubectl label --overwrite namespace httpbin istio-injection=enabled
    namespace/httpbin labeled
    
  4. httpbin命名空间中部署httpbin

    压缩
    $ kubectl apply -n httpbin -f @samples/httpbin/httpbin.yaml@
    
  5. 部署与httpbin关联的网关

压缩
$ kubectl apply -n httpbin -f @samples/httpbin/httpbin-gateway.yaml@
  1. 根据 Istio 入口网关的 IP 地址设置本地GATEWAY_URL环境变量。
$ export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  1. 运行以下curl命令以模拟在X-Forwarded-For头部中带有代理地址的请求。

    $ curl -s -H 'X-Forwarded-For: 56.5.6.7, 72.9.5.6, 98.1.2.3' "$GATEWAY_URL/get?show_env=true" | jq '.headers["X-Forwarded-For"][0]'
      "56.5.6.7, 72.9.5.6, 98.1.2.3,10.244.0.1"
    

以上输出显示了httpbin工作负载接收到的请求头部。当 Istio 网关收到此请求时,它将X-Envoy-External-Address头部设置为来自您的 curl 命令的X-Forwarded-For头部中倒数第二个 (numTrustedProxies: 2) 地址。此外,网关在将其转发到 httpbin 工作负载之前,会将其自己的 IP 附加到X-Forwarded-For头部。

配置 X-Forwarded-Client-Cert 头部

来自Envoy 的文档关于 XFCC 的内容

要配置如何处理 XFCC 头部,请在您的IstioOperator中设置forwardClientCertDetails

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      gatewayTopology:
        forwardClientCertDetails: <ENUM_VALUE>

其中ENUM_VALUE可以是以下类型。

ENUM_VALUE
UNDEFINED字段未设置。
SANITIZE不要将 XFCC 头部发送到下一个跳跃点。
FORWARD_ONLY当客户端连接为 mTLS(双向 TLS)时,转发请求中的 XFCC 头部。
APPEND_FORWARD当客户端连接为 mTLS 时,将客户端证书信息附加到请求的 XFCC 头部并转发。
SANITIZE_SET当客户端连接为 mTLS 时,使用客户端证书信息重置 XFCC 头部并将其发送到下一个跳跃点。这是网关的默认值。
ALWAYS_FORWARD_ONLY始终转发请求中的 XFCC 头部,而不管客户端连接是否为 mTLS。

有关使用此功能的示例,请参阅Envoy 文档

PROXY 协议

PROXY 协议允许在 TCP 代理之间交换和保留客户端属性,而无需依赖于 HTTP 等 L7 协议以及X-Forwarded-ForX-Envoy-External-Address头部。它适用于外部 TCP 负载均衡器需要通过 Istio 网关将 TCP 流量代理到后端 TCP 服务,并且仍然向上游 TCP 服务端点公开客户端属性(如源 IP)的场景。可以通过EnvoyFilter启用 PROXY 协议。

如果您的外部 TCP 负载均衡器配置为转发 TCP 流量并使用 PROXY 协议,则 Istio 网关 TCP 侦听器也必须配置为接受 PROXY 协议。要在网关上的所有 TCP 侦听器上启用 PROXY 协议,请在您的IstioOperator中设置proxyProtocol。例如

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      gatewayTopology:
        proxyProtocol: {}

或者,部署具有以下 Pod 注解的网关

metadata:
  annotations:
    "proxy.istio.io/config": '{"gatewayTopology" : { "proxyProtocol": {} }}'

网关从 PROXY 协议中检索客户端 IP,并在X-Forwarded-ForX-Envoy-External-Address头部中设置(或附加)它。请注意,PROXY 协议与 L7 头部(如X-Forwarded-ForX-Envoy-External-Address)互斥。当 PROXY 协议与gatewayTopology配置一起使用时,numTrustedProxies和接收到的X-Forwarded-For头部优先于确定受信任的客户端地址,并且将忽略 PROXY 协议客户端信息。

请注意,以上示例仅配置网关以接受传入的 PROXY 协议 TCP 流量 - 有关如何配置 Envoy 本身以使用 PROXY 协议与上游服务通信的示例,请参阅Envoy 文档

此信息是否有用?
您对改进有什么建议?

感谢您的反馈!