設定閘道網路拓撲

將外部用戶端屬性(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 功能範例

  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. istio-injection 標籤設定為 enabled 以啟用 sidecar 注入

    $ 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無論用戶端連線是否為 mTLS,都始終轉發請求中的 XFCC 標頭。

請參閱 Envoy 文件,以取得使用此功能的範例。

PROXY 協定

PROXY 協定允許在 TCP 代理伺服器之間交換和保留用戶端屬性,而無需依賴 HTTP 等 L7 協定以及 X-Forwarded-ForX-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-ForX-Envoy-External-Address 標頭中設定(或附加)。請注意,PROXY 協定與 X-Forwarded-ForX-Envoy-External-Address 等 L7 標頭互斥。當 PROXY 協定與 gatewayTopology 設定一起使用時,numTrustedProxies 和接收到的 X-Forwarded-For 標頭在決定受信任的用戶端位址時會優先考慮,並且 PROXY 協定用戶端資訊將被忽略。

請注意,上述範例僅設定閘道接受傳入的 PROXY 協定 TCP 流量 - 請參閱 Envoy 文件,以取得有關如何設定 Envoy 本身以使用 PROXY 協定與上游服務通訊的範例。

此資訊是否有用?
您有任何改進建議嗎?

感謝您的意見反應!