'Restrict Ingress/Egress CIDR Ranges – OPA Gatekeeper NetworkPolicy
I am trying to deploy some Restrict Ingress/Egress CIDR Ranges through OPA gatekeeper network policy.
So first I have to create constrainttemplate which will apply any kind of ingress/egress access to any IP or IP CIDR ranges except the ones which are allowed with below yaml file:
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."
}
---
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"
Once after the deployment getting below error:
Target: admission.k8s.gatekeeper.sh
Status:
By Pod:
Errors:
Code: ingest_error
Message: Could not ingest Rego: 1 error occurred: __modset_templates["admission.k8s.gatekeeper.sh"]["K8sDenyEgress"]_idx_0:7: rego_type_error: net.cidr_contains: invalid argument(s)
have: (set[any], set[any], ???)
want: (string, string, boolean)
Id: gatekeeper-audit-54c9759898-xxdmd
Observed Generation: 1
Operations:
audit
status
Template UID: f29e2dd0-5918-48a7-b943-23f36b91690f
Errors:
Code: ingest_error
Message: Could not ingest Rego: 1 error occurred: __modset_templates["admission.k8s.gatekeeper.sh"]["K8sDenyEgress"]_idx_0:7: rego_type_error: net.cidr_contains: invalid argument(s)
have: (set[any], set[any], ???)
want: (string, string, boolean)
Id: gatekeeper-controller-manager-6bcc7f8fb5-fjbfq
Observed Generation: 1
Operations:
webhook
Template UID: f29e2dd0-5918-48a7-b943-23f36b91690f
Errors:
Code: ingest_error
Message: Could not ingest Rego: 1 error occurred: __modset_templates["admission.k8s.gatekeeper.sh"]["K8sDenyEgress"]_idx_0:7: rego_type_error: net.cidr_contains: invalid argument(s)
have: (set[any], set[any], ???)
want: (string, string, boolean)
Id: gatekeeper-controller-manager-6bcc7f8fb5-gwhrl
Observed Generation: 1
Operations:
webhook
Template UID: f29e2dd0-5918-48a7-b943-23f36b91690f
Errors:
Code: ingest_error
Message: Could not ingest Rego: 1 error occurred: __modset_templates["admission.k8s.gatekeeper.sh"]["K8sDenyEgress"]_idx_0:7: rego_type_error: net.cidr_contains: invalid argument(s)
have: (set[any], set[any], ???)
want: (string, string, boolean)
Id: gatekeeper-controller-manager-6bcc7f8fb5-sc67f
Observed Generation: 1
Operations:
webhook
Template UID: f29e2dd0-5918-48a7-b943-23f36b91690f
Created: true
Events: <none>
Could you please help out with resolving this error?
Solution 1:[1]
The function cidr_contains does not accept sets as parameters, see documentation. I used the function cidr_contains_matches instead as follows:
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"
egress_cidrs := { cidr | cidr := input.review.object.spec.egress[_].to[_].ipBlock.cidr}
whitelist_cidrs := { cidr | cidr := input.parameters.cidr[_]}
matches := net.cidr_contains_matches(whitelist_cidrs, egress_cidrs)
matched := { cidr | cidr := matches[_][1]}
not_matched := egress_cidrs - matched
count(not_matched) > 0
msg := sprintf("The network policy '%s' contains egress cidrs that are not contained in whitelist: %s", [input.review.object.metadata.name, not_matched])
}
violation [{"msg": msg}] {
input.review.object.kind == "NetworkPolicy"
not input.review.object.spec.egress[0].to
msg := sprintf("The network policy '%s' contains an empty egress (allow all), which is not permitted.", [input.review.object.metadata.name])
}
For those wondering how to check for errors:
kubectl describe constrainttemplate.templates.gatekeeper.sh/k8sdenyegress
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
