為了對ASM的入口網關進行訪問保護,需要擷取用戶端真實IP,以便使用授權原則設定訪問入口網關的IP黑名單和白名單。本文介紹如何在HTTP要求標頭中擷取用戶端真實IP。
前提條件
已為命名空間注入Sidecar。具體操作,請參見啟用自動注入。
背景資訊
通常情況下,應用程式依靠反向 Proxy來轉寄請求中的用戶端屬性,例如X-Forwarded-For標題。但是由於Istio可以部署多種網路拓撲,除了直接使用負載平衡器CLB的公網地址訪問之外,也可能會在Web應用程式防火牆(WAF)接入入口網關地址,或者使用其他的未指定的部署拓撲來訪問入口網關地址。在支援各種部署架構的情況下,Service MeshASM無法提供一個固定的預設值,將用戶端屬性正確轉寄到目標工作負載,也就無法直接通過X-Forwarded-For擷取用戶端真實IP。
為瞭解決上述問題,您需要在ASM網關中將numTrustedProxies參數的值,配置為部署在網關代理前面的可受信的代理數量,以便正確擷取用戶端地址。控制入口網關在X-Envoy-External-Address標題中填充的值,以便上遊服務使用該值來訪問用戶端的原始IP地址。
操作步驟
部署樣本應用。
通過kubectl管理叢集和應用。具體操作,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集。
部署httpbin應用。
使用以下內容建立httpbin.yaml檔案。
執行以下命令,部署httpbin應用。
kubectl apply -f httpbin.yaml
建立ASM網關。
建立網關規則和虛擬服務。
通過API方式管理ASM執行個體。具體操作,請參見通過控制面kubectl訪問Istio資源。
建立網關規則。
使用以下內容,建立httpbin-gateway.yaml檔案。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
執行以下命令,建立網關規則。
kubectl apply -f httpbin-gateway.yaml
建立虛擬服務。
使用以下內容,建立httpbin-virtualservice.yaml檔案。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - "*" gateways: - httpbin-gateway http: - route: - destination: host: httpbin port: number: 8000
執行以下命令,建立虛擬服務。
kubectl apply -f httpbin-virtualservice.yaml
擷取httpbin應用的80連接埠的入口網關地址。具體操作,請參見建立入口網關服務。
在Web Application Firewall,接入步驟4擷取的入口網關的地址。具體操作,請參見使用教程。
為ASM網關添加numTrustedProxies參數。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇 。
在入口網關頁面的目標網關右側,單擊查看YAML。
在編輯對話方塊的spec參數下,添加以下內容,然後單擊確定。
podAnnotations: proxy.istio.io/config: '{"gatewayTopology" : { "numTrustedProxies": 2 } }'
根據實際的拓撲設定numTrustedProxies為部署在網關代理前面的可受信的代理數量。如果設定numTrustedProxies為一個大於零的值N,則可信用戶端地址為X-Forwarded-For右側起的第N+1個地址。
執行以下命令,訪問httpbin應用,擷取用戶端真實IP。
curl http://{入口網關地址}/get?show_env=true
預期輸出:
{ "args": { "show_env": "true" }, "headers": { "Accept": "*/*", .... "X-Envoy-Attempt-Count": "1", "X-Envoy-External-Address": "106.11.**.**", .... }, .... }
X-Envoy-External-Address的值即為用戶端真實IP。