Search code examples
kubernetesauthorizationazure-aksistioetcd

Istio Authorization Policy for peer authorization


I am trying to create authorization policy for etcd peer pods with envoy sidecar to authorize to access port 2380 and deny any other pod in the cluster trying to access the peer port. These pods are under a same service.

I tried adding hosts (*.etcd-cluster.ns.svc) to the when condition in the authorization policy that if hosts don't match in the request, the request needs to be denied. But, with istio hosts will change as envoy would pass the traffic and it is not working.

How can I setup a simple authorization policy that specific to etcd for authorize and allow etcd peer pods communication and deny rest of the pods if tried to access?


Solution

  • To implement the Istio AuthorizationPolicy that allows etcd peer pods to communicate on port 2380 and denies access to any other pods, you would need to create an AuthorizationPolicy resource in the same namespace where your etcd pods are running.

    Below is an example of what the policy might look like. But before that ensure below things

    Identify the Etcd Pods: Ensure that your etcd pods can be distinctly identified by labels or service accounts. If they are not already labeled or using a specific service account, you will need to set this up.

    Create Service Accounts for Etcd Pods (if necessary): If they don't already exist, create dedicated Kubernetes ServiceAccounts for your etcd pods. This will allow you to create an authorization policy based on the source.principal.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: etcd-peer
      namespace: ns
    

    Apply it with kubectl apply -f <filename>.yaml. enter image description here

    Update your etcd deployment configurations to use the newly created service accounts.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: etcd-cluster
      namespace: ns  # replace with the actual namespace where the etcd pods should run
    spec:
      selector:
        matchLabels:
          app: etcd-cluster  # these labels should match the labels in template.metadata.labels
      replicas: 3  # set the number of etcd replicas
      template:
        metadata:
          labels:
            app: etcd-cluster  # these labels should match the labels in spec.selector.matchLabels
        spec:
          serviceAccountName: etcd-peer  # the service account created for etcd
          containers:
          - name: etcd
            image: etcd:latest  # replace with the actual etcd image you want to use
            ports:
            - containerPort: 2380
    
    

    Again, apply with kubectl apply -f <filename>.yaml.

    enter image description here

    Create the Istio AuthorizationPolicy that allows communication to port 2380 only if it comes from pods with the etcd-peer ServiceAccount.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: etcd-peer-authz
      namespace: ns  # Replace 'ns' with the actual namespace of the etcd pods
    spec:
      selector:
        matchLabels:
          app: etcd-cluster  # Replace with actual labels of the etcd pods
      action: ALLOW
      rules:
      - to:
        - operation:
            ports: ["2380"]
        when:
        - key: source.namespace
          values: ["ns"]  # Replace 'ns' with the actual namespace of the etcd pods
        - key: source.principal
          values: ["cluster.local/ns/ns/sa/etcd-peer"]  
    

    enter image description here

    This policy does the following:

    • It applies to pods with the label app: etcd-cluster within the namespace ns.
    • It allows traffic to port 2380 if it originates from the same namespace.
    • It uses the source.principal field to restrict access based on the service account of the originating pod. This assumes that your etcd pods have a unique service account or principal that can be identified by Istio.

    References: