配置网关网络拓扑
将外部客户端属性(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 的示例
运行以下命令以创建一个名为
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
创建一个
httpbin
命名空间$ kubectl create namespace httpbin namespace/httpbin created
为 sidecar 注入设置
istio-injection
标签为enabled
。$ kubectl label --overwrite namespace httpbin istio-injection=enabled namespace/httpbin labeled
在
httpbin
命名空间中部署httpbin
。$ kubectl apply -n httpbin -f @samples/httpbin/httpbin.yaml@
部署与
httpbin
关联的网关
$ kubectl apply -n httpbin -f @samples/httpbin/httpbin-gateway.yaml@
$ kubectl apply -n httpbin -f @samples/httpbin/gateway-api/httpbin-gateway.yaml@
$ kubectl wait --for=condition=programmed gtw -n httpbin httpbin-gateway
- 根据 Istio 入口网关的 IP 地址设置本地
GATEWAY_URL
环境变量。
$ export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export GATEWAY_URL=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -n httpbin -ojsonpath='{.status.addresses[0].value}')
运行以下
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-For
和X-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-For
和X-Envoy-External-Address
头部中设置(或附加)它。请注意,PROXY 协议与 L7 头部(如X-Forwarded-For
和X-Envoy-External-Address
)互斥。当 PROXY 协议与gatewayTopology
配置一起使用时,numTrustedProxies
和接收到的X-Forwarded-For
头部优先于确定受信任的客户端地址,并且将忽略 PROXY 协议客户端信息。
请注意,以上示例仅配置网关以接受传入的 PROXY 协议 TCP 流量 - 有关如何配置 Envoy 本身以使用 PROXY 协议与上游服务通信的示例,请参阅Envoy 文档。