配置 Gateway 网络拓扑

    许多应用程序需要知道发起源请求的客户端 IP 地址和证书信息才能正常工作。值得注意的是填充了客户端 IP 的日志、验证工具以及安全工具。例如 Web Application Firewalls (WAF),它应用这些信息来运行正确的规则集。 反向代理的主要工作内容是给服务提供客户端属性。为了向目的地的工作负载转发这些客户端属性,代理使用 X-Forwarded-For (XFF) 和 X-Forwarded-Client-Cert (XFCC) 头。

    如今的网络千差万别,无论网络拓扑结构如何,对这些多样化属性的支持都是必要的。 不管网络使用的是基于云的负载均衡、前置负载均衡、直接暴露在网络上的 Gateway、为许多中间代理服务的 Gateway,还是没有指定其他部署拓扑等,这些信息都是需要保存和转发。

    当 Istio 提供一个 Ingress Gateway,鉴于上述多样化架构的复杂性,无法提供合理的默认值,将客户端属性正确转发到目标工作负载。 随着 Istio 多集群部署模式越来越普遍,这个问题需要被越来越重视。

    了解关于 X-Forwarded-For 更多信息,参考 IETF 的 。

    XFF 和 XFCC 头的配置可以通过 MeshConfig 为所有 Gateway 工作负载进行全局设置,也可以通过使用 Pod 注释给每个 Gateway 配置。例如,在安装或者升级期间,使用 IstioOperator 自定义资源去配置全局设置:

    在您的 Istio Ingress Gateway Pod 的 Spec 通过添加 proxy.istio.io/config 注解可以来设置这两个配置。

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

    应用程序依靠反向代理来转发请求的客户端属性,如 X-Forwarded-For 头。然而由于 Istio 可以部署多样性的网络拓扑,您必须设置 Istio 网关代理上游的可信代理数量 numTrustedProxies ,这样才能正确提取客户端地址。因为它将控制 Ingress Gateway 在 X-Envoy-Eternal-Address 头中填充的值,该值可以被上游服务可靠地用于访问客户的原始 IP 地址。

    例如,如果在 Istio Gateway 之前,有一个基于云的负载均衡和一个反向代理,设置 numTrustedProxies2

    httpbin X-Forwarded-For 示例

    1. 运行一下命令去创建一个 topology.yaml 的文件,并且设置 numTrustedProxies2,然后安装 Istio:

      1. $ cat <<EOF > topology.yaml
      2. apiVersion: install.istio.io/v1alpha1
      3. kind: IstioOperator
      4. spec:
      5. meshConfig:
      6. defaultConfig:
      7. gatewayTopology:
      8. numTrustedProxies: 2
      9. EOF

      If you previously installed an Istio ingress gateway, restart all ingress gateway pods after step 1.

    2. 创建一个 命名空间:

    3. 启用 Sidecar 注入,设置 istio-injection 标签为 enabled

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

      1. $ kubectl apply -n httpbin -f samples/httpbin/httpbin.yaml
    5. 部署一个 httpbin 相关的 Gateway:

    6. 基于您的 Istio Ingress Gateway 设置一个本地环境变量 GATEWAY_URL

      1. $ export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    7. 运行下面的 curl 命令,模拟在 X-Forwarded-For 头中包含代理地址的请求:

      1. $ curl -H 'X-Forwarded-For: 56.5.6.7, 72.9.5.6, 98.1.2.3' $GATEWAY_URL/get?show_env=true
      2. {
      3. "args": {
      4. "show_env": "true"
      5. },
      6. "headers": {
      7. ...
      8. "X-Envoy-External-Address": "72.9.5.6",
      9. ...
      10. "X-Forwarded-For": "56.5.6.7, 72.9.5.6, 98.1.2.3, <YOUR GATEWAY IP>",
      11. },
      12. ...
      13. }

    配置 X-Forwarded-Client-Cert 头

    Envoy 文档 参考 XFCC:

    x-forwarded-client-cert(XFCC)是一个代理头,它表明了请求从客户端流向服务器的途中所流经的部分或全部客户端和代理的证书信息。代理商可以选择在代理请求之前对 XFCC 头进行清理/附加/转发。

    配置如何处理 XFCC 头文件,需要在 IstioOperator 中设置 forwardClientCertDetails

    其中ENUM_VALUE可以是以下类型:

    参考 ,了解并使用此功能的示例。

    PROXY 协议 允许在不依赖7层协议的情况下,在多个代理之间交换和保存客户端属性。

    如果外部负载均衡器使用 PROXY 协议,Istio Gateway 也必须配置接受 PROXY 协议。启用该功能需要在 Gateway 工作负载上使用 EnvoyFilter 添加 。示例:

    1. apiVersion: networking.istio.io/v1alpha3
    2. kind: EnvoyFilter
    3. metadata:
    4. name: proxy-protocol
    5. namespace: istio-system
    6. spec:
    7. configPatches:
    8. - applyTo: LISTENER
    9. patch:
    10. operation: MERGE
    11. value:
    12. listener_filters:
    13. - name: envoy.listener.proxy_protocol
    14. - name: envoy.listener.tls_inspector
    15. workloadSelector:
    16. labels:
    17. istio: ingressgateway

    客户端 IP 从 PROXY 协议中获取,并在 X-Forwarded-ForX-Envoy-External-Address 头中设置(或附加)。当 PROXY 协议与 gatewayTopology 配置一起使用时,确定可信客户地址时会优先使用 和接收到的 X-Forwarded-For 头。