Ensure that your Google Kubernetes Engine (GKE) cluster nodes use the Container-Optimized OS (cos_containerd), a managed, optimized, and hardened base OS provided by GKE to limit the host's attack surface. cos_containerd's layered architecture enables advanced GKE features like gVisor and Image Streaming, and offers improved resource efficiency and security.
PoC代码[已公开]
id: gcloud-gke-cos-containerd-disabled
info:
name: GKE Clusters Not Using Container-Optimized OS
author: princechaddha
severity: medium
description: |
Ensure that your Google Kubernetes Engine (GKE) cluster nodes use the Container-Optimized OS (cos_containerd), a managed, optimized, and hardened base OS provided by GKE to limit the host's attack surface. cos_containerd's layered architecture enables advanced GKE features like gVisor and Image Streaming, and offers improved resource efficiency and security.
impact: |
Not using Container-Optimized OS with containerd can result in reduced security posture and inability to use advanced GKE features. Other OS images may have larger attack surfaces and lack the optimizations specific to container workloads.
remediation: |
Update your GKE node pools to use Container-Optimized OS with containerd using the command:
gcloud container clusters upgrade CLUSTER_NAME --node-pool POOL_NAME --image-type cos_containerd
reference:
- https://cloud.google.com/kubernetes-engine/docs/concepts/node-images
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/GKE/use-cos-containerd.html
tags: cloud,devops,gcp,gcloud,gke,kubernetes,security,containers,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let cluster of iterate(template.clusters)){
cluster = JSON.parse(cluster)
set("clusterName", cluster.name)
set("location", cluster.location)
code(3)
for(let nodePool of iterate(template.nodePools)){
nodePool = JSON.parse(nodePool)
set("nodePoolName", nodePool.name)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud container clusters list --project $projectId --format="json(name,location)"
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud container node-pools list --cluster $clusterName --location $location --project $projectId --format="json(name)"
extractors:
- type: json
name: nodePools
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud container node-pools describe $nodePoolName --cluster $clusterName --location $location --project $projectId --format="json(config.imageType)"
matchers-condition: and
matchers:
- type: word
words:
- "COS_CONTAINERD"
negative: true
- type: regex
regex:
- '(?m)^.*$'
extractors:
- type: dsl
dsl:
- '"Node pool " + nodePoolName + " in GKE cluster " + clusterName + " (" + location + ") of project " + projectId + " is not using Container-Optimized OS with containerd"'
# digest: 490a004630440220384831859cdde26777efea3694796ead3e70bcc77f3747cf9f912d33d823e06d022054ebbfa9e21bec19af80d2159e99b1d38b24a1d8c8679ff621572b4dc117e569:922c64590222798bb761d5b6d8e72950