The problem for external IPs is that source.ip
contains the IP of the ingress gateway pod, and not the real IP. When the request passes though the ingress gateway, a header x-envoy-external-address
is added to the request. It is not injected when the request comes from the internal network though. So you have to filter in the match to avoid some nil
error
My configuration is the following trying to map yours :
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: blacklistip
namespace: istio-system
spec:
compiledAdapter: listchecker
params:
blacklist: false
entryType: IP_ADDRESSES
overrides:
- 0.0.0.25/8
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: sourceip-blacklist
namespace: istio-system
spec:
compiledTemplate: listentry
params:
value: request.headers["x-envoy-external-address"] | "0.0.0.0"
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: sourceip-blacklist
namespace: istio-system
spec:
actions:
- handler: blacklistip
instances:
- sourceip
match: (source.labels["istio"] | "") == "ingressgateway" && (request.headers["x-envoy-external-address"] | "") !=""
Also, the external traffic policy has to be set for ingress-gaterway. Using helm, I set it with :
--set gateways.istio-ingressgateway.externalTrafficPolicy=Local
Hope this helps