Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 57 additions & 38 deletions example/config/managedk8s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,22 @@ providers: # contains information about known providers
# justification: "the whole rule is accepted for ... reasons"
# args:
# acceptedNamespaces:
# - matchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# acceptedTraffic:
# ingress: true
# egress: true
# - ruleID: "2001"
# args:
# acceptedPods:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# - ruleID: "2002"
# args:
Expand All @@ -207,28 +210,34 @@ providers: # contains information about known providers
# - ruleID: "2003"
# args:
# acceptedPods:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# volumeNames:
# - "volume-a"
# - "volume-b"
# - matchLabels:
# foo: baz
# namespaceMatchLabels:
# foo: baz
# - labelSelector:
# matchLabels:
# foo: baz
# namespaceLabelSelector:
# matchLabels:
# foo: baz
# justification: "justification"
# volumeNames:
# - "*" # a wildcard can be used to match against all volumes in an accepted pod
# - ruleID: "2004"
# args:
# acceptedServices:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# - ruleID: "2005"
# args:
Expand All @@ -237,42 +246,52 @@ providers: # contains information about known providers
# - ruleID: "2006"
# args:
# acceptedRoles:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# acceptedClusterRoles:
# - matchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# - ruleID: "2007"
# args:
# acceptedRoles:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# acceptedClusterRoles:
# - matchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# - ruleID: "2008"
# args:
# acceptedPods:
# - matchLabels:
# foo: bar
# namespaceMatchLabels:
# foo: bar
# - labelSelector:
# matchLabels:
# foo: bar
# namespaceLabelSelector:
# matchLabels:
# foo: bar
# justification: "justification"
# volumeNames:
# - "volume-a"
# - "volume-b"
# - matchLabels:
# foo: baz
# namespaceMatchLabels:
# foo: baz
# - labelSelector:
# matchLabels:
# foo: baz
# namespaceLabelSelector:
# matchLabels:
# foo: baz
# justification: "justification"
# volumeNames:
# - "*" # a wildcard can be used to match against all volumes in an accepted pod
Expand Down
83 changes: 50 additions & 33 deletions example/guides/security-hardened-k8s-shoot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,75 +14,92 @@ providers:
- ruleID: "2000"
args:
acceptedNamespaces:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Gardener managed namespaces are accepted to allow traffic by default."
acceptedTraffic:
ingress: true
egress: true
- ruleID: "2001"
args:
acceptedPods:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Gardener managed resources are accepted to allow privilege escalation."
- ruleID: "2003"
args:
acceptedPods:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Gardener managed resources are accepted to use a wider range of volume types."
volumeNames:
- "*"
- ruleID: "2004"
args:
acceptedServices:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Gardener managed services are accepted to be of type NodePort."
- ruleID: "2006"
args:
acceptedRoles:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Roles managed by Gardener are accepted to use wildcards in RBAC resources."
acceptedClusterRoles:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "ClusterRoles managed by Gardener are accepted to use wildcards in RBAC resources."
- matchLabels:
kubernetes.io/bootstrapping: rbac-defaults
- labelSelector:
matchLabels:
kubernetes.io/bootstrapping: rbac-defaults
justification: "Kubernetes default ClusterRoles are accepted to use wildcards in RBAC resources."
- ruleID: "2007"
args:
acceptedRoles:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Roles managed by Gardener are accepted to use wildcards in RBAC verbs."
acceptedClusterRoles:
- matchLabels:
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "ClusterRoles managed by Gardener are accepted to use wildcards in RBAC verbs."
- matchLabels:
kubernetes.io/bootstrapping: rbac-defaults
- labelSelector:
matchLabels:
kubernetes.io/bootstrapping: rbac-defaults
justification: "Kubernetes default ClusterRoles are accepted to use wildcards in RBAC verbs."
- ruleID: "2008"
args:
acceptedPods:
- matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceMatchLabels:
resources.gardener.cloud/managed-by: gardener
- labelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
namespaceLabelSelector:
matchLabels:
resources.gardener.cloud/managed-by: gardener
justification: "Gardener managed resources are accepted to use a wider range of volume types."
volumeNames:
- "*"
Expand Down
39 changes: 22 additions & 17 deletions pkg/provider/managedk8s/ruleset/securityhardenedk8s/rules/2000.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import (
"context"
"slices"

corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/gardener/diki/pkg/internal/utils"
kubeutils "github.com/gardener/diki/pkg/kubernetes/utils"
"github.com/gardener/diki/pkg/rule"
"github.com/gardener/diki/pkg/shared/kubernetes/option"
Expand Down Expand Up @@ -127,7 +125,10 @@ func (r *Rule2000) Run(ctx context.Context) (rule.RuleResult, error) {
if deniesAllIngress && !allowsAllIngress {
checkResults = append(checkResults, rule.PassedCheckResult("Ingress traffic is denied by default.", deniesAllIngressTarget))
} else {
accepted, justification := r.acceptedIngress(namespace)
accepted, justification, err := r.acceptedIngress(namespace.Labels)
if err != nil {
return rule.Result(r, rule.ErroredCheckResult(err.Error(), rule.NewTarget())), nil
}

acceptedTarget := target
msg := "Namespace is accepted to allow Ingress traffic by default."
Expand All @@ -152,7 +153,10 @@ func (r *Rule2000) Run(ctx context.Context) (rule.RuleResult, error) {
if deniesAllEgress && !allowsAllEgress {
checkResults = append(checkResults, rule.PassedCheckResult("Egress traffic is denied by default.", deniesAllEgressTarget))
} else {
accepted, justification := r.acceptedEgress(namespace)
accepted, justification, err := r.acceptedEgress(namespace.Labels)
if err != nil {
return rule.Result(r, rule.ErroredCheckResult(err.Error(), rule.NewTarget())), nil
}

acceptedTarget := target
msg := "Namespace is accepted to allow Egress traffic by default."
Expand All @@ -178,33 +182,34 @@ func (r *Rule2000) Run(ctx context.Context) (rule.RuleResult, error) {
return rule.Result(r, checkResults...), nil
}

func (r *Rule2000) acceptedIngress(namespace corev1.Namespace) (bool, string) {
func (r *Rule2000) acceptedIngress(namespaceLabels map[string]string) (bool, string, error) {
if r.Options == nil {
return false, ""
return false, "", nil
}

for _, acceptedNamespace := range r.Options.AcceptedNamespaces {

if utils.MatchLabels(namespace.Labels, acceptedNamespace.MatchLabels) &&
acceptedNamespace.AcceptedTraffic.Ingress {
return true, acceptedNamespace.Justification
if matches, err := acceptedNamespace.Matches(namespaceLabels); err != nil {
return false, "", err
} else if matches && acceptedNamespace.AcceptedTraffic.Ingress {
return true, acceptedNamespace.Justification, nil
}
}

return false, ""
return false, "", nil
}

func (r *Rule2000) acceptedEgress(namespace corev1.Namespace) (bool, string) {
func (r *Rule2000) acceptedEgress(namespaceLabels map[string]string) (bool, string, error) {
if r.Options == nil {
return false, ""
return false, "", nil
}

for _, acceptedNamespace := range r.Options.AcceptedNamespaces {
if utils.MatchLabels(namespace.Labels, acceptedNamespace.MatchLabels) &&
acceptedNamespace.AcceptedTraffic.Egress {
return true, acceptedNamespace.Justification
if matches, err := acceptedNamespace.Matches(namespaceLabels); err != nil {
return false, "", err
} else if matches && acceptedNamespace.AcceptedTraffic.Egress {
return true, acceptedNamespace.Justification, nil
}
}

return false, ""
return false, "", nil
}
Loading
Loading