This topic describes how to restrict specific IP addresses from accessing applications in a Service Mesh (ASM) instance.
Prerequisites
A cluster is added to an ASM instance of v1.15.3.25 or later. For more information, see Add a cluster to an ASM instance.
Automatic sidecar proxy injection is enabled. For more information, see Enable automatic sidecar proxy injection.
The HTTPBin application is deployed and can be accessed. For more information, see Deploy the HTTPBin application.
Usage notes
In this example, the externalTrafficPolicy field of the gateway is set to Local. If the externalTrafficPolicy field is set to Cluster, source IP addresses are not preserved.
Scenario 1: No Layer 7 proxy is deployed between the client that initiates requests to access applications in the ASM instance and the ASM gateway
Run the following command to access the HTTPBin application:
curl 47.111.XXX.XX:80/ -IThe actual IP address of the client is 106.11.XX.X. You can see that the values of the downstream_remote_address and x_forwarded_for fields are correct in the gateway logs. In this case, the configurations of ipBlocks and remoteIpBlocks on the gateway can take effect.
You can see that the value of the x_forwarded_for field in the access logs of the sidecar proxy is the actual IP address of the client. The value of the downstream_remote_address field is also the actual IP address of the client, but the port information is lost and displayed as 0.
Example 1: Configure a blacklist or whitelist on the gateway
Test ipBlocks
Use the following content to create an authorization policy named gateway-test.yaml.
You can use ASM security policies or the blacklist or whitelist of the gateway to simplify configurations.
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: ingressgatewayRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.175.XX:XX/ -IExpected output:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 06:56:00 GMT server: istio-envoy
Test remoteIpBlocks
Use the following content to create an authorization policy named gateway-test.yaml.
You can use ASM security policies or the blacklist or whitelist of the gateway to simplify configurations.
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: ingressgatewayRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.175.XX:XX/ -IExpected output:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 09:59:02 GMT server: istio-envoy
Example 2: Configure a blacklist or whitelist on the sidecar proxy
Test ipBlocks
Use the following content to create an authorization policy named 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: httpbinRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.175.XX:XX/ -IExpected output:
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: 2You can see that the value of the
downstream_remote_addressfield in the access logs of the sidecar proxy is the client IP address, which is not blocked.The value of
downstream_remote_addressis not always an IP address specified in theipBlocksfield. TheipBlocksfield specifies the IP addresses of the clients that are not allowed to directly establish TCP connections with the current proxy. In this case, the actual source IP addresses of the TCP connections are the pod IP addresses of the gateway.downstream_remote_addressis a flexible field and its value is not always the physical IP address of the downstream connection.The
downstream_remote_addressfield indicates the remote address of the downstream connection. If the address is an IP address, it contains the IP address and port. It may not be the real physical address of the remote end. The address may be inferred from the Proxy Protocol filter or anx_forwarded_forrequest header.You can replace the address in the
ipBlocksfield with the pod IP address of the gateway. After the configuration, you cannot access the HTTPBin application.
Test remoteIpBlocks
Use the following content to create an authorization policy named 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: httpbinRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.XXX.XX:80/ -IExpected output:
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: 0The
remoteIpBlocksconfiguration takes effect. In this case, the value of thex_forwarded_forfield is the same as the value of the downstream_remote_address field.
Scenario 2: A Layer 7 proxy is deployed between the client that initiates requests to access applications in the ASM instance and the ASM gateway
In this scenario, the x_forwarded_for request header in the requests received by the ASM gateway should have a default value, which is added by the Layer 7 proxy.
Before the requests reach the ASM gateway, the value of the x_forwarded_for request header should be 56.5.X.X, 72.9.X.X, 98.1.X.X. The last IP address 106.11.XX.X is added by the ASM gateway. downstream_remote_address indicates the IP address of the peer end that directly connects to the gateway. In this case, it is a physical IP address and contains a valid port.
The logs of the sidecar proxy indicate that the value of the x_forwarded_for request header is the same as that of the gateway. The value of downstream_remote_address is not the actual physical address. It is the last IP address in the value of the x_forwarded_for request header. (The x_forwarded_for field contains only IP addresses. Therefore, the port here is 0.)
The following section does not test the ipBlocks field (this field indicates the actual physical IP address of the peer end). Only the remoteIpBlocks field is tested. In this case, you need to treat the x_forwarded_for field as an array. It rejects an IP address from accessing the ASM gateway. The last IP address in x_forwarded_for in the preceding logs is not allowed to access the ASM gateway.
Example 1: Set remoteIpBlocks to the last IP address in the x_forwarded_for field
Use the following content to create an authorization policy named 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: ingressgatewayRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.175.XX:XX/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -IExpected output:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 11:50:36 GMT server: istio-envoyThe output indicates that the last IP address in the
x_forwarded_forfield is not allowed to access the ASM gateway.
Example 2: Set the numTrustedProxies field of the ingress gateway to 2
Add the following configuration to the
specfield in the YAML file of the ingress gateway. For more information about how to edit the YAML file of an ingress gateway, see Manage the ingress gateway in the ASM console.podAnnotations: proxy.istio.io/config: '{"gatewayTopology" : { "numTrustedProxies": 2 } }'NoteThis configuration causes the gateway to restart.
After the gateway is restarted, run the following command to access the HTTPBin application:
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -IExpected output:
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: 2The output indicates that the access is successful and the value of the
numTrustedProxiesfield affects the judgment results of theremoteIpBlocksfield.When
numTrustedProxiesis set to2, the ASM gateway considers the two proxies closest to itself to be trusted and the third closest proxy to be untrustworthy. Therefore, theremoteIpBlocksfield rejects the IP address of the third closest proxy from accessing the gateway. IfnumTrustedProxiesis not set, the default value is 0.
Example 3: Use an authorization policy to reject access from the third-to-last IP address in the x_forwarded_for field of the gateway logs
Use the following content to create an authorization policy named 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: ingressgatewayRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -IExpected output:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Thu, 31 Aug 2023 12:38:09 GMT server: istio-envoyThe output indicates that access from the third-to-last IP address specified in the
x_forwarded_forfield is rejected.
Example 4: Change the effective scope of the preceding authorization policy to the HTTPBin application
Use the following content to create an authorization policy named 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: httpbinRun the following command to deploy the authorization policy:
kubectl apply -f gateway-test.yamlRun the following command to access the HTTPBin application:
curl 47.111.XXX.XX:80/ -H 'X-Forwarded-For: 56.5.X.X, 72.9.X.X, 98.1.X.X' -IExpected output:
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: 6The output indicates that the access is successful and the authorization policy is invalid. The preceding
numTrustedProxiesfield is configured for the gateway. The default value ofnumTrustedProxiesfor the sidecar proxy is still 0. The sidecar proxy verifies the last IP address of the receivedx_forwarded_forrequest header. Therefore, the request is not rejected.If you change the value of
remoteIpBlocksin the authorization policy to the last IP address ofx_forwarded_forin the sidecar proxy logs, the access is rejected.