From 8d618e48a2f1b60c2e4c49cdd9deb8eb45c972b0 Mon Sep 17 00:00:00 2001 From: chenk Date: Wed, 26 Jun 2024 10:04:50 +0300 Subject: [PATCH] feat(k8s)!: node-collector dynamic commands support (#6861) Signed-off-by: chenk --- docs/docs/compliance/compliance.md | 224 +++++++++++++++++- .../configuration/cli/trivy_image.md | 2 +- .../configuration/cli/trivy_kubernetes.md | 4 +- docs/docs/target/container_image.md | 4 +- docs/docs/target/kubernetes.md | 20 +- go.mod | 15 +- go.sum | 34 +-- integration/testdata/helm.json.golden | 2 +- .../testdata/helm_testchart.json.golden | 6 +- .../helm_testchart.overridden.json.golden | 6 +- pkg/commands/app.go | 12 +- pkg/commands/app_test.go | 2 +- pkg/flag/kubernetes_flags.go | 2 +- pkg/flag/options.go | 2 +- pkg/iac/rules/register.go | 2 +- pkg/iac/types/compliance.go | 4 + pkg/k8s/commands/cluster.go | 53 ++++- pkg/types/report.go | 28 ++- 18 files changed, 353 insertions(+), 69 deletions(-) diff --git a/docs/docs/compliance/compliance.md b/docs/docs/compliance/compliance.md index 2301fc3fb27..5ff9c6ac665 100644 --- a/docs/docs/compliance/compliance.md +++ b/docs/docs/compliance/compliance.md @@ -35,9 +35,231 @@ to specify a built-in compliance report, select it by ID like `trivy --complianc For the list of built-in compliance reports, please see the relevant section: - [Docker compliance](../target/container_image.md#compliance) -- [Kubernetes compliance](../target/kubernetes.md#compliance) +- [Kubernetes compliance](../target/kubernetes.md#compliance) - [AWS compliance](../target/aws.md#compliance) +## Contribute a Built-in Compliance Report + +### Define a Compliance spec, based on CIS benchmark or other specs + +Here is an example for CIS compliance report: + +```yaml +--- +spec: + id: k8s-cis-1.23 + title: CIS Kubernetes Benchmarks v1.23 + description: CIS Kubernetes Benchmarks + platform: k8s + type: cis + version: '1.23' + relatedResources: + - https://www.cisecurity.org/benchmark/kubernetes + controls: + - id: 1.1.1 + name: Ensure that the API server pod specification file permissions are set to + 600 or more restrictive + description: Ensure that the API server pod specification file has permissions + of 600 or more restrictive + checks: + - id: AVD-KCV-0073 + commands: + - id: CMD-0001 + severity: HIGH + +``` + +### Compliance ID + +ID field is the name used to execute the compliance scan via trivy +example: + +```sh +trivy k8s --compliance k8s-cis-1.23 +``` + +ID naming convention: {platform}-{type}-{version} + +### Compliance Platform + +The platform field specifies the type of platform on which to run this compliance report. +Supported platforms: + +- k8s (native kubernetes cluster) +- eks (elastic kubernetes service) +- aks (azure kubernetes service) +- gke (google kubernetes engine) +- rke2 (rancher kubernetes engine v2) +- ocp (OpenShift Container Platform) +- docker (docker engine) +- aws (amazon web services) + +### Compliance Type + +The type field specifies the kind compliance report. + +- cis (Center for Internet Security) +- nsa (National Security Agency) +- pss (Pod Security Standards) + +### Compliance Version + +The version field specifies the version of the compliance report. + +- 1.23 + +### Compliance Check ID + +Specify the check ID that needs to be evaluated based on the information collected from the command data output to assess the control. + +Example of how to define check data under [checks folder](https://github.com/aquasecurity/trivy-checks/tree/main/checks): + +```sh +# METADATA +# title: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive" +# description: "Ensure that the kubelet.conf file has permissions of 600 or more restrictive." +# scope: package +# schemas: +# - input: schema["kubernetes"] +# related_resources: +# - https://www.cisecurity.org/benchmark/kubernetes +# custom: +# id: KCV0073 +# avd_id: AVD-KCV-0073 +# severity: HIGH +# short_code: ensure-kubelet.conf-file-permissions-600-or-more-restrictive. +# recommended_action: "Change the kubelet.conf file permissions to 600 or more restrictive if exist" +# input: +# selector: +# - type: kubernetes +package builtin.kubernetes.KCV0073 + +import data.lib.kubernetes + +types := ["master", "worker"] + +validate_kubelet_file_permission(sp) := {"kubeletConfFilePermissions": violation} { + sp.kind == "NodeInfo" + sp.type == types[_] + violation := {permission | permission = sp.info.kubeletConfFilePermissions.values[_]; permission > 600} + count(violation) > 0 +} + +deny[res] { + output := validate_kubelet_file_permission(input) + msg := "Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive" + res := result.new(msg, output) +} +``` + +### Compliance Command ID + +***Note:*** This field is not mandatory, it is relevant to k8s compliance report when node-collector is in use + +Specify the command ID (#ref) that needs to be executed to collect the information required to evaluate the control. + +Example of how to define command data under [commands folder](https://github.com/aquasecurity/trivy-checks/tree/main/commands) + +```yaml +--- +- id: CMD-0001 + key: kubeletConfFilePermissions + title: kubelet.conf file permissions + nodeType: worker + audit: stat -c %a $kubelet.kubeconfig + platfroms: + - k8s + - aks +``` + +#### Command ID + +Find the next command ID by running the command on [trivy-checks project](https://github.com/aquasecurity/trivy-checks). + +```sh +make command-id +``` + +#### Command Key + +- Re-use an existing key or specifiy a new one (make sure key name has no spaces) + +Note: The key value should match the key name evaluated by the Rego check. + +### Command Title + +Represent the purpose of the command + +### Command NodeType + +Specify the node type on which the command is supposed to run. + +- worker +- master + +### Command Audit + +Specify here the shell command to be used please make sure to add error supression (2>/dev/null) + +### Command Platforms + +The list of platforms that support this command. Name should be taken from this list [Platforms](#compliance-platform) + +### Command Config Files + +The commands use a configuration file that helps obtain the paths to binaries and configuration files based on different platforms (e.g., Rancher, native Kubernetes, etc.). + +For example: + +```yaml +kubelet: + bins: + - kubelet + - hyperkube kubelet + confs: + - /etc/kubernetes/kubelet-config.yaml + - /var/lib/kubelet/config.yaml +``` + +### Commands Files Location + +Currently checks files location are :`https://github.com/aquasecurity/trivy-checks/tree/main/checks` + +Command files location: `https://github.com/aquasecurity/trivy-checks/tree/main/commands` +under command file + +Note: command config files will be located under `https://github.com/aquasecurity/trivy-checks/tree/main/commands` as well + +### Node-collector output + +The node collector will read commands and execute each command, and incorporate the output into the NodeInfo resource. + +example: + +```json +{ + "apiVersion": "v1", + "kind": "NodeInfo", + "metadata": { + "creationTimestamp": "2023-01-04T11:37:11+02:00" + }, + "type": "master", + "info": { + "adminConfFileOwnership": { + "values": [ + "root:root" + ] + }, + "adminConfFilePermissions": { + "values": [ + 600 + ] + } + ... + } +} +``` + ## Custom compliance You can create your own custom compliance report. A compliance report is a simple YAML document in the following format: diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index 251ea85b6f3..1ef6e1e8cf3 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -38,7 +38,7 @@ trivy image [flags] IMAGE_NAME --cache-ttl duration cache TTL when using redis as cache backend --check-namespaces strings Rego namespaces --checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0") - --compliance string compliance report to generate (docker-cis) + --compliance string compliance report to generate (docker-cis-1.6.0) --config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files --config-data strings specify paths from which data for the Rego checks will be recursively loaded --custom-headers strings custom headers in client mode diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index a39275750bd..91e9e5fa8e7 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -34,7 +34,7 @@ trivy kubernetes [flags] [CONTEXT] --cache-ttl duration cache TTL when using redis as cache backend --check-namespaces strings Rego namespaces --checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0") - --compliance string compliance report to generate (k8s-nsa,k8s-cis,k8s-pss-baseline,k8s-pss-restricted) + --compliance string compliance report to generate (k8s-nsa-1.0,k8s-cis-1.23,eks-cis-1.4,rke2-cis-1.24,k8s-pss-baseline-0.1,k8s-pss-restricted-0.1) --config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files --config-data strings specify paths from which data for the Rego checks will be recursively loaded --db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2") @@ -71,7 +71,7 @@ trivy kubernetes [flags] [CONTEXT] --list-all-pkgs output all packages in the JSON report regardless of vulnerability --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot]) --no-progress suppress progress bar - --node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.2.1") + --node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.3.1") --node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp") --offline-scan do not issue API requests to identify dependencies -o, --output string output file name diff --git a/docs/docs/target/container_image.md b/docs/docs/target/container_image.md index 948cf967828..94acc954a74 100644 --- a/docs/docs/target/container_image.md +++ b/docs/docs/target/container_image.md @@ -436,14 +436,14 @@ The following reports are available out of the box: | Compliance | Version | Name for command | More info | |----------------------------------------|---------|------------------|---------------------------------------------------------------------------------------------| -| CIS Docker Community Edition Benchmark | 1.1.0 | `docker-cis` | [Link](https://www.aquasec.com/cloud-native-academy/docker-container/docker-cis-benchmark/) | +| CIS Docker Community Edition Benchmark | 1.1.0 | `docker-cis-1.6.0` | [Link](https://www.aquasec.com/cloud-native-academy/docker-container/docker-cis-benchmark/) | ### Examples Scan a container image configuration and generate a compliance summary report: ``` -$ trivy image --compliance docker-cis [YOUR_IMAGE_NAME] +trivy image --compliance docker-cis-1.6.0 [YOUR_IMAGE_NAME] ``` !!! note diff --git a/docs/docs/target/kubernetes.md b/docs/docs/target/kubernetes.md index a92057dc534..10253aff4c7 100644 --- a/docs/docs/target/kubernetes.md +++ b/docs/docs/target/kubernetes.md @@ -355,12 +355,14 @@ For an overview of Trivy's Compliance feature, including working with custom com The following reports are available out of the box: -| Compliance | Name for command | More info | -|----------------------------------------------|----------------------|---------------------------------------------------------------------------------------------------------------------| -| NSA, CISA Kubernetes Hardening Guidance v1.2 | `k8s-nsa` | [Link](https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF) | -| CIS Benchmark for Kubernetes v1.23 | `k8s-cis` | [Link](https://www.cisecurity.org/benchmark/kubernetes) | -| Pod Security Standards, Baseline | `k8s-pss-baseline` | [Link](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) | -| Pod Security Standards, Restricted | `k8s-pss-restricted` | [Link](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted) | +| Compliance | Name for command | More info | +|----------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------------------------------| +| NSA, CISA Kubernetes Hardening Guidance v1.0 | `k8s-nsa-1.0` | [Link](https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF) | +| CIS Benchmark for Kubernetes v1.23 | `k8s-cis-1.23` | [Link](https://www.cisecurity.org/benchmark/kubernetes) | +| CIS Benchmark for RKE2 v1.24 | `rke2-cis-1.24` | [Link](https://www.cisecurity.org/benchmark/kubernetes) | +| CIS Benchmark for EKS v1.4 | `eks-cis-1.4` | [Link](https://www.cisecurity.org/benchmark/kubernetes) | +| Pod Security Standards, Baseline | `k8s-pss-baseline-0.1` | [Link](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) | +| Pod Security Standards, Restricted | `k8s-pss-restricted-0.1` | [Link](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted) | Examples: @@ -376,7 +378,7 @@ Get the detailed report for checks: ``` -trivy k8s --compliance=k8s-cis --report all +trivy k8s --compliance=k8s-cis-1.23 --report all ``` @@ -384,7 +386,7 @@ Get summary report in JSON format: ``` -trivy k8s --compliance=k8s-cis --report summary --format json +trivy k8s --compliance=k8s-cis-1.23 --report summary --format json ``` @@ -392,7 +394,7 @@ Get detailed report in JSON format: ``` -trivy k8s --compliance=k8s-cis --report all --format json +trivy k8s --compliance=k8s-cis-1.23 --report all --format json ``` diff --git a/go.mod b/go.mod index 77158774095..1f4c4fc4c7e 100644 --- a/go.mod +++ b/go.mod @@ -25,10 +25,10 @@ require ( github.com/aquasecurity/table v1.8.0 github.com/aquasecurity/testdocker v0.0.0-20240613070307-2c3868d658ac github.com/aquasecurity/tml v0.6.1 - github.com/aquasecurity/trivy-checks v0.11.0 + github.com/aquasecurity/trivy-checks v0.13.0 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 - github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240516051533-4c5a4aad13b7 + github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240625102549-87c0f9c7bcf4 github.com/aws/aws-sdk-go-v2 v1.27.2 github.com/aws/aws-sdk-go-v2/config v1.27.18 github.com/aws/aws-sdk-go-v2/credentials v1.17.18 @@ -167,7 +167,7 @@ require ( github.com/antchfx/xpath v1.3.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.53.0 // indirect + github.com/aws/aws-sdk-go v1.53.16 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 // indirect @@ -205,6 +205,7 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect + github.com/dsnet/compress v0.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -369,12 +370,12 @@ require ( k8s.io/apiextensions-apiserver v0.30.0 // indirect k8s.io/apimachinery v0.30.1 // indirect k8s.io/apiserver v0.30.0 // indirect - k8s.io/cli-runtime v0.30.0 // indirect - k8s.io/client-go v0.30.0 // indirect - k8s.io/component-base v0.30.0 // indirect + k8s.io/cli-runtime v0.30.1 // indirect + k8s.io/client-go v0.30.1 // indirect + k8s.io/component-base v0.30.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/kubectl v0.30.0 // indirect + k8s.io/kubectl v0.30.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect modernc.org/libc v1.50.9 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/go.sum b/go.sum index b181d9ecb24..6c441559ac1 100644 --- a/go.sum +++ b/go.sum @@ -769,14 +769,14 @@ github.com/aquasecurity/testdocker v0.0.0-20240613070307-2c3868d658ac h1:dy7xjLO github.com/aquasecurity/testdocker v0.0.0-20240613070307-2c3868d658ac/go.mod h1:nyavBQqxtIkQh99lQE1ssup3i2uIq1+giL7tOSHapYk= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= -github.com/aquasecurity/trivy-checks v0.11.0 h1:hS5gSQyuyIITrY/kCY2AWQMUSwXLpdtbHDPaCs6eSaI= -github.com/aquasecurity/trivy-checks v0.11.0/go.mod h1:IAK3eHcKNxIHo/ckxKoHsXmEpUG45/38grW5bBjL9lw= +github.com/aquasecurity/trivy-checks v0.13.0 h1:na6PTdY4U0uK/fjz3HNRYBxvYSJ8vgTb57a5T8Y5t9w= +github.com/aquasecurity/trivy-checks v0.13.0/go.mod h1:Xec/SMVGV66I7RgUqOX9MEr+YxBqHXDVLTYmpspPi3E= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= -github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240516051533-4c5a4aad13b7 h1:bLmh/xuC/7abvt9S/xnODTQRu8fW6BhFHS6Cmbn0RNU= -github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240516051533-4c5a4aad13b7/go.mod h1:HSpAJE8Y5Cjjg0Aw/0lqd3vMihN/FxBEj/f/7yDi/Uc= +github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240625102549-87c0f9c7bcf4 h1:IKKfTgIxDptIQWB3AQFP55uuFpE9DzsbHrYIPL3VK1w= +github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20240625102549-87c0f9c7bcf4/go.mod h1:U3LFiVzDi7FYUToe2hV0+HrEIcVpnqaajX7cEUha9Bs= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -787,8 +787,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.53.0 h1:MMo1x1ggPPxDfHMXJnQudTbGXYlD4UigUAud1DJxPVo= -github.com/aws/aws-sdk-go v1.53.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc= +github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8= github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk= @@ -1091,6 +1091,9 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -1538,6 +1541,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -1546,6 +1550,7 @@ github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f h1:GvCU5GXhHq+7LeOzx/haG7HSIZokl3/0GkoUFzsRJjg= github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f/go.mod h1:q59u9px8b7UTj0nIjEjvmTWekazka6xIt6Uogz5Dm+8= @@ -2021,6 +2026,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/twitchtv/twirp v8.1.3+incompatible h1:+F4TdErPgSUbMZMwp13Q/KgDVuI7HJXP61mNV3/7iuU= github.com/twitchtv/twirp v8.1.3+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -2993,18 +2999,18 @@ k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.30.0 h1:QCec+U72tMQ+9tR6A0sMBB5Vh6ImCEkoKkTDRABWq6M= k8s.io/apiserver v0.30.0/go.mod h1:smOIBq8t0MbKZi7O7SyIpjPsiKJ8qa+llcFCluKyqiY= -k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= -k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= +k8s.io/cli-runtime v0.30.1 h1:kSBBpfrJGS6lllc24KeniI9JN7ckOOJKnmFYH1RpTOw= +k8s.io/cli-runtime v0.30.1/go.mod h1:zhHgbqI4J00pxb6gM3gJPVf2ysDjhQmQtnTxnMScab8= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= -k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= +k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= +k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.30.0 h1:cj6bp38g0ainlfYtaOQuRELh5KSYjhKxM+io7AUIk4o= -k8s.io/component-base v0.30.0/go.mod h1:V9x/0ePFNaKeKYA3bOvIbrNoluTSG+fSJKjLdjOoeXQ= +k8s.io/component-base v0.30.1 h1:bvAtlPh1UrdaZL20D9+sWxsJljMi0QZ3Lmw+kmZAaxQ= +k8s.io/component-base v0.30.1/go.mod h1:e/X9kDiOebwlI41AvBHuWdqFriSRrX50CdwA9TFaHLI= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -3017,8 +3023,8 @@ k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= -k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= +k8s.io/kubectl v0.30.1 h1:sHFIRI3oP0FFZmBAVEE8ErjnTyXDPkBcvO88mH9RjuY= +k8s.io/kubectl v0.30.1/go.mod h1:7j+L0Cc38RYEcx+WH3y44jRBe1Q1jxdGPKkX0h4iDq0= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= diff --git a/integration/testdata/helm.json.golden b/integration/testdata/helm.json.golden index c9721e20527..518458ac108 100644 --- a/integration/testdata/helm.json.golden +++ b/integration/testdata/helm.json.golden @@ -21,7 +21,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 125, + "Successes": 80, "Failures": 14, "Exceptions": 0 }, diff --git a/integration/testdata/helm_testchart.json.golden b/integration/testdata/helm_testchart.json.golden index ce6df6b17ce..2e659b13e68 100644 --- a/integration/testdata/helm_testchart.json.golden +++ b/integration/testdata/helm_testchart.json.golden @@ -21,7 +21,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 135, + "Successes": 90, "Failures": 4, "Exceptions": 0 }, @@ -341,7 +341,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 106, + "Successes": 61, "Failures": 0, "Exceptions": 0 } @@ -351,7 +351,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 105, + "Successes": 60, "Failures": 0, "Exceptions": 0 } diff --git a/integration/testdata/helm_testchart.overridden.json.golden b/integration/testdata/helm_testchart.overridden.json.golden index 573d789ef7b..1b1ada2cd9a 100644 --- a/integration/testdata/helm_testchart.overridden.json.golden +++ b/integration/testdata/helm_testchart.overridden.json.golden @@ -21,7 +21,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 133, + "Successes": 88, "Failures": 6, "Exceptions": 0 }, @@ -568,7 +568,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 106, + "Successes": 61, "Failures": 0, "Exceptions": 0 } @@ -578,7 +578,7 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 105, + "Successes": 60, "Failures": 0, "Exceptions": 0 } diff --git a/pkg/commands/app.go b/pkg/commands/app.go index 0cd331e7b9b..71c85aaa593 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -247,7 +247,7 @@ func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup.ReportFormat = report compliance := flag.ComplianceFlag.Clone() - compliance.Values = []string{types.ComplianceDockerCIS} + compliance.Values = []string{types.ComplianceDockerCIS160} reportFlagGroup.Compliance = compliance // override usage as the accepted values differ for each subcommand. misconfFlagGroup := flag.NewMisconfFlagGroup() @@ -946,10 +946,12 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup := flag.NewReportFlagGroup() compliance := flag.ComplianceFlag.Clone() compliance.Values = []string{ - types.ComplianceK8sNsa, - types.ComplianceK8sCIS, - types.ComplianceK8sPSSBaseline, - types.ComplianceK8sPSSRestricted, + types.ComplianceK8sNsa10, + types.ComplianceK8sCIS123, + types.ComplianceEksCIS14, + types.ComplianceRke2CIS124, + types.ComplianceK8sPSSBaseline01, + types.ComplianceK8sPSSRestricted01, } reportFlagGroup.Compliance = compliance // override usage as the accepted values differ for each subcommand. reportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol' diff --git a/pkg/commands/app_test.go b/pkg/commands/app_test.go index 143de739caf..7235a3e94c7 100644 --- a/pkg/commands/app_test.go +++ b/pkg/commands/app_test.go @@ -271,7 +271,7 @@ func TestFlags(t *testing.T) { "--scanners", "license", "--compliance", - "docker-cis", + "docker-cis-1.6.0", }, want: want{ format: types.FormatTable, diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index 2683fa07b13..6d0d64f4dc5 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -39,7 +39,7 @@ var ( NodeCollectorImageRef = Flag[string]{ Name: "node-collector-imageref", ConfigName: "kubernetes.node-collector.imageref", - Default: "ghcr.io/aquasecurity/node-collector:0.2.1", + Default: "ghcr.io/aquasecurity/node-collector:0.3.1", Usage: "indicate the image reference for the node-collector scan job", } ExcludeOwned = Flag[bool]{ diff --git a/pkg/flag/options.go b/pkg/flag/options.go index ee18c45c409..8f15480ccfe 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -384,7 +384,7 @@ func (o *Options) Align() error { o.Scanners = scanners o.ImageConfigScanners = nil // TODO: define image-config-scanners in the spec - if o.Compliance.Spec.ID == types.ComplianceDockerCIS { + if o.Compliance.Spec.ID == types.ComplianceDockerCIS160 { o.Scanners = types.Scanners{types.VulnerabilityScanner} o.ImageConfigScanners = types.Scanners{ types.MisconfigScanner, diff --git a/pkg/iac/rules/register.go b/pkg/iac/rules/register.go index ab847de2e1d..e0726825541 100755 --- a/pkg/iac/rules/register.go +++ b/pkg/iac/rules/register.go @@ -5,7 +5,7 @@ import ( "gopkg.in/yaml.v3" - "github.com/aquasecurity/trivy-checks/specs" + "github.com/aquasecurity/trivy-checks/pkg/specs" "github.com/aquasecurity/trivy/pkg/iac/framework" "github.com/aquasecurity/trivy/pkg/iac/scan" dftypes "github.com/aquasecurity/trivy/pkg/iac/types" diff --git a/pkg/iac/types/compliance.go b/pkg/iac/types/compliance.go index 5928537e132..42636fffe54 100644 --- a/pkg/iac/types/compliance.go +++ b/pkg/iac/types/compliance.go @@ -7,6 +7,9 @@ type ControlStatus string type SpecCheck struct { ID string `yaml:"id"` } +type Command struct { + ID string `yaml:"id"` +} // ComplianceSpec represent the compliance specification type ComplianceSpec struct { @@ -28,6 +31,7 @@ type Control struct { Name string `yaml:"name"` Description string `yaml:"description,omitempty"` Checks []SpecCheck `yaml:"checks"` + Commands []Command `yaml:"commands"` Severity Severity `yaml:"severity"` DefaultStatus ControlStatus `yaml:"defaultStatus,omitempty"` } diff --git a/pkg/k8s/commands/cluster.go b/pkg/k8s/commands/cluster.go index 6b169771f1c..179a089523d 100644 --- a/pkg/k8s/commands/cluster.go +++ b/pkg/k8s/commands/cluster.go @@ -5,9 +5,11 @@ import ( "golang.org/x/xerrors" + trivy_checks "github.com/aquasecurity/trivy-checks" k8sArtifacts "github.com/aquasecurity/trivy-kubernetes/pkg/artifacts" "github.com/aquasecurity/trivy-kubernetes/pkg/k8s" "github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s" + "github.com/aquasecurity/trivy/pkg/commands/operation" "github.com/aquasecurity/trivy/pkg/flag" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/types" @@ -35,11 +37,7 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err trivyk8s.WithExcludeOwned(opts.ExcludeOwned), } if opts.Scanners.AnyEnabled(types.MisconfigScanner) && !opts.DisableNodeCollector { - artifacts, err = trivyk8s.New(cluster, k8sOpts...).ListArtifactAndNodeInfo(ctx, - trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace), - trivyk8s.WithIgnoreLabels(opts.ExcludeNodes), - trivyk8s.WithScanJobImageRef(opts.NodeCollectorImageRef), - trivyk8s.WithTolerations(opts.Tolerations)) + artifacts, err = trivyk8s.New(cluster, k8sOpts...).ListArtifactAndNodeInfo(ctx, nodeCollectorOptions(opts)...) if err != nil { return xerrors.Errorf("get k8s artifacts with node info error: %w", err) } @@ -60,3 +58,48 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err runner := newRunner(opts, cluster.GetCurrentContext()) return runner.run(ctx, artifacts) } + +func nodeCollectorOptions(opts flag.Options) []trivyk8s.NodeCollectorOption { + nodeCollectorOptions := []trivyk8s.NodeCollectorOption{ + trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace), + trivyk8s.WithIgnoreLabels(opts.ExcludeNodes), + trivyk8s.WithScanJobImageRef(opts.NodeCollectorImageRef), + trivyk8s.WithTolerations(opts.Tolerations)} + + contentPath, err := operation.InitBuiltinPolicies(context.Background(), + opts.CacheDir, + opts.Quiet, + opts.SkipCheckUpdate, + opts.MisconfOptions.ChecksBundleRepository, + opts.RegistryOpts()) + + if err != nil { + log.Error("Falling back to embedded checks", log.Err(err)) + nodeCollectorOptions = append(nodeCollectorOptions, + []trivyk8s.NodeCollectorOption{ + trivyk8s.WithEmbeddedCommandFileSystem(trivy_checks.EmbeddedK8sCommandsFileSystem), + trivyk8s.WithEmbeddedNodeConfigFilesystem(trivy_checks.EmbeddedConfigCommandsFileSystem), + }...) + } + + complianceCommandsIDs := getComplianceCommands(opts) + nodeCollectorOptions = append(nodeCollectorOptions, []trivyk8s.NodeCollectorOption{ + trivyk8s.WithCommandPaths(contentPath), + trivyk8s.WithSpecCommandIds(complianceCommandsIDs), + }...) + return nodeCollectorOptions +} + +func getComplianceCommands(opts flag.Options) []string { + var commands []string + if opts.Compliance.Spec.ID != "" { + for _, control := range opts.Compliance.Spec.Controls { + for _, command := range control.Commands { + if command.ID != "" { + commands = append(commands, command.ID) + } + } + } + } + return commands +} diff --git a/pkg/types/report.go b/pkg/types/report.go index baaeaab0a0c..6937f8ce796 100644 --- a/pkg/types/report.go +++ b/pkg/types/report.go @@ -53,13 +53,15 @@ const ( ClassLicenseFile ResultClass = "license-file" // For detected licenses in files ClassCustom ResultClass = "custom" - ComplianceK8sNsa = Compliance("k8s-nsa") - ComplianceK8sCIS = Compliance("k8s-cis") - ComplianceK8sPSSBaseline = Compliance("k8s-pss-baseline") - ComplianceK8sPSSRestricted = Compliance("k8s-pss-restricted") - ComplianceAWSCIS12 = Compliance("aws-cis-1.2") - ComplianceAWSCIS14 = Compliance("aws-cis-1.4") - ComplianceDockerCIS = Compliance("docker-cis") + ComplianceK8sNsa10 = Compliance("k8s-nsa-1.0") + ComplianceK8sCIS123 = Compliance("k8s-cis-1.23") + ComplianceK8sPSSBaseline01 = Compliance("k8s-pss-baseline-0.1") + ComplianceK8sPSSRestricted01 = Compliance("k8s-pss-restricted-0.1") + ComplianceAWSCIS12 = Compliance("aws-cis-1.2") + ComplianceAWSCIS14 = Compliance("aws-cis-1.4") + ComplianceDockerCIS160 = Compliance("docker-cis-1.6.0") + ComplianceEksCIS14 = Compliance("eks-cis-1.4") + ComplianceRke2CIS124 = Compliance("rke2-cis-1.24") FormatTable Format = "table" FormatJSON Format = "json" @@ -91,13 +93,15 @@ var ( FormatGitHub, } SupportedCompliances = []string{ - ComplianceK8sNsa, - ComplianceK8sCIS, - ComplianceK8sPSSBaseline, - ComplianceK8sPSSRestricted, + ComplianceK8sNsa10, + ComplianceK8sCIS123, + ComplianceK8sPSSBaseline01, + ComplianceK8sPSSRestricted01, ComplianceAWSCIS12, ComplianceAWSCIS14, - ComplianceDockerCIS, + ComplianceDockerCIS160, + ComplianceEksCIS14, + ComplianceRke2CIS124, } )