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 at creating gatekeeper policies for networking inside the Kubernetes cluster.

If you want to know how the Audit logs are sent to EFK, you can read the following article on sending the logs to EFK.

Aim:

Write a gatekeeper policy which denies anyone, trying to apply any kind of ingress/egress acesss to any IP or IP CIDR ranges except the ones which are allowed.

Template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdenyegress
spec:
  crd:
    spec:
      names:
        kind: K8sDenyEgress
      validation:
          openAPIV3Schema:
                  properties:
                        cidr:
                                type: array
                                items:
                                        type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdenyegress 
        violation [{"msg": msg}] {
            input.review.object.kind == "NetworkPolicy"
            cidr_or_ip :=  { ip | ip := input.review.object.spec.egress[_].to[_].ipBlock.cidr}
            cidr := { ip | ip := input.parameters.cidr[_]}
            value := net.cidr_contains(cidr, cidr_or_ip)
            not(value)
            msg := "The specified IP is not allowed."
        }

Understanding the REGO policy, 

  • In this template, we have defined a parameter in the ‘OPENAPIV3SCHEMA’. This parameter is of type array and data type string. The parameter will be included in our constraint file.
  • ‘input.review.object.kind == “NetworkPolicy” ‘ (Checks if the kind if NetworkPolicy)
  • Next, we take a variable cidr_or_ip and save the value of the IP CIDR provided in the NetworkPolicy.yaml.
  • Next, a variable cidr which stores the value of IP CIDR provided in the constraints file.
  • The Value cidr will store the result of ‘net.cidr_contains’ function.
  • net.cidr_contains(cidr,cidr_or_ip) is an inbuilt function in rego. CIDR will contain the allowed range and cidr_or_ip will contain the cidr or ip we want. It will check the value against cidr, and if it exists in the range, it will return true.
constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyEgress
metadata:
  name: deny-egress
spec:
  match:
    kinds:
      - apiGroups: ["networking.k8s.io"]
        kinds: ["NetworkPolicy"]
  parameters:
          cidr:
                  - "192.168.0.1/24"

Since, we defined a parameter in our template file, we will be including it in the parameters label. We have provided the IP CIDR of 192.168.0.1/24.

NetworkPolicy Deny :
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-external
spec:
  podSelector: {}
  policyTypes:
  - Egress
  - Ingress
  egress:
  - to:
    - ipBlock:
        cidr: 192.168.1.45/32
Network policy denied.
NetworkPolicy Allow :
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-external
spec:
  podSelector: {}
  policyTypes:
  - Egress
  - Ingress
  egress:
  - to:
    - ipBlock:
        cidr: 192.168.0.45/32
 


Network Policy allowed.

The Same can be used for ingress with some changes to the REGO code. We can use the following code in rego to get the Ipblock.

‘input.review.object.spec.ingress[_].from[_].ipBlock.cidr’

Conclusion : 

This was a very basic example of applying OPA gatekeeper, to deny anyone trying to allow ingress/egress access to an IP or IP CIDR range which is not allowed.

Other related articles:

Practice here:

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

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: