設定閘道網路拓撲
將外部用戶端屬性(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
。
使用 httpbin 的 X-Forwarded-For 功能範例
執行以下命令以建立一個名為
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
將
istio-injection
標籤設定為enabled
以啟用 sidecar 注入$ 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 標頭
若要配置如何處理 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 | 無論用戶端連線是否為 mTLS,都始終轉發請求中的 XFCC 標頭。 |
請參閱 Envoy 文件,以取得使用此功能的範例。
PROXY 協定
PROXY 協定允許在 TCP 代理伺服器之間交換和保留用戶端屬性,而無需依賴 HTTP 等 L7 協定以及 X-Forwarded-For
和 X-Envoy-External-Address
標頭。它適用於需要外部 TCP 負載平衡器透過 Istio 閘道將 TCP 流量代理到後端 TCP 服務,並且仍將來源 IP 等用戶端屬性暴露給上游 TCP 服務端點的情況。可以透過 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": {} }}'
用戶端 IP 是由閘道從 PROXY 協定中擷取的,並在 X-Forwarded-For
和 X-Envoy-External-Address
標頭中設定(或附加)。請注意,PROXY 協定與 X-Forwarded-For
和 X-Envoy-External-Address
等 L7 標頭互斥。當 PROXY 協定與 gatewayTopology
設定一起使用時,numTrustedProxies
和接收到的 X-Forwarded-For
標頭在決定受信任的用戶端位址時會優先考慮,並且 PROXY 協定用戶端資訊將被忽略。
請注意,上述範例僅設定閘道接受傳入的 PROXY 協定 TCP 流量 - 請參閱 Envoy 文件,以取得有關如何設定 Envoy 本身以使用 PROXY 協定與上游服務通訊的範例。