本文介紹如何限制特定IP訪問網格內應用。
前提條件
已添加叢集到ASM執行個體,且ASM執行個體版本為1.15.3.25及以上。
已部署httpbin應用,且可以正常訪問。
使用說明
本文網關的externalTrafficPolicy均設定為Local。externalTrafficPolicy設定為Cluster無法保留源IP。
情境一:ASM網關之前不存在7層代理
執行以下命令,直接存取httpbin。
curl 47.111.XXX.XX:80/ -I用戶端實際IP為106.11.XX.X。從網關日誌可以看到downstream_remote_address和x_forwarded_for中的值都正確。此時,在網關上配置ipBlocks和remoteIpBlocks都可以生效。
從Sidecar側的訪問日誌可以看到x_forwarded_for中的值依然為用戶端真實IP。downstream_remote_address也是用戶端真實IP,但是丟失了連接埠資訊,顯示為0。
樣本一:網關側配置黑白名單
測試ipBlocks
使用以下內容,建立授權策略gateway-test.yaml。
您可以使用ASM安全性原則或網關的黑白名單簡化配置。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test namespace: istio-system spec: action: DENY rules: - from: - source: ipBlocks: - 106.11.XX.X selector: matchLabels: istio: ingressgateway執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.175.XX:XX/ -I預期輸出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 06:56:00 GMT server: istio-envoy
測試remoteIpBlocks
使用以下內容,建立授權策略gateway-test.yaml。
您可以使用ASM安全性原則或網關的黑白名單簡化配置。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test namespace: istio-system spec: action: DENY rules: - from: - source: remoteIpBlocks: - 106.11.XX.X selector: matchLabels: istio: ingressgateway執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.175.XX:XX/ -I預期輸出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 09:59:02 GMT server: istio-envoy
樣本二:Sidecar側配置黑白名單
測試ipBlocks
使用以下內容,建立授權策略gateway-test.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test namespace: default spec: action: DENY rules: - from: - source: ipBlocks: - 106.11.XX.X selector: matchLabels: app: httpbin執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.175.XX:XX/ -I預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Thu, 31 Aug 2023 10:14:01 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2從Sidecar側的訪問日誌可以看到,
downstream_remote_address是用戶端IP,但是沒有被攔截。downstream_remote_address並不完全等於ipBlocks中限制的欄位。ipBlocks限制“和當前代理直接建立TCP串連的用戶端IP”,所以真實發送過來的源IP是網關的Pod IP。downstream_remote_address是一個較為靈活的欄位,並不總是下遊的物理IP。downstream_remote_address表示下遊串連的遠端地址。如果該地址是一個IP地址,則它包含IP和連接埠。它不是遠端的真實物理地址,該地址可能來自於ProxyProtocol過濾器或x_forwarded_for要求標頭。您可以測試將
ipBlocks中的地址換成網關的Pod IP,配置後將無法訪問httpbin。
測試remoteIpBlocks
使用以下內容,建立授權策略gateway-test.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test namespace: default spec: action: DENY rules: - from: - source: remoteIpBlocks: - 106.11.XX.X selector: matchLabels: app: httpbin執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.XXX.XX:80/ -I預期輸出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 11:06:42 GMT server: istio-envoy x-envoy-upstream-service-time: 0remoteIpBlocks配置生效,因為x_forwarded_for中的值正常。
情境二:ASM網關之前存在7層代理
此情境下,ASM網關收到的請求中,x_forwarded_for要求標頭中應有預設值(由網關之前的7層代理提添加)。
到達網關之前的x_forwarded_for要求標頭應為56.5.X.X, 72.9.X.X, 98.1.X.X,最後的一個IP(106.11.XX.X)由ASM網關添加。downstream_remote_address表示與網關直接相連的對端IP(此時是真實的物理IP,所以是一個有效連接埠)。
從Sidecar的日誌可以看到,x_forwarded_for要求標頭和網關側相同。downstream_remote_address此時並不是真實的物理地址,而是來自於x_forwarded_for要求標頭的最後一個值(由於x_forwarded_for中只有IP,所以此處連接埠為0)。
下文不再測試ipBlocks欄位(該欄位表示對端真實物理IP),僅測試remoteIpBlocks欄位。這種情況下,需要將x_forwarded_for看作一個數組,此時限制“誰可以訪問ASM網關”,即限制上述日誌中x_forwarded_for的最後一個元素。
樣本一:配置remoteIpBlocks為x_forwarded_for中的最後一個地址
使用以下內容,建立授權策略gateway-test.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test-ap-wg-gateway-test-istio-system-gateway-ingressgateway namespace: istio-system spec: action: DENY rules: - from: - source: remoteIpBlocks: - 106.11.XX.X selector: matchLabels: istio: ingressgateway執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.175.XX:XX/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -I預期輸出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 11:50:36 GMT server: istio-envoy預期輸出表明成功限制
x_forwarded_for中的最後一個地址。
樣本二:設定網關的numTrustedProxies為2
在入口網關YAML的
spec欄位中添加如下配置。關於如何編輯入口網關,請參見通過ASM控制台管理入口網關。podAnnotations: proxy.istio.io/config: '{"gatewayTopology" : { "numTrustedProxies": 2 } }'說明該配置會導致網關重啟。
網關重啟後,執行以下命令,訪問httpbin。
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -I預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Thu, 31 Aug 2023 12:10:15 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2預期輸出表明訪問成功,
numTrustedProxies影響了remoteIpBlocks中的判斷結果。numTrustedProxies設定為2,表示網關會認為最靠近ASM網關的2個代理是可信的,第三近的代理不可信。因此,remoteIpBlocks限制第三近的代理IP。numTrustedProxies在不配置的情況下,預設值為0。
樣本三:授權策略中限制網關日誌x_forwarded_for的倒數第三個地址
使用以下內容,建立授權策略gateway-test.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test-ap-wg-gateway-test-istio-system-gateway-ingressgateway namespace: istio-system spec: action: DENY rules: - from: - source: remoteIpBlocks: - 72.9.X.X selector: matchLabels: istio: ingressgateway執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -I預期輸出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 12:38:09 GMT server: istio-envoy預期輸出表明成功限制
x_forwarded_for的倒數第三個地址。
樣本四:變更上述授權策略的生效範圍為httpbin應用
使用以下內容,建立授權策略gateway-test.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: gateway-test namespace: default spec: action: DENY rules: - from: - source: remoteIpBlocks: - 72.9.X.X selector: matchLabels: app: httpbin執行以下命令,部署授權策略。
kubectl apply -f gateway-test.yaml執行以下命令,訪問httpbin。
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -I預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Thu, 31 Aug 2023 12:39:36 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 6預期輸出表明訪問成功,授權策略規則失效。因為上述
numTrustedProxies是為網關配置的,Sidecar的numTrustedProxies預設值還是0,它會校正自己收到的x_forwarded_for要求標頭的最後一個值,因此沒有成功拒絕當前請求。您可以修改該授權策略中的
remoteIpBlocks為Sidecar日誌中x_forwarded_for的最後一個IP,即可看到訪問被拒絕。