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,
httpbinin 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 fooSee Source IP for Services with
Type=NodePortfor more information. Update the ingress gateway to setexternalTrafficPolicy: localto 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"}}'Follow the instructions in Determining the ingress IP and ports to define the
INGRESS_HOSTandINGRESS_PORTenvironment variables.Verify that the
httpbinworkload and ingress gateway are working as expected using this command:$ curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 200Verify 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":"$INGRESS_PORT"/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 theactionfield toALLOWto allow the IP addresses specified in theipBlocksto access the ingress gateway. IP addresses not in the list will be denied. TheipBlockssupports 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"] EOFVerify that a request to the ingress gateway is denied:
$ curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 403Update the
ingress-policyto 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"] EOFVerify that a request to the ingress gateway is allowed:
$ curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 200Update the
ingress-policyauthorization policy to set theactionkey toDENYso that the IP addresses specified in theipBlocksare 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"] EOFVerify that a request to the ingress gateway is denied:
$ curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 403You 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 fooRemove the authorization policy:
$ kubectl delete authorizationpolicy ingress-policy -n istio-system