-
Notifications
You must be signed in to change notification settings - Fork 13
[Security Hardened Kubernetes Cluster] Additional checks for namespaces marked for deletion #642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[Security Hardened Kubernetes Cluster] Additional checks for namespaces marked for deletion #642
Conversation
|
@georgibaltiev: The label(s) In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/hold |
|
/unhold |
4dc35e6 to
5256e60
Compare
AleksandarSavchev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Have some minor suggestions
| namespaceDeletionWithoutPodsMessage = "namespace is marked for deletion - no pods are deployed on it" | ||
| namespaceDeletionWithPodsMessage = "namespace is marked for deletion - there are still pods deployed on it" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| namespaceDeletionWithoutPodsMessage = "namespace is marked for deletion - no pods are deployed on it" | |
| namespaceDeletionWithPodsMessage = "namespace is marked for deletion - there are still pods deployed on it" | |
| namespaceDeletionWithoutPodsDetails = "namespace is marked for deletion with no present pods" | |
| namespaceDeletionWithPodsDetails = "namespace is marked for deletion with present pods" | |
| ingressTrafficNotDeniedMessage = "Ingress traffic is not denied by default." | |
| egressTrafficNotDeniedMessage = "Egress traffic is not denied by default." |
The "not denied by default" message is repeated several times, we can store it in a const.
| pods, err := kubeutils.GetPods(ctx, r.Client, namespace.Name, labels.NewSelector(), 300) | ||
| if err != nil { | ||
| checkResults = append(checkResults, rule.ErroredCheckResult(err.Error(), rule.NewTarget())) | ||
| break | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pods, err := kubeutils.GetPods(ctx, r.Client, namespace.Name, labels.NewSelector(), 300) | |
| if err != nil { | |
| checkResults = append(checkResults, rule.ErroredCheckResult(err.Error(), rule.NewTarget())) | |
| break | |
| } | |
| pods, err := kubeutils.GetPods(ctx, r.Client, namespace.Name, labels.NewSelector(), 300) | |
| if err != nil { | |
| return rule.Result(r, rule.ErroredCheckResult(err.Error(), target)), nil | |
| } |
We should return on errored CheckResult here. I think it would only error here if there is a problem with the client. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My assumption was based on the fact that there could be issues with the GetPods function, related to a specific namespace, for example the user not having permissions to access it, but I am not sure if those use cases are relevant, if even possible. This was my reasoning as to why I want to check all namespaces, even if one of them errors. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, the user might not have permissions for a specific namespace. On a side note the break here is not needed.
We tell the user to use an admin kubeconfig when running diki. Most likely there will be a lot of errored rules when such permissions are missing. I do not think we should cater to this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that makes sense.
| checkResults = append(checkResults, rule.ErroredCheckResult(err.Error(), rule.NewTarget())) | ||
| break | ||
| } | ||
| if len(pods) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if len(pods) > 0 { | |
| if len(pods) > 0 { |
| checkResults = append(checkResults, rule.FailedCheckResult("All Ingress traffic is allowed by default.", allowsAllIngressTarget)) | ||
| default: | ||
| case namespace.DeletionTimestamp == nil: | ||
| checkResults = append(checkResults, rule.FailedCheckResult("Ingress traffic is not denied by default.", target)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| checkResults = append(checkResults, rule.FailedCheckResult("Ingress traffic is not denied by default.", target)) | |
| checkResults = append(checkResults, rule.FailedCheckResult(ingressTrafficNotDeniedMessage, target)) |
- other applicable places.
| if err != nil { | ||
| checkResults = append(checkResults, rule.ErroredCheckResult(err.Error(), rule.NewTarget())) | ||
| break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: "deny-all", | ||
| Namespace: "plain-namespace", | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ObjectMeta: metav1.ObjectMeta{ | |
| Name: "deny-all", | |
| Namespace: "plain-namespace", | |
| }, | |
| ObjectMeta: metav1.ObjectMeta{ | |
| Name: "foo", | |
| Namespace: "plain-namespace", | |
| }, |
I see that most of the entries use the same name & namespace. We can have the ObjectMeta be set in the test func and only pass the Spec here.
| }, | ||
| }, | ||
| ), | ||
| Entry("should warn fail an allow-all network policy is configured for the ingress traffic and there are no pods present", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Entry("should warn fail an allow-all network policy is configured for the ingress traffic and there are no pods present", | |
| Entry("should fail when an allow-all network policy is configured for the ingress traffic and there are no pods present", |
| }, | ||
| }, | ||
| ), | ||
| Entry("should warn fail an allow-all network policy is configured for the egress traffic and there are no pods present", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Entry("should warn fail an allow-all network policy is configured for the egress traffic and there are no pods present", | |
| Entry("should fail when an allow-all network policy is configured for the egress traffic and there are no pods present", |
| &networkingv1.NetworkPolicy{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: "deny-all", | ||
| Namespace: "plain-namespace", | ||
| }, | ||
| Spec: networkingv1.NetworkPolicySpec{ | ||
| PolicyTypes: []networkingv1.PolicyType{ | ||
| "Ingress", | ||
| "Egress", | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can also have only the spec passed here.
How to categorize this PR?
/kind enhancement
What this PR does / why we need it:
This PR enhances the already present evaluation of a
Namespace' sNetworkPolicies, by checking if the namespace is marked for deletion with a.deletionTimestamp. If the namespace is marked for deletion, and has neither pods on it deployed nor anyallow-allnetwork policies, security finding results are marked asWarninginstead ofFailedWhich issue(s) this PR fixes:
Fixes #638
Special notes for your reviewer:
Release note: