mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2025-05-29 12:18:55 +00:00
add alternative method to identify AKS specific cluster
This commit is contained in:
parent
754c462d54
commit
b446c25c3c
@ -10,7 +10,16 @@ groups:
|
||||
checks:
|
||||
- id: 4.1.1
|
||||
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: |
|
||||
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.
|
||||
@ -21,7 +30,34 @@ groups:
|
||||
|
||||
- id: 4.1.2
|
||||
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: |
|
||||
Where possible, remove get, list and watch access to secret objects in the cluster.
|
||||
scored: false
|
||||
@ -45,14 +81,44 @@ groups:
|
||||
|
||||
- id: 4.1.4
|
||||
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: |
|
||||
Where possible, remove create access to pod objects in the cluster.
|
||||
scored: false
|
||||
|
||||
- id: 4.1.5
|
||||
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: |
|
||||
Create explicit service accounts wherever a Kubernetes workload requires specific access
|
||||
to the Kubernetes API server.
|
||||
@ -62,7 +128,16 @@ groups:
|
||||
|
||||
- id: 4.1.6
|
||||
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: |
|
||||
Modify the definition of pods and service accounts which do not need to mount service
|
||||
account tokens to disable it.
|
||||
@ -258,7 +333,16 @@ groups:
|
||||
|
||||
- id: 4.6.3
|
||||
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: |
|
||||
Ensure that namespaces are created to allow for appropriate segregation of Kubernetes
|
||||
resources and that all new resources are created in a specific namespace.
|
||||
|
29
cmd/util.go
29
cmd/util.go
@ -300,6 +300,7 @@ func getKubeVersion() (*KubeVersion, error) {
|
||||
glog.V(3).Infof("Error fetching cluster config: %s", err)
|
||||
}
|
||||
isRKE := false
|
||||
isAKS := false // Variable to track AKS detection
|
||||
if err == nil && kubeConfig != nil {
|
||||
k8sClient, err := kubernetes.NewForConfig(kubeConfig)
|
||||
if err != nil {
|
||||
@ -311,7 +312,12 @@ func getKubeVersion() (*KubeVersion, error) {
|
||||
if err != nil {
|
||||
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 {
|
||||
@ -319,6 +325,9 @@ func getKubeVersion() (*KubeVersion, error) {
|
||||
if isRKE {
|
||||
k8sVer.GitVersion = k8sVer.GitVersion + "-rancher1"
|
||||
}
|
||||
if isAKS {
|
||||
k8sVer.GitVersion = k8sVer.GitVersion + "-aks1" // Mark it as AKS in the version
|
||||
}
|
||||
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, it’s 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 {
|
||||
glog.V(3).Infof("getPlatformBenchmarkVersion platform: %s", platform)
|
||||
switch platform.Name {
|
||||
|
@ -627,6 +627,11 @@ func Test_getPlatformNameFromKubectlOutput(t *testing.T) {
|
||||
args: args{s: "v1.27.6+rke2r1"},
|
||||
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 {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@ -729,6 +734,13 @@ func Test_getPlatformBenchmarkVersion(t *testing.T) {
|
||||
},
|
||||
want: "rke2-cis-1.7",
|
||||
},
|
||||
{
|
||||
name: "aks",
|
||||
args: args{
|
||||
platform: Platform{Name: "aks", Version: "1.27"},
|
||||
},
|
||||
want: "aks-1.7",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user