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 that denies anyone, trying to allow ingress access to the web server pod on any other port except 443. 

Scenario:  

A pod running a web-server should only be allowed ingress access on the port 443. 

template.yaml :
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sblockports
spec:
  crd:
    spec:
      names:
        kind: K8sBlockPorts
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            ports:
              type: array
              items: 
                type: integer
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |

        package k8sblockedports
        violation [{"msg": msg}] {
          input.review.object.spec.podSelector.matchLabels.app == "webserver"
          some i
          allowed := input.parameters.ports
          provided := input.review.object.spec.ingress[i].ports[i].port 
          provided != allowed[i]
          msg := "Applying Ingress rule for the provided port is not allowed"
        }

Understanding the REGO policy, 

Here, we define a schema for the parameter field. The parameters will be present inside the constraint.yaml file.

  • input.review.object.spec.podSelector.matchLabels.app == “webserver”(Checks if the pod to which the policy is being applied has the label ‘app: webserver.)
  • some i ( A variable to iterate through array)
  • allowed := input.parameters.ports  ( A variable allowed will save the value of the ports we provided as a parameter inside the constraing.yaml file)
  • provided := input.review.object.spec.ingress[i].ports[i].port (This will check for the port that has been provided by the user.)
  • provided != allowed[i] (Finally it will check if the provided value is present inside the constraint parameter.)
  • If it does not , then the NetworkPolicy will be rejected with a violation message.
constraint.yaml :
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockPorts
metadata:
  name: deny-ingress-ports
spec:
  match:
    kinds:
      - apiGroups: ["networking.k8s.io"]
        kinds: ["NetworkPolicy"]
  parameters:
    ports: [443]

 Since we defined the parameter as an object array, having the value integer. We have defined the parameter here with the value of 443. This means, any NetworkPolicy trying to allow ingress access to the webserver pod on any other port will be rejected.

Now, deploy the template and the constraint.

Template and constraint deployment.

NetworkPolicy Deny :

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-5000
spec:
  podSelector:
    matchLabels:
      app: webserver
  ingress:
  - ports:
    - port: 5000
 
Network policy denied.

NetworkPolicy Allow :

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-443
spec:
  podSelector:
    matchLabels:
      app: webserver
  ingress:
  - ports:
    - port: 443
Network policy allowed.

Conclusion :

This was a very basic example of apply OPA gatekeeper policies, which denied any NetworkPolicy which gave ingress access to the web-server on any other port except 443. We will be looking at more such policies in our future blog posts.

Other Related articles:

Practice here:

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

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: