1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2025-06-05 07:38:50 +00:00

add alternative method to identify AKS specific cluster

This commit is contained in:
LaibaBareera 2025-05-27 15:56:47 +05:00
parent 754c462d54
commit b446c25c3c
3 changed files with 131 additions and 6 deletions

View File

@ -10,7 +10,16 @@ groups:
checks: checks:
- id: 4.1.1 - id: 4.1.1
text: "Ensure that the cluster-admin role is only used where required (Automated)" text: "Ensure that the cluster-admin role is only used where required (Automated)"
type: "manual" audit: "kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name"
audit_config: "kubectl get clusterrolebindings"
tests:
test_items:
- flag: cluster-admin
path: '{.roleRef.name}'
set: true
compare:
op: eq
value: "cluster-admin"
remediation: | remediation: |
Identify all clusterrolebindings to the cluster-admin role. Check if they are used and Identify all clusterrolebindings to the cluster-admin role. Check if they are used and
if they need this role or if they could use a role with fewer privileges. if they need this role or if they could use a role with fewer privileges.
@ -21,7 +30,34 @@ groups:
- id: 4.1.2 - id: 4.1.2
text: "Minimize access to secrets (Automated)" text: "Minimize access to secrets (Automated)"
type: "manual" audit: "kubectl get roles,rolebindings --all-namespaces -o=custom-columns=NAME:.metadata.name,ROLE:.rules[*].resources,SUBJECT:.subjects[*].name"
audit_config: "kubectl get roles --all-namespaces"
tests:
test_items:
- flag: secrets
path: '{.rules[*].resources}'
set: true
compare:
op: eq
value: "secrets"
- flag: get
path: '{.rules[*].verbs}'
set: true
compare:
op: contains
value: "get"
- flag: list
path: '{.rules[*].verbs}'
set: true
compare:
op: contains
value: "list"
- flag: watch
path: '{.rules[*].verbs}'
set: true
compare:
op: contains
value: "watch"
remediation: | remediation: |
Where possible, remove get, list and watch access to secret objects in the cluster. Where possible, remove get, list and watch access to secret objects in the cluster.
scored: false scored: false
@ -45,14 +81,44 @@ groups:
- id: 4.1.4 - id: 4.1.4
text: "Minimize access to create pods (Automated)" text: "Minimize access to create pods (Automated)"
type: "manual" audit: "kubectl get roles,rolebindings --all-namespaces -o=custom-columns=NAME:.metadata.name,ROLE:.rules[*].resources,SUBJECT:.subjects[*].name"
audit_config: "kubectl get roles --all-namespaces"
tests:
test_items:
- flag: pods
path: '{.rules[*].resources}'
set: true
compare:
op: eq
value: "pods"
- flag: create
path: '{.rules[*].verbs}'
set: true
compare:
op: contains
value: "create"
remediation: | remediation: |
Where possible, remove create access to pod objects in the cluster. Where possible, remove create access to pod objects in the cluster.
scored: false scored: false
- id: 4.1.5 - id: 4.1.5
text: "Ensure that default service accounts are not actively used (Automated)" text: "Ensure that default service accounts are not actively used (Automated)"
type: "manual" audit: "kubectl get serviceaccounts --all-namespaces -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,TOKEN:.automountServiceAccountToken"
audit_config: "kubectl get serviceaccounts --all-namespaces"
tests:
test_items:
- flag: default
path: '{.metadata.name}'
set: true
compare:
op: eq
value: "default"
- flag: automountServiceAccountToken
path: '{.automountServiceAccountToken}'
set: true
compare:
op: eq
value: "false"
remediation: | remediation: |
Create explicit service accounts wherever a Kubernetes workload requires specific access Create explicit service accounts wherever a Kubernetes workload requires specific access
to the Kubernetes API server. to the Kubernetes API server.
@ -62,7 +128,16 @@ groups:
- id: 4.1.6 - id: 4.1.6
text: "Ensure that Service Account Tokens are only mounted where necessary (Automated)" text: "Ensure that Service Account Tokens are only mounted where necessary (Automated)"
type: "manual" audit: "kubectl get pods --all-namespaces -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,SERVICE_ACCOUNT:.spec.serviceAccountName,MOUNT_TOKEN:.spec.automountServiceAccountToken"
audit_config: "kubectl get pods --all-namespaces"
tests:
test_items:
- flag: automountServiceAccountToken
path: '{.spec.automountServiceAccountToken}'
set: true
compare:
op: eq
value: "false"
remediation: | remediation: |
Modify the definition of pods and service accounts which do not need to mount service Modify the definition of pods and service accounts which do not need to mount service
account tokens to disable it. account tokens to disable it.
@ -258,7 +333,16 @@ groups:
- id: 4.6.3 - id: 4.6.3
text: "The default namespace should not be used (Automated)" text: "The default namespace should not be used (Automated)"
type: "manual" audit: "kubectl get all -n default"
audit_config: "kubectl get all -n default"
tests:
test_items:
- flag: "namespace"
path: "{.metadata.namespace}"
set: true
compare:
op: eq
value: "default"
remediation: | remediation: |
Ensure that namespaces are created to allow for appropriate segregation of Kubernetes Ensure that namespaces are created to allow for appropriate segregation of Kubernetes
resources and that all new resources are created in a specific namespace. resources and that all new resources are created in a specific namespace.

View File

@ -300,6 +300,7 @@ func getKubeVersion() (*KubeVersion, error) {
glog.V(3).Infof("Error fetching cluster config: %s", err) glog.V(3).Infof("Error fetching cluster config: %s", err)
} }
isRKE := false isRKE := false
isAKS := false // Variable to track AKS detection
if err == nil && kubeConfig != nil { if err == nil && kubeConfig != nil {
k8sClient, err := kubernetes.NewForConfig(kubeConfig) k8sClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil { if err != nil {
@ -311,7 +312,12 @@ func getKubeVersion() (*KubeVersion, error) {
if err != nil { if err != nil {
glog.V(3).Infof("Error detecting RKE cluster: %s", err) glog.V(3).Infof("Error detecting RKE cluster: %s", err)
} }
isAKS, err = IsAKS(context.Background(), k8sClient)
if err != nil {
glog.V(3).Infof("Error detecting AKS cluster: %s", err)
}
} }
} }
if k8sVer, err := getKubeVersionFromRESTAPI(); err == nil { if k8sVer, err := getKubeVersionFromRESTAPI(); err == nil {
@ -319,6 +325,9 @@ func getKubeVersion() (*KubeVersion, error) {
if isRKE { if isRKE {
k8sVer.GitVersion = k8sVer.GitVersion + "-rancher1" k8sVer.GitVersion = k8sVer.GitVersion + "-rancher1"
} }
if isAKS {
k8sVer.GitVersion = k8sVer.GitVersion + "-aks1" // Mark it as AKS in the version
}
return k8sVer, nil return k8sVer, nil
} }
@ -485,6 +494,26 @@ func getPlatformInfoFromVersion(s string) Platform {
} }
} }
func IsAKS(ctx context.Context, k8sClient kubernetes.Interface) (bool, error) {
// Query the nodes for any annotations that indicate AKS (Azure Kubernetes Service)
nodes, err := k8sClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})
if err != nil {
return false, err
}
// If the cluster contains nodes with specific AKS annotations, its likely AKS
if len(nodes.Items) == 0 {
return false, nil
}
annotations := nodes.Items[0].Annotations
if _, exists := annotations["azure-identity-binding"]; exists { // "azure-identity-binding" is one possible AKS-specific annotation
return true, nil
}
return false, nil
}
func getPlatformBenchmarkVersion(platform Platform) string { func getPlatformBenchmarkVersion(platform Platform) string {
glog.V(3).Infof("getPlatformBenchmarkVersion platform: %s", platform) glog.V(3).Infof("getPlatformBenchmarkVersion platform: %s", platform)
switch platform.Name { switch platform.Name {

View File

@ -627,6 +627,11 @@ func Test_getPlatformNameFromKubectlOutput(t *testing.T) {
args: args{s: "v1.27.6+rke2r1"}, args: args{s: "v1.27.6+rke2r1"},
want: Platform{Name: "rke2r", Version: "1.27"}, want: Platform{Name: "rke2r", Version: "1.27"},
}, },
{
name: "aks",
args: args{s: "v1.27.6+aks1"},
want: Platform{Name: "aks", Version: "1.27"},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -729,6 +734,13 @@ func Test_getPlatformBenchmarkVersion(t *testing.T) {
}, },
want: "rke2-cis-1.7", want: "rke2-cis-1.7",
}, },
{
name: "aks",
args: args{
platform: Platform{Name: "aks", Version: "1.27"},
},
want: "aks-1.7",
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {