In this series of blog posts, we will be looking at deploying OPA gatekeeper as the admission controller for our Kubernetes cluster. We will be focusing specifically on creating gatekeeper policies for implementing Network Policy inside the Kubernetes cluster.

This article assumes that you are already familiar with installing OPA gatekeeper as the admission controller and also writing the gatekeeper policies. 

If you want to push the gatekeeper Audit logs to EFK, you can read the following article  on sending  logs to EFK.

Aim:

To write a gatekeeper policy that denies anyone, trying to apply any kind of egress rules to the ‘loadbalancer’ namespace.

Scenario:  

There is a namespace called ‘loadbalancer’ which has a replica set of 5 Nginx web servers running inside it.

Why do we need it?

This allows us to implement finer controls for the cluster. Again, following the principle of least privilege we make sure that only give access to a particular resource if it is needed.

template.yaml

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdenyegress
spec:
  crd:
    spec:
      names:
        kind: K8sDenyEgress
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdenyegress 
        violation [{"msg": msg}] {
          input.review.object.metadata.namespace == "loadbalancer"
          some i
          input.review.object.spec.policyTypes[i] == "Egress"
          msg := "You cannot apply Egress rules to the loadbalancer namespace."
 
        }

Understanding the REGO policy,

  • input.review.object.metadata.namespace == “loadbalancer” (Checks if the namespace is loadbalancer.)
  • Some i (A variable i which we will be used to iterate through the PolicyTypes array)
  • Input.review.object.spec.policyTypes[i] = “Egress” (Iterate through the policyTypes and check if Egress is present.)
  • If it does, then the NetworkPolicy will be rejected with a violation message.

constraint.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyEgress
metadata:
  name: denyegress
spec:
  match
    kinds:
      - apiGroups: ["networking.k8s.io"]
        kinds: ["NetworkPolicy"]

Since we have not defined any parameters in our template file, we won’t be using any here. One thing to remember is that the kind and the apiGroups should match the kind and the apiVersion of the deployment file. In our example that would be ‘NetworkPolicy’ and ‘networking.k8s.io.’

Now, deploy the template and the constraint.

Apply the template and the constraint.

Network Policy Deny :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
        name: allow
        namespace: loadbalancer
spec:
        podSelector:
                matchLabels:
        policyTypes:
                - Ingress
                - Egress
        ingress: []
        egress: []
 
Network policy denied by gatekeeper.

Network Policy Allow :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
        name: allow
        namespace: loadbalancer
spec:
        podSelector:
                matchLabels:
        policyTypes:
                - Ingress
        ingress: []
Network policy allowed by gatekeeper.

Conclusion : 

This was a basic example of using gatekeeper as a Validating admission webhook inside our cluster. In the next blog posts we will be looking at more scenarios to create gatekeeper policies for networking inside the Kubernetes cluster.

Other Related articles:

Practice here:

https://www.katacoda.com/cloudsecops/courses/opagatekeeper-policy/denyegress

References:

Thank you for reading! – Siddarth Tanna and Setu Parimi

Sign up for the blog directly here.

Check out our professional services here.

Feedback is welcome! For professional services, fan mail, hate mail, or whatever else, contact [email protected]


0 Comments

Leave a Reply

%d bloggers like this: