IP Whitelisting with AuthorizationPolicy in EKS

The topic of IP whitelisting has been covered many times here, but the examples never quite work for me. Maybe because a lot of the examples assume Google Cloud/GKE? I’ve also noticed that most of the threads discussing IP whitelisting have a post telling everybody that Istio 1.5 deprecates Mixer.

I need the most basic IP whitelisting, only those on our local network. So would a single AuthorizationPolicy in the istio-system namespace be capable of this? Or must one also use an EnvoyFilter to do this?

Finally, all the docs which I’ve read indicate that the Istio Ingress must have externalTrafficPolicy set to Local. This setting makes my demo service flat-out stop working. Is it possible to get the IP whitelisting working without that setting? I suspect it may be because I have actually been able to see the IP I want to allow in the logs. The IP I whitelist comes through in a comma-separated list, so it seems like this would be sufficient to allow for the whitelisting. Especially if I were to write a little Lua in my EnvoyFilter.

But again, I can’t even tell if I’m supposed to use EnvoyFilter with AuthorizationPolicy…

Any pointers would be appreciated!

Finally, got something working, though not by using AuthorizationPolicy. Figured I would share this Yaml which finally made it work:

apiVersion: v1
kind: Service
metadata:
  name: httpbin
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
  type: NodePort
  ports:
  - port: 80
    name: http
    targetPort: 80
  selector:
    app: httpbin

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - image: docker.io/kennethreitz/httpbin
        name: httpbin
        ports:
        - containerPort: 80
          name: http

---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: rsl-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "*"
  gateways:
  - rsl-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: httpbin
      weight: 100

---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: rsl-envoyfilter
  namespace: istio-system
spec:
  workloadLabels:
    app: istio-ingressgateway
  filters:
    - listenerMatch:
        portNumber: 80
        listenerType: GATEWAY
      filterName: envoy.lua
      filterType: HTTP
      filterConfig:
        inlineCode: |
          function envoy_on_request(request_handle)
            local xff_header = request_handle:headers():get("X-Forwarded-For")
            local first_ip = string.gmatch(xff_header, "(%d+.%d+.%d+.%d+)")();
            first_ip = string.gsub(first_ip, ",", "")
            request_handle:headers():add("X-Custom-User-IP", first_ip);
          end

---
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
  name: rsl-whitelistip
spec:
  compiledAdapter: listchecker
  params:
    overrides:
      - <redacted>
      - <redacted>
    blacklist: false
    entryType: IP_ADDRESSES
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
  name: rsl-sourceip
spec:
  compiledTemplate: listentry
  params:
    value: request.headers["x-custom-user-ip"] | "0.0.0.0"
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: checkip
spec:
  match: source.labels["istio"] == "ingressgateway"
  actions:
  - handler: rsl-whitelistip
    instances: [ rsl-sourceip ]
2 Likes

oh yeah ! thanks for you, this method works !!!