Authorization on Ingress Gateway
This task shows you how to enforce access control on an Istio ingress gateway using an authorization policy.
An Istio authorization policy supports IP-based allow lists or deny lists as well as the attribute-based allow lists or deny lists previously provided by Mixer policy. The Mixer policy is deprecated in 1.5 and not recommended for production use.
Before you begin
Before you begin this task, do the following:
Read the Authorization conceptual documentation.
Install Istio using the Istio installation guide.
Deploy a workload,
httpbin
in a namespace, for examplefoo
, and expose it through the Istio ingress gateway with this command:$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin-gateway.yaml@) -n foo
See Source IP for Services with
Type=NodePort
for more information. Update the ingress gateway to setexternalTrafficPolicy: local
to preserve the original client source IP on the ingress gateway using the following command:$ kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'
Verify that the
httpbin
workload and ingress gateway are working as expected using this command:$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') $ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" 200
Verify the output of the following command to ensure the ingress gateway receives the original client source IP address, which will be used in the authorization policy:
$ CLIENT_IP=$(curl $INGRESS_HOST/ip -s | grep "origin" | cut -d'"' -f 4) && echo $CLIENT_IP 105.133.10.12
IP-based allow list and deny list
The following command creates the authorization policy,
ingress-policy
, for the Istio ingress gateway. The following policy sets theaction
field toALLOW
to allow the IP addresses specified in theipBlocks
to access the ingress gateway. IP addresses not in the list will be denied. TheipBlocks
supports both single IP address and CIDR notation. Create the authorization policy:$ kubectl apply -f - <<EOF 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: ipBlocks: ["1.2.3.4", "5.6.7.0/24"] EOF
Verify that a request to the ingress gateway is denied:
$ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" 403
Update the
ingress-policy
to include your client IP address:$ kubectl apply -f - <<EOF 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: ipBlocks: ["1.2.3.4", "5.6.7.0/24", "$CLIENT_IP"] EOF
Verify that a request to the ingress gateway is allowed:
$ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" 200
Update the
ingress-policy
authorization policy to set theaction
key toDENY
so that the IP addresses specified in theipBlocks
are not allowed to access the ingress gateway:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ingress-policy namespace: istio-system spec: selector: matchLabels: app: istio-ingressgateway action: DENY rules: - from: - source: ipBlocks: ["$CLIENT_IP"] EOF
Verify that a request to the ingress gateway is denied:
$ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" 403
You could use an online proxy service to access the ingress gateway using a different client IP to verify the request is allowed.
Clean up
Remove the namespace
foo
:$ kubectl delete namespace foo
Remove the authorization policy:
$ kubectl delete authorizationpolicy ingress-policy -n istio-system