How to create a whitelist in Istio's AuthorizationPolicy?

I deployed istio in kubernetes on AWS EKS as

istioctl install \
--set profile=demo \
--set values.gateways.istio-ingressgateway.type=NodePort

Then deployed some gateway and virtualservices:

I want only allowed IPs access my website, so tried this

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ingress-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
       remoteIpBlocks: ["ALLOWED IP"]

But it blocked all IPs. When access the website got RBAC access denied.

From Istio’s ingress gateway log got

...
2021-12-21T03:36:41.819072Z     debug   envoy rbac      checking request: requestedServerName: , sourceIP: 10.123.45.111:25965, directRemoteIP: 10.123.45.111:25965, remoteIP: 10.123.45.111:25965,localAddress: 10.123.46.222:8443, ssl: uriSanPeerCertificate: , dnsSanPeerCertificate: , subjectPeerCertificate: , headers: ':authority', '10.123.45.111:30974'
':path', '/healthz/ready'
':method', 'GET'
':scheme', 'https'
'user-agent', 'ELB-HealthChecker/2.0'
'accept-encoding', 'gzip, compressed'
'x-forwarded-for', '10.123.45.111'
'x-forwarded-proto', 'https'
'x-envoy-internal', 'true'
'x-request-id', '123412231a-cb12-9732-859e-0213jladfsj9'
'x-envoy-decorator-operation', 'demo-service.default.svc.cluster.local:80/*'
, dynamicMetadata:
2021-12-21T03:36:41.819091Z     debug   envoy rbac      enforced allowed, matched policy none

I didn’t use RBAC yet, it seems envoy’s rbac matched policy none. Is that the reason? How to set a policy for it?

matched policy none. this means none of the policies are matched for the current request and it is rejected by default, this is because you used the ALLOW action in the policy which means only requested matched will be allowed.

Are you trying to match the IP in 'x-forwarded-for', '10.123.45.111'? Please make sure you followed the task Istio / Ingress Gateway, especially the numTrustedProxies configuration part.

Thank you for your comment.

Are you trying to match the IP in 'x-forwarded-for', '10.123.45.111' ?

Where to set it? I’m using alb-ingress-controller for AWS. Should I set header in its annotations?

About numTrustedProxies, I found this example Source IP address of the original client for HTTP/HTTPS Load Balancer.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogEncoding: JSON
    accessLogFile: /dev/stdout
    defaultConfig:
      gatewayTopology:
        numTrustedProxies: 1

But it shown AWS EKS’ Load Balancer Type is

Cloud Provider Load Balancer Name Load Balancer Type
AWS EKS Classic Elastic Load Balancer TCP Proxy

Hi Tian, regarding Yangmin’s comment

Are you trying to match the IP in 'x-forwarded-for', '10.123.45.111' ?

I think it means if you want to specify this ip 10.123.45.111 within the field of remoteIpBlocks

spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
       remoteIpBlocks: ["ALLOWED IP"]

If 10.123.45.111 is not the original client IP address which should be allowed, there is some details on configuring numTrustedProxies Istio / Configuring Gateway Network Topology

I created some resource by the guide above. I got nothing when did this step:

export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $GATEWAY_URL

This command returned

$ kubectl -n istio-system get service istio-ingressgateway
NAME                   TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
istio-ingressgateway   NodePort   170.10.123.110   <none>        15021:32174/TCP,80:30481/TCP,443:30370/TCP,31400:30700/TCP,15443:31837/TCP   21h

I also can’t get CLIENT_ID by this command

$ CLIENT_IP=$(kubectl get pods -n istio-system -o name -l istio=ingressgateway | sed 's|pod/||' | while read -r pod; do kubectl logs "$pod" -n istio-system | grep remoteIP; done | tail -1 | awk -F, '{print $4}' | awk -F: '{print $2}' | sed 's/ //') && echo "$CLIENT_IP"

Ref: IP-based allow list and deny list

Is it because that my installation using NodePort type?