├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── dependabot.yml └── workflows │ ├── build.yml │ ├── mkdocs-deploy.yaml │ ├── publish.yml │ └── release.yml ├── .gitignore ├── .golangci.yaml ├── .goreleaser.yml ├── .yamllint.yaml ├── CONTRIBUTING.md ├── Dockerfile ├── Dockerfile.fips.ubi ├── Dockerfile.ubi ├── LICENSE ├── NOTICE ├── OWNERS ├── README.md ├── cfg ├── ack-1.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── aks-1.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.10 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.20 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.23 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.24-microk8s │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.24 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.5 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.6-k3s │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.6 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.7 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.8 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── cis-1.9 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── config.yaml ├── eks-1.0.1 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── eks-1.1.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── eks-1.2.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── eks-1.5.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── eks-stig-kubernetes-v1r6 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── gke-1.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── gke-1.2.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── gke-1.6.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── managedservices.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── k3s-cis-1.23 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── k3s-cis-1.24 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── k3s-cis-1.7 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── k3s-cis-1.8 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rh-0.7 │ ├── config.yaml │ ├── master.yaml │ └── node.yaml ├── rh-1.0 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke-cis-1.23 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke-cis-1.24 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke-cis-1.7 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke2-cis-1.23 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke2-cis-1.24 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── rke2-cis-1.7 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml └── tkgi-1.2.53 │ ├── config.yaml │ ├── controlplane.yaml │ ├── etcd.yaml │ ├── master.yaml │ ├── node.yaml │ └── policies.yaml ├── check ├── check.go ├── check_test.go ├── controls.go ├── controls_test.go ├── data ├── test.go └── test_test.go ├── cmd ├── common.go ├── common_test.go ├── database.go ├── kubernetes_version.go ├── kubernetes_version_test.go ├── root.go ├── run.go ├── run_test.go ├── securityHub.go ├── testdata │ ├── controlsCollection.json │ ├── passedControlsCollection.json │ ├── result.json │ └── result_no_totals.json ├── util.go ├── util_test.go └── version.go ├── codecov.yml ├── docs ├── architecture.md ├── asff.md ├── controls.md ├── flags-and-commands.md ├── images │ ├── asff-example-finding.png │ ├── kube-bench-logo-only.png │ ├── kube-bench-security-hub.png │ ├── kube-bench.jpg │ ├── kube-bench.png │ ├── kube-bench.svg │ └── output.png ├── index.md ├── installation.md ├── platforms.md └── running.md ├── entrypoint.sh ├── fipsonly.go ├── go.mod ├── go.sum ├── hack ├── debug.yaml ├── kind-stig.test.yaml ├── kind-stig.yaml ├── kind.yaml └── node_only.yaml ├── helper_scripts └── check_files_owner_in_dir.sh ├── hooks └── build ├── integration └── testdata │ ├── Expected_output.data │ └── Expected_output_stig.data ├── internal └── findings │ ├── doc.go │ └── publisher.go ├── job-ack.yaml ├── job-aks.yaml ├── job-eks-asff.yaml ├── job-eks-stig.yaml ├── job-eks.yaml ├── job-gke.yaml ├── job-iks.yaml ├── job-master.yaml ├── job-node.yaml ├── job-tkgi.yaml ├── job.yaml ├── main.go ├── makefile └── mkdocs.yml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Tell us about a problem you are experiencing 4 | --- 5 | 6 | **Overview** 7 | 8 | [A clear and concise description of what the bug is] 9 | 10 | **How did you run kube-bench?** 11 | 12 | [Please specify exactly how you ran kube-bench, including details of command parameters and/or job file that you used to run it] 13 | 14 | **What happened?** 15 | 16 | [Please include output from the report to illustrate the problem. If possible please supply logs generated with the `-v 3` parameter.] 17 | 18 | **What did you expect to happen:** 19 | 20 | [Please describe what you expected to happen differently.] 21 | 22 | **Environment** 23 | 24 | [What is your version of kube-bench? (run `kube-bench version`)] 25 | 26 | [What is your version of Kubernetes? (run `kubectl version` or `oc version` on OpenShift.)] 27 | 28 | **Running processes** 29 | 30 | [Please include the output from running `ps -eaf | grep kube` on the affected node. This will allow us to check what Kubernetes processes are running, and how this compares to what kube-bench detected.] 31 | 32 | **Configuration files** 33 | 34 | [If kube-bench is reporting an issue related to the settings defined in a config file, please attach the file, or include an extract showing the settings that are being detected incorrectly.] 35 | 36 | **Anything else you would like to add:** 37 | 38 | [Miscellaneous information that will assist in solving the issue.] 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | blank_issues_enabled: false 3 | contact_links: 4 | - name: Feature request 5 | url: https://github.com/aquasecurity/kube-bench/discussions/new?category_id=19113743 6 | about: Share ideas for new features 7 | - name: Ask a question 8 | url: https://github.com/aquasecurity/kube-bench/discussions/new?category_id=19113742 9 | about: Ask questions and discuss with other community members 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: gomod 5 | directory: / 6 | schedule: 7 | interval: weekly 8 | - package-ecosystem: github-actions 9 | directory: / 10 | schedule: 11 | interval: weekly 12 | - package-ecosystem: docker 13 | directory: / 14 | schedule: 15 | interval: weekly 16 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Build 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - "*.md" 9 | - "LICENSE" 10 | - "NOTICE" 11 | pull_request: 12 | paths-ignore: 13 | - "*.md" 14 | - "LICENSE" 15 | - "NOTICE" 16 | env: 17 | GO_VERSION: "1.23.6" 18 | KIND_VERSION: "v0.11.1" 19 | KIND_IMAGE: "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6" 20 | 21 | jobs: 22 | lint: 23 | name: Lint 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Setup Go 27 | uses: actions/setup-go@v5 28 | with: 29 | go-version: ${{ env.GO_VERSION }} 30 | - name: Checkout code 31 | uses: actions/checkout@v4 32 | - name: yaml-lint 33 | uses: ibiqlik/action-yamllint@v3 34 | - name: Setup golangci-lint 35 | uses: golangci/golangci-lint-action@v6 36 | with: 37 | version: v1.64 38 | args: --verbose --timeout 2m 39 | unit: 40 | name: Unit tests 41 | runs-on: ubuntu-latest 42 | steps: 43 | - name: Setup Go 44 | uses: actions/setup-go@v5 45 | with: 46 | go-version: ${{ env.GO_VERSION }} 47 | - name: Checkout code 48 | uses: actions/checkout@v4 49 | - name: Run unit tests 50 | run: make tests 51 | - name: Upload code coverage 52 | uses: codecov/codecov-action@v5 53 | with: 54 | file: ./coverage.txt 55 | e2e: 56 | name: E2e tests 57 | runs-on: ubuntu-latest 58 | steps: 59 | - name: Setup Go 60 | uses: actions/setup-go@v5 61 | with: 62 | go-version: ${{ env.GO_VERSION }} 63 | - name: Checkout code 64 | uses: actions/checkout@v4 65 | - name: Setup Kubernetes cluster (KIND) 66 | uses: engineerd/setup-kind@v0.6.2 67 | with: 68 | version: ${{ env.KIND_VERSION }} 69 | image: ${{ env.KIND_IMAGE }} 70 | name: kube-bench 71 | - name: Test connection to Kubernetes cluster 72 | run: | 73 | kubectl cluster-info 74 | kubectl describe node 75 | - name: Run integration tests 76 | run: | 77 | make integration-test 78 | - name: Compare output with expected output 79 | uses: GuillaumeFalourd/diff-action@v1 80 | with: 81 | first_file_path: ./test.data 82 | second_file_path: integration/testdata/Expected_output.data 83 | expected_result: PASSED 84 | release: 85 | name: Release snapshot 86 | runs-on: ubuntu-latest 87 | needs: [e2e, unit] 88 | steps: 89 | - name: Setup Go 90 | uses: actions/setup-go@v5 91 | with: 92 | go-version: ${{ env.GO_VERSION }} 93 | - name: Checkout code 94 | uses: actions/checkout@v4 95 | with: 96 | fetch-depth: 0 97 | - name: Dry-run release snapshot 98 | uses: goreleaser/goreleaser-action@v6 99 | with: 100 | distribution: goreleaser 101 | version: v1.7.0 102 | args: release --snapshot --skip-publish --rm-dist 103 | -------------------------------------------------------------------------------- /.github/workflows/mkdocs-deploy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a manually triggered workflow to build and publish the MkDocs from the 3 | # main branch to GitHub pages at https://aquasecurity.github.io/kube-bench. 4 | name: Deploy documentation 5 | 6 | on: 7 | workflow_dispatch: 8 | inputs: 9 | version: 10 | description: Version to be deployed 11 | required: true 12 | 13 | jobs: 14 | deploy: 15 | name: Deploy documentation 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout main 19 | uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | persist-credentials: true 23 | - uses: actions/setup-python@v5 24 | with: 25 | python-version: 3.x 26 | - run: | 27 | pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git 28 | pip install mike 29 | pip install mkdocs-macros-plugin 30 | env: 31 | # Note: It is not the same as ${{ secrets.GITHUB_TOKEN }} ! 32 | GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }} 33 | - run: | 34 | git config user.name "aqua-bot" 35 | git config user.email "aqua-bot@users.noreply.github.com" 36 | - run: | 37 | mike deploy --push --update-aliases ${{ github.event.inputs.version }} latest 38 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Publish 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - "v*" 8 | env: 9 | ALIAS: aquasecurity 10 | DOCKERHUB_ALIAS: aquasec 11 | REP: kube-bench 12 | 13 | jobs: 14 | publish: 15 | name: Publish 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Check Out Repo 19 | uses: actions/checkout@v4 20 | - name: Set up QEMU 21 | uses: docker/setup-qemu-action@v3 22 | - name: Set up Docker Buildx 23 | id: buildx 24 | uses: docker/setup-buildx-action@v3 25 | - name: Cache Docker layers 26 | uses: actions/cache@v4 27 | with: 28 | path: /tmp/.buildx-cache 29 | key: ${{ runner.os }}-buildxarch-${{ github.sha }} 30 | restore-keys: | 31 | ${{ runner.os }}-buildxarch- 32 | - name: Login to Docker Hub 33 | uses: docker/login-action@v3 34 | with: 35 | username: ${{ secrets.DOCKERHUB_USER }} 36 | password: ${{ secrets.DOCKERHUB_TOKEN }} 37 | - name: Login to ECR 38 | uses: docker/login-action@v3 39 | with: 40 | registry: public.ecr.aws 41 | username: ${{ secrets.ECR_ACCESS_KEY_ID }} 42 | password: ${{ secrets.ECR_SECRET_ACCESS_KEY }} 43 | - name: Get version 44 | id: get_version 45 | uses: crazy-max/ghaction-docker-meta@v5 46 | with: 47 | images: ${{ env.REP }} 48 | tag-semver: | 49 | {{version}} 50 | - name: Extract variables from makefile (kubectl) 51 | id: extract_vars 52 | run: | 53 | echo "KUBECTL_VERSION=$(grep -oP '^KUBECTL_VERSION\s*\?=\s*\K.*' makefile)" >> $GITHUB_ENV 54 | - name: Build and push - Docker/ECR 55 | id: docker_build 56 | uses: docker/build-push-action@v6 57 | with: 58 | context: . 59 | platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x 60 | builder: ${{ steps.buildx.outputs.name }} 61 | push: true 62 | build-args: | 63 | KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }} 64 | KUBECTL_VERSION=${{ env.KUBECTL_VERSION }} 65 | tags: | 66 | ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }} 67 | public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }} 68 | ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:latest 69 | public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:latest 70 | cache-from: type=local,src=/tmp/.buildx-cache/release 71 | cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release 72 | 73 | - name: Build and push ubi image - Docker/ECR 74 | id: docker_build_ubi 75 | uses: docker/build-push-action@v6 76 | with: 77 | context: . 78 | platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x 79 | builder: ${{ steps.buildx.outputs.name }} 80 | push: true 81 | file: Dockerfile.ubi 82 | build-args: | 83 | KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }} 84 | KUBECTL_VERSION=${{ env.KUBECTL_VERSION }} 85 | tags: | 86 | ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi 87 | public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi 88 | cache-from: type=local,src=/tmp/.buildx-cache/release 89 | cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release 90 | - name: Image digest 91 | run: echo ${{ steps.docker_build.outputs.digest }} 92 | 93 | - name: Build and push fips ubi image - Docker/ECR 94 | id: docker_build_fips_ubi 95 | uses: docker/build-push-action@v6 96 | with: 97 | context: . 98 | platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x 99 | builder: ${{ steps.buildx.outputs.name }} 100 | push: true 101 | file: Dockerfile.fips.ubi 102 | build-args: | 103 | KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }} 104 | KUBECTL_VERSION=${{ env.KUBECTL_VERSION }} 105 | tags: | 106 | ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips 107 | public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips 108 | cache-from: type=local,src=/tmp/.buildx-cache/release 109 | cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release 110 | - name: Image digest 111 | run: echo ${{ steps.docker_build.outputs.digest }} 112 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | env: 8 | GO_VERSION: "1.23.6" 9 | KIND_VERSION: "v0.11.1" 10 | KIND_IMAGE: "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6" 11 | 12 | jobs: 13 | release: 14 | name: Release 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Setup Go 18 | uses: actions/setup-go@v5 19 | with: 20 | go-version: ${{ env.GO_VERSION }} 21 | - name: Checkout code 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | - name: Run unit tests 26 | run: make tests 27 | - name: Setup Kubernetes cluster (KIND) 28 | uses: engineerd/setup-kind@v0.6.2 29 | with: 30 | version: ${{ env.KIND_VERSION }} 31 | image: ${{ env.KIND_IMAGE }} 32 | name: kube-bench 33 | - name: Test connection to Kubernetes cluster 34 | run: | 35 | kubectl cluster-info 36 | kubectl describe node 37 | - name: Run integration tests 38 | run: | 39 | make integration-test 40 | - name: Compare output with expected output 41 | uses: GuillaumeFalourd/diff-action@v1 42 | with: 43 | first_file_path: ./test.data 44 | second_file_path: integration/testdata/Expected_output.data 45 | expected_result: PASSED 46 | - name: Release 47 | uses: goreleaser/goreleaser-action@v6 48 | with: 49 | distribution: goreleaser 50 | version: v1.7.0 51 | args: release --rm-dist 52 | env: 53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | kube-bench 2 | *.swp 3 | vendor 4 | dist 5 | .vscode/ 6 | hack/kind.test.yaml 7 | coverage.txt 8 | 9 | .idea/ 10 | 11 | # Directory junk file 12 | .DS_Store 13 | thumbs.db 14 | /kubeconfig.kube-bench 15 | /test.data 16 | *.iml -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | linters: 3 | disable-all: true 4 | enable: 5 | - gocyclo 6 | - gofmt 7 | - goimports 8 | - govet 9 | - misspell 10 | - typecheck 11 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | --- 2 | project_name: kube-bench 3 | env: 4 | - GO111MODULE=on 5 | - CGO_ENABLED=0 6 | - KUBEBENCH_CFG=/etc/kube-bench/cfg 7 | builds: 8 | - main: . 9 | binary: kube-bench 10 | tags: 11 | - osusergo 12 | - netgo 13 | - static_build 14 | goos: 15 | - linux 16 | - darwin 17 | goarch: 18 | - amd64 19 | - arm 20 | - arm64 21 | - ppc64le 22 | - s390x 23 | goarm: 24 | - 6 25 | - 7 26 | ldflags: 27 | - "-s" 28 | - "-w" 29 | - "-extldflags '-static'" 30 | - "-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion={{.Version}}" 31 | - "-X github.com/aquasecurity/kube-bench/cmd.cfgDir={{.Env.KUBEBENCH_CFG}}" 32 | # Archive customization 33 | archives: 34 | - id: default 35 | format: tar.gz 36 | name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{.Arm }}{{ end }}' 37 | files: 38 | - "cfg/**/*" 39 | - "cfg/config.yaml" 40 | nfpms: 41 | - 42 | vendor: Aqua Security 43 | description: "The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed according to security best practices" 44 | maintainer: Yoav Rotem 45 | license: Apache-2.0 46 | homepage: https://github.com/aquasecurity/kube-bench 47 | file_name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{.Arm }}{{ end }}' 48 | contents: 49 | - src: "cfg/**/*" 50 | dst: "/etc/kube-bench/cfg" 51 | - src: "cfg/config.yaml" 52 | dst: "/etc/kube-bench/cfg/config.yaml" 53 | formats: 54 | - deb 55 | - rpm 56 | changelog: 57 | sort: asc 58 | filters: 59 | exclude: 60 | - '^docs' 61 | - '^test' 62 | - '^release' 63 | -------------------------------------------------------------------------------- /.yamllint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: disable 6 | truthy: disable 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.24.3 AS build 2 | WORKDIR /go/src/github.com/aquasecurity/kube-bench/ 3 | COPY makefile makefile 4 | COPY go.mod go.sum ./ 5 | COPY main.go . 6 | COPY check/ check/ 7 | COPY cmd/ cmd/ 8 | COPY internal/ internal/ 9 | ARG KUBEBENCH_VERSION 10 | RUN make build && cp kube-bench /go/bin/kube-bench 11 | 12 | # Add kubectl to run policies checks 13 | ARG KUBECTL_VERSION TARGETARCH 14 | RUN wget -O /usr/local/bin/kubectl "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" 15 | RUN wget -O kubectl.sha256 "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256" 16 | 17 | # Verify kubectl sha256sum 18 | RUN /bin/bash -c 'echo "$( 20 | 21 | kube-bench is a tool that checks whether Kubernetes is deployed securely by running the checks documented in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/). 22 | 23 | Tests are configured with YAML files, making this tool easy to update as test specifications evolve. 24 | 25 | ![Kubernetes Bench for Security](/docs/images/output.png "Kubernetes Bench for Security") 26 | 27 | ## CIS Scanning as part of Trivy and the Trivy Operator 28 | 29 | [Trivy](https://github.com/aquasecurity/trivy), the all in one cloud native security scanner, can be deployed as a [Kubernetes Operator](https://github.com/aquasecurity/trivy-operator) inside a cluster. 30 | Both, the [Trivy CLI](https://github.com/aquasecurity/trivy), and the [Trivy Operator](https://github.com/aquasecurity/trivy-operator) support CIS Kubernetes Benchmark scanning among several other features. 31 | 32 | ## Quick start 33 | 34 | There are multiple ways to run kube-bench. 35 | You can run kube-bench inside a pod, but it will need access to the host's PID namespace in order to check the running processes, as well as access to some directories on the host where config files and other files are stored. 36 | 37 | The supplied `job.yaml` [file](job.yaml) can be applied to run the tests as a job. For example: 38 | 39 | ```bash 40 | $ kubectl apply -f job.yaml 41 | job.batch/kube-bench created 42 | 43 | $ kubectl get pods 44 | NAME READY STATUS RESTARTS AGE 45 | kube-bench-j76s9 0/1 ContainerCreating 0 3s 46 | 47 | # Wait for a few seconds for the job to complete 48 | $ kubectl get pods 49 | NAME READY STATUS RESTARTS AGE 50 | kube-bench-j76s9 0/1 Completed 0 11s 51 | 52 | # The results are held in the pod's logs 53 | kubectl logs kube-bench-j76s9 54 | [INFO] 1 Master Node Security Configuration 55 | [INFO] 1.1 API Server 56 | ... 57 | ``` 58 | For more information and different ways to run kube-bench see [documentation](docs/running.md) 59 | ### Please Note 60 | 61 | 1. kube-bench implements the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/) as closely as possible. Please raise issues here if kube-bench is not correctly implementing the test as described in the Benchmark. To report issues in the Benchmark itself (for example, tests that you believe are inappropriate), please join the [CIS community](https://cisecurity.org). 62 | 63 | 1. There is not a one-to-one mapping between releases of Kubernetes and releases of the CIS benchmark. See [CIS Kubernetes Benchmark support](docs/platforms.md#cis-kubernetes-benchmark-support) to see which releases of Kubernetes are covered by different releases of the benchmark. 64 | 65 | 66 | By default, kube-bench will determine the test set to run based on the Kubernetes version running on the machine. 67 | - see the following documentation on [Running kube-bench](docs/running.md#running-kube-bench) for more details. 68 | 69 | 70 | ## Contributing 71 | Kindly read [Contributing](CONTRIBUTING.md) before contributing. 72 | We welcome PRs and issue reports. 73 | 74 | ## Roadmap 75 | 76 | Going forward we plan to release updates to kube-bench to add support for new releases of the CIS Benchmark. Note that these are not released as frequently as Kubernetes releases. 77 | -------------------------------------------------------------------------------- /cfg/ack-1.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/ack-1.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "ack-1.0" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Revoke client certificate when possible leakage (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Kubernetes provides the option to use client certificates for user authentication. 16 | ACK issues kubeconfig with its client certificates as the user credentials for connecing to target cluster. 17 | User should revoke his/her issued kubeconfig when possible leakage. 18 | scored: false 19 | 20 | - id: 3.2 21 | text: "Logging" 22 | checks: 23 | - id: 3.2.1 24 | text: "Ensure that a minimal audit policy is created (Manual)" 25 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 26 | tests: 27 | test_items: 28 | - flag: "--audit-policy-file" 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Consider modification of the audit policy in use on the cluster to include these items, at a 38 | minimum. 39 | scored: false 40 | -------------------------------------------------------------------------------- /cfg/ack-1.0/managedservices.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "ack-1.0" 4 | id: 6 5 | text: "Managed Services" 6 | type: "managedservices" 7 | groups: 8 | - id: 6.1 9 | text: "Image Registry and Image Scanning" 10 | checks: 11 | - id: 6.1.1 12 | text: "Ensure Image Vulnerability Scanning using ACR image scanning or a third party provider (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Ensure Image Vulnerability Scanning using ACR image scanning or a third party provider by follow the ACR document: https://www.alibabacloud.com/help/doc-detail/160146.htm 16 | scored: false 17 | 18 | - id: 6.1.2 19 | text: "Minimize user access to ACR (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Minimize user access to ACR by follow the ACR document to setup network access control: https://www.alibabacloud.com/help/doc-detail/142179.htm 23 | And follow the ACR document to setup Resource Access Management (RAM) policies for ACR: https://www.alibabacloud.com/help/doc-detail/144229.htm 24 | scored: false 25 | 26 | - id: 6.1.3 27 | text: "Minimize cluster access to read-only for ACR (Manual)" 28 | type: "manual" 29 | remediation: Minimize cluster access to read-only for ACR 30 | scored: false 31 | 32 | - id: 6.1.4 33 | text: "Minimize Container Registries to only those approved (Manual)" 34 | type: "manual" 35 | remediation: Minimize Container Registries to only those approved 36 | scored: false 37 | 38 | - id: 6.2 39 | text: "Key Management Service (KMS)" 40 | checks: 41 | - id: 6.2.1 42 | text: "Ensure Kubernetes Secrets are encrypted using keys managed in KMS (Manual)" 43 | type: "manual" 44 | remediation: | 45 | Ensure Kubernetes Secrets are encrypted using keys managed in KMS by follow The ACK document: https://www.alibabacloud.com/help/zh/doc-detail/177372.htm 46 | scored: false 47 | 48 | - id: 6.3 49 | text: "Cluster Networking" 50 | checks: 51 | - id: 6.3.1 52 | text: "Restrict Access to the Control Plane Endpoint (Manual)" 53 | type: "manual" 54 | remediation: Restrict Access to the Control Plane Endpoint 55 | scored: false 56 | 57 | - id: 6.3.2 58 | text: "Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)" 59 | type: "manual" 60 | remediation: Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled 61 | scored: false 62 | 63 | - id: 6.3.3 64 | text: "Ensure clusters are created with Private Nodes (Manual)" 65 | type: "manual" 66 | remediation: Ensure clusters are created with Private Nodes 67 | scored: false 68 | 69 | - id: 6.3.4 70 | text: "Ensure Network Policy is Enabled and set as appropriate (Manual)" 71 | type: "manual" 72 | remediation: Ensure Network Policy is Enabled and set as appropriate 73 | scored: false 74 | 75 | - id: 6.3.5 76 | text: "Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)" 77 | type: "manual" 78 | remediation: Encrypt traffic to HTTPS load balancers with TLS certificates 79 | scored: false 80 | 81 | - id: 6.4 82 | text: "Storage" 83 | checks: 84 | - id: 6.4.1 85 | text: "Enable data disk encryption for Alibaba Cloud Disks (Manual)" 86 | type: "manual" 87 | remediation: Enable data disk encryption for Alibaba Cloud Disks 88 | scored: false 89 | 90 | - id: 6.5 91 | text: "Logging" 92 | checks: 93 | - id: 6.5.1 94 | text: "Ensure Cluster Auditing is Enabled (Manual)" 95 | type: "manual" 96 | remediation: Ensure Cluster Auditing is Enabled 97 | scored: false 98 | 99 | - id: 6.6 100 | text: "Other Cluster Configurations" 101 | checks: 102 | - id: 6.6.1 103 | text: "Ensure Pod Security Policy is Enabled and set as appropriate (Manual)" 104 | type: "manual" 105 | remediation: Ensure Pod Security Policy is Enabled and set as appropriate 106 | scored: false 107 | 108 | - id: 6.6.2 109 | text: "Enable Cloud Security Center (Manual)" 110 | type: "manual" 111 | remediation: Enable Cloud Security Center 112 | scored: false 113 | 114 | - id: 6.6.3 115 | text: "Consider ACK Sandboxed-Container for running untrusted workloads (Manual)" 116 | type: "manual" 117 | remediation: Consider ACK Sandboxed-Container for running untrusted workloads 118 | 119 | - id: 6.6.4 120 | text: "Consider ACK TEE-based when running confidential computing (Manual)" 121 | type: "manual" 122 | remediation: Consider ACK TEE-based when running confidential computing 123 | 124 | - id: 6.6.5 125 | text: "Consider use service account token volume projection (Manual)" 126 | type: "manual" 127 | remediation: Consider use service account token volume projection 128 | -------------------------------------------------------------------------------- /cfg/aks-1.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/aks-1.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "aks-1.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Logging" 10 | checks: 11 | - id: 2.1.1 12 | text: "Enable audit Logs" 13 | type: "manual" 14 | remediation: | 15 | Azure audit logs are enabled and managed in the Azure portal. To enable log collection for 16 | the Kubernetes master components in your AKS cluster, open the Azure portal in a web 17 | browser and complete the following steps: 18 | 1. Select the resource group for your AKS cluster, such as myResourceGroup. Don't 19 | select the resource group that contains your individual AKS cluster resources, such 20 | as MC_myResourceGroup_myAKSCluster_eastus. 21 | 2. On the left-hand side, choose Diagnostic settings. 22 | 3. Select your AKS cluster, such as myAKSCluster, then choose to Add diagnostic setting. 23 | 4. Enter a name, such as myAKSClusterLogs, then select the option to Send to Log Analytics. 24 | 5. Select an existing workspace or create a new one. If you create a workspace, provide 25 | a workspace name, a resource group, and a location. 26 | 6. In the list of available logs, select the logs you wish to enable. For this example, 27 | enable the kube-audit and kube-audit-admin logs. Common logs include the kube- 28 | apiserver, kube-controller-manager, and kube-scheduler. You can return and change 29 | the collected logs once Log Analytics workspaces are enabled. 30 | 7. When ready, select Save to enable collection of the selected logs. 31 | scored: false 32 | -------------------------------------------------------------------------------- /cfg/aks-1.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "aks-1.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/cis-1.10/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.10/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.10" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.1.2 20 | text: "Service account token authentication should not be used for users (Manual)" 21 | type: "manual" 22 | remediation: | 23 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 24 | in place of service account tokens. 25 | scored: false 26 | 27 | - id: 3.1.3 28 | text: "Bootstrap token authentication should not be used for users (Manual)" 29 | type: "manual" 30 | remediation: | 31 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 32 | in place of bootstrap tokens. 33 | scored: false 34 | 35 | - id: 3.2 36 | text: "Logging" 37 | checks: 38 | - id: 3.2.1 39 | text: "Ensure that a minimal audit policy is created (Manual)" 40 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 41 | tests: 42 | test_items: 43 | - flag: "--audit-policy-file" 44 | set: true 45 | remediation: | 46 | Create an audit policy file for your cluster. 47 | scored: false 48 | 49 | - id: 3.2.2 50 | text: "Ensure that the audit policy covers key security concerns (Manual)" 51 | type: "manual" 52 | remediation: | 53 | Review the audit policy provided for the cluster and ensure that it covers 54 | at least the following areas, 55 | - Access to Secrets managed by the cluster. Care should be taken to only 56 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 57 | order to avoid risk of logging sensitive data. 58 | - Modification of Pod and Deployment objects. 59 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 60 | For most requests, minimally logging at the Metadata level is recommended 61 | (the most basic level of logging). 62 | scored: false 63 | -------------------------------------------------------------------------------- /cfg/cis-1.20/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.20/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.20" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Consider modification of the audit policy in use on the cluster to include these items, at a 38 | minimum. 39 | scored: false 40 | -------------------------------------------------------------------------------- /cfg/cis-1.23/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.23/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.23" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/cis-1.24-microk8s/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.24-microk8s/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.24" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "cat $apiserverconf | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/cis-1.24-microk8s/etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.24" 4 | id: 2 5 | text: "Etcd Node Configuration" 6 | type: "etcd" 7 | groups: 8 | - id: 2 9 | text: "Etcd Node Configuration" 10 | checks: 11 | - id: 2.1 12 | text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)" 13 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 14 | tests: 15 | bin_op: and 16 | test_items: 17 | - flag: "--cert-file" 18 | env: "ETCD_CERT_FILE" 19 | - flag: "--key-file" 20 | env: "ETCD_KEY_FILE" 21 | remediation: | 22 | Not applicable. MicroK8s used dqlite and the communication to this service is done through a 23 | local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible 24 | to users with root permissions. 25 | scored: false 26 | 27 | - id: 2.2 28 | text: "Ensure that the --client-cert-auth argument is set to true (Automated)" 29 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 30 | tests: 31 | test_items: 32 | - flag: "--client-cert-auth" 33 | env: "ETCD_CLIENT_CERT_AUTH" 34 | compare: 35 | op: eq 36 | value: true 37 | remediation: | 38 | Not applicable. MicroK8s used dqlite and the communication to this service is done through a 39 | local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible 40 | to users with root permissions. 41 | scored: false 42 | 43 | - id: 2.3 44 | text: "Ensure that the --auto-tls argument is not set to true (Automated)" 45 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 46 | tests: 47 | bin_op: or 48 | test_items: 49 | - flag: "--auto-tls" 50 | env: "ETCD_AUTO_TLS" 51 | set: false 52 | - flag: "--auto-tls" 53 | env: "ETCD_AUTO_TLS" 54 | compare: 55 | op: eq 56 | value: false 57 | remediation: | 58 | Not applicable. MicroK8s used dqlite and the communication to this service is done through a 59 | local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible 60 | to users with root permissions. 61 | scored: false 62 | 63 | - id: 2.4 64 | text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)" 65 | audit: "if test -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.crt && test -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.key; then echo 'certs-found'; fi" 66 | tests: 67 | test_items: 68 | - flag: "certs-found" 69 | remediation: | 70 | The certificate pair for dqlite and tls peer communication is 71 | /var/snap/microk8s/current/var/kubernetes/backend/cluster.crt and 72 | /var/snap/microk8s/current/var/kubernetes/backend/cluster.key. 73 | scored: true 74 | 75 | - id: 2.5 76 | text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)" 77 | audit: "/bin/cat $etcdconf | /bin/grep enable-tls || true" 78 | tests: 79 | bin_op: or 80 | test_items: 81 | - flag: "--enable-tls" 82 | compare: 83 | op: eq 84 | value: true 85 | - flag: "--enable-tls" 86 | set: false 87 | remediation: | 88 | MicroK8s used dqlite and tls peer communication uses is TLS if the --enable-tls is set in 89 | /var/snap/microk8s/current/args/k8s-dqlite, set to true by default. 90 | scored: true 91 | 92 | - id: 2.6 93 | text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)" 94 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 95 | tests: 96 | bin_op: or 97 | test_items: 98 | - flag: "--peer-auto-tls" 99 | env: "ETCD_PEER_AUTO_TLS" 100 | set: false 101 | - flag: "--peer-auto-tls" 102 | env: "ETCD_PEER_AUTO_TLS" 103 | compare: 104 | op: eq 105 | value: false 106 | remediation: | 107 | Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates 108 | created upon the snap creation. 109 | scored: false 110 | 111 | - id: 2.7 112 | text: "Ensure that a unique Certificate Authority is used for etcd (Manual)" 113 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 114 | tests: 115 | test_items: 116 | - flag: "--trusted-ca-file" 117 | env: "ETCD_TRUSTED_CA_FILE" 118 | remediation: | 119 | Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates 120 | created upon the snap creation. 121 | scored: false 122 | -------------------------------------------------------------------------------- /cfg/cis-1.24/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.24/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.24" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/cis-1.5/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.5/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.5" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Not Scored)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Scored)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: true 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Not Scored)" 35 | type: "manual" 36 | remediation: | 37 | Consider modification of the audit policy in use on the cluster to include these items, at a 38 | minimum. 39 | scored: false 40 | -------------------------------------------------------------------------------- /cfg/cis-1.5/etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.5" 4 | id: 2 5 | text: "Etcd Node Configuration" 6 | type: "etcd" 7 | groups: 8 | - id: 2 9 | text: "Etcd Node Configuration Files" 10 | checks: 11 | - id: 2.1 12 | text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)" 13 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 14 | tests: 15 | bin_op: and 16 | test_items: 17 | - flag: "--cert-file" 18 | set: true 19 | - flag: "--key-file" 20 | set: true 21 | remediation: | 22 | Follow the etcd service documentation and configure TLS encryption. 23 | Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml 24 | on the master node and set the below parameters. 25 | --cert-file= 26 | --key-file= 27 | scored: true 28 | 29 | - id: 2.2 30 | text: "Ensure that the --client-cert-auth argument is set to true (Scored)" 31 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 32 | tests: 33 | test_items: 34 | - flag: "--client-cert-auth" 35 | compare: 36 | op: eq 37 | value: true 38 | set: true 39 | remediation: | 40 | Edit the etcd pod specification file $etcdconf on the master 41 | node and set the below parameter. 42 | --client-cert-auth="true" 43 | scored: true 44 | 45 | - id: 2.3 46 | text: "Ensure that the --auto-tls argument is not set to true (Scored)" 47 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 48 | tests: 49 | bin_op: or 50 | test_items: 51 | - flag: "--auto-tls" 52 | set: false 53 | - flag: "--auto-tls" 54 | compare: 55 | op: eq 56 | value: false 57 | remediation: | 58 | Edit the etcd pod specification file $etcdconf on the master 59 | node and either remove the --auto-tls parameter or set it to false. 60 | --auto-tls=false 61 | scored: true 62 | 63 | - id: 2.4 64 | text: "Ensure that the --peer-cert-file and --peer-key-file arguments are 65 | set as appropriate (Scored)" 66 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 67 | tests: 68 | bin_op: and 69 | test_items: 70 | - flag: "--peer-cert-file" 71 | set: true 72 | - flag: "--peer-key-file" 73 | set: true 74 | remediation: | 75 | Follow the etcd service documentation and configure peer TLS encryption as appropriate 76 | for your etcd cluster. Then, edit the etcd pod specification file $etcdconf on the 77 | master node and set the below parameters. 78 | --peer-client-file= 79 | --peer-key-file= 80 | scored: true 81 | 82 | - id: 2.5 83 | text: "Ensure that the --peer-client-cert-auth argument is set to true (Scored)" 84 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 85 | tests: 86 | test_items: 87 | - flag: "--peer-client-cert-auth" 88 | compare: 89 | op: eq 90 | value: true 91 | set: true 92 | remediation: | 93 | Edit the etcd pod specification file $etcdconf on the master 94 | node and set the below parameter. 95 | --peer-client-cert-auth=true 96 | scored: true 97 | 98 | - id: 2.6 99 | text: "Ensure that the --peer-auto-tls argument is not set to true (Scored)" 100 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 101 | tests: 102 | bin_op: or 103 | test_items: 104 | - flag: "--peer-auto-tls" 105 | set: false 106 | - flag: "--peer-auto-tls" 107 | compare: 108 | op: eq 109 | value: false 110 | set: true 111 | remediation: | 112 | Edit the etcd pod specification file $etcdconf on the master 113 | node and either remove the --peer-auto-tls parameter or set it to false. 114 | --peer-auto-tls=false 115 | scored: true 116 | 117 | - id: 2.7 118 | text: "Ensure that a unique Certificate Authority is used for etcd (Not Scored)" 119 | audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep" 120 | tests: 121 | test_items: 122 | - flag: "--trusted-ca-file" 123 | set: true 124 | remediation: | 125 | [Manual test] 126 | Follow the etcd documentation and create a dedicated certificate authority setup for the 127 | etcd service. 128 | Then, edit the etcd pod specification file $etcdconf on the 129 | master node and set the below parameter. 130 | --trusted-ca-file= 131 | scored: false 132 | -------------------------------------------------------------------------------- /cfg/cis-1.6-k3s/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | master: 5 | components: 6 | - scheduler 7 | - controllermanager 8 | - node 9 | 10 | scheduler: 11 | kubeconfig: 12 | - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig 13 | defaultkubeconfig: /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig 14 | 15 | controllermanager: 16 | kubeconfig: 17 | - /var/lib/rancher/k3s/server/cred/cloud-controller.kubeconfig 18 | defaultkubeconfig: /var/lib/rancher/k3s/server/cred/cloud-controller.kubeconfig 19 | 20 | etcd: 21 | components: 22 | - etcd 23 | etcd: 24 | confs: 25 | - /var/lib/rancher/k3s/server/db/etcd/config 26 | defaultconf: /var/lib/rancher/k3s/server/db/etcd/config 27 | 28 | node: 29 | components: 30 | - proxy 31 | - kubelet 32 | proxy: 33 | kubeconfig: 34 | - "/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig" 35 | defaultkubeconfig: "/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig" 36 | kubelet: 37 | kubeconfig: 38 | - "/var/lib/rancher/k3s/agent/kubelet.kubeconfig" 39 | defaultkubeconfig: "/var/lib/rancher/k3s/agent/kubelet.kubeconfig" 40 | cafile: 41 | - "/var/lib/rancher/k3s/server/tls/server-ca.crt" 42 | defaultcafile: "/var/lib/rancher/k3s/server/tls/server-ca.crt" 43 | -------------------------------------------------------------------------------- /cfg/cis-1.6-k3s/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.6-k3s" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Automated)" 24 | audit: journalctl -u k3s | grep "Running kube-apiserver" | tail -n1 | grep "audit-policy-file" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster and pass it to k3s. 31 | e.g. --kube-apiserver-arg='audit-log-path=/var/lib/rancher/k3s/server/logs/audit-log' 32 | scored: true 33 | 34 | - id: 3.2.2 35 | text: "Ensure that the audit policy covers key security concerns (Manual)" 36 | type: "manual" 37 | remediation: | 38 | Consider modification of the audit policy in use on the cluster to include these items, at a 39 | minimum. 40 | scored: false 41 | -------------------------------------------------------------------------------- /cfg/cis-1.6-k3s/etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.6-k3s" 4 | id: 2 5 | text: "Etcd Node Configuration" 6 | type: "etcd" 7 | groups: 8 | - id: 2 9 | text: "Etcd Node Configuration Files" 10 | checks: 11 | - id: 2.1 12 | text: "Ensure that the --cert-file and --key-file arguments are set as appropriate if use etcd as database (Automated)" 13 | audit: grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file' 14 | tests: 15 | bin_op: and 16 | test_items: 17 | - flag: "cert-file" 18 | - flag: "key-file" 19 | remediation: | 20 | By default, K3s uses a config file for etcd that can be found at $etcdconf. 21 | The config file contains client-transport-security: which has fields that have the peer cert and peer key files. No manual remediation needed. 22 | scored: true 23 | 24 | - id: 2.2 25 | text: "Ensure that the --client-cert-auth argument is set to true (Automated)" 26 | audit: grep 'client-cert-auth' $etcdconf 27 | tests: 28 | test_items: 29 | - flag: "client-cert-auth" 30 | compare: 31 | op: eq 32 | value: true 33 | remediation: | 34 | By default, K3s uses a config file for etcd that can be found at $etcdconf. 35 | client-cert-auth is set to true. No manual remediation needed. 36 | scored: true 37 | 38 | - id: 2.3 39 | text: "Ensure that the --auto-tls argument is not set to true (Automated)" 40 | audit: grep 'auto-tls' $etcdconf | cat 41 | tests: 42 | bin_op: or 43 | test_items: 44 | - flag: "auto-tls" 45 | set: false 46 | - flag: "auto-tls" 47 | compare: 48 | op: eq 49 | value: false 50 | remediation: | 51 | By default, K3s starts Etcd without this flag. It is set to false by default. 52 | scored: true 53 | 54 | - id: 2.4 55 | text: "Ensure that the --peer-cert-file and --peer-key-file arguments are 56 | set as appropriate (Automated)" 57 | audit: grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file' 58 | tests: 59 | bin_op: and 60 | test_items: 61 | - flag: "cert-file" 62 | - flag: "key-file" 63 | remediation: | 64 | By default, K3s starts Etcd with a config file found here, $etcdconf. 65 | The config file contains peer-transport-security: which has fields that have the peer cert and peer key files. 66 | scored: true 67 | 68 | - id: 2.5 69 | text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)" 70 | audit: grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth' 71 | tests: 72 | test_items: 73 | - flag: "client-cert-auth" 74 | compare: 75 | op: eq 76 | value: true 77 | remediation: | 78 | By default, K3s uses a config file for etcd that can be found at $etcdconf. 79 | The config file contains peer-transport-security: which has client-cert-auth set to true. No manual remediation needed. 80 | scored: true 81 | 82 | - id: 2.6 83 | text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)" 84 | audit: grep 'peer-auto-tls' $etcdconf | cat 85 | tests: 86 | bin_op: or 87 | test_items: 88 | - flag: "peer-auto-tls" 89 | set: false 90 | - flag: "peer-auto-tls" 91 | compare: 92 | op: eq 93 | value: false 94 | remediation: | 95 | By default, K3s uses a config file for etcd that can be found at $etcdconf. 96 | Within the file, it does not contain the peer-auto-tls field. No manual remediation needed. 97 | scored: true 98 | 99 | - id: 2.7 100 | text: "Ensure that a unique Certificate Authority is used for etcd (Manual)" 101 | audit: | 102 | if [ -f "$etcdconf" ];then 103 | etcd_ca=$(grep 'trusted-ca-file' $etcdconf | awk -F ":|: *" '{print $NF}'); 104 | apiserver_ca=$(journalctl -u k3s | grep "Running kube-apiserver" | tail -n1 | grep "trusted-ca-file" | awk -F "=" '{print $NF}') 105 | if [ "$etcd_ca" == "$apiserver_ca" ]; then 106 | echo 'etcd_and_apiserver_have_same_ca'; 107 | else 108 | echo 'etcd_and_apiserver_ca_not_same1' ; 109 | fi 110 | else 111 | echo 'etcd_and_apiserver_ca_not_same'; return ; 112 | fi 113 | tests: 114 | test_items: 115 | - flag: "etcd_and_apiserver_ca_not_same" 116 | remediation: | 117 | By default, K3s uses a config file for etcd that can be found at $etcdconf 118 | and the trusted-ca-file parameters in it are set to unique values specific to etcd. No manual remediation needed. 119 | scored: false 120 | -------------------------------------------------------------------------------- /cfg/cis-1.6/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.6/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.6" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Consider modification of the audit policy in use on the cluster to include these items, at a 38 | minimum. 39 | scored: false 40 | -------------------------------------------------------------------------------- /cfg/cis-1.7/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.7/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.7" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | - id: 3.1.2 19 | text: "Service account token authentication should not be used for users (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 23 | in place of service account tokens. 24 | scored: false 25 | - id: 3.1.3 26 | text: "Bootstrap token authentication should not be used for users (Manual)" 27 | type: "manual" 28 | remediation: | 29 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 30 | in place of bootstrap tokens. 31 | scored: false 32 | 33 | - id: 3.2 34 | text: "Logging" 35 | checks: 36 | - id: 3.2.1 37 | text: "Ensure that a minimal audit policy is created (Manual)" 38 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 39 | tests: 40 | test_items: 41 | - flag: "--audit-policy-file" 42 | set: true 43 | remediation: | 44 | Create an audit policy file for your cluster. 45 | scored: false 46 | 47 | - id: 3.2.2 48 | text: "Ensure that the audit policy covers key security concerns (Manual)" 49 | type: "manual" 50 | remediation: | 51 | Review the audit policy provided for the cluster and ensure that it covers 52 | at least the following areas, 53 | - Access to Secrets managed by the cluster. Care should be taken to only 54 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 55 | order to avoid risk of logging sensitive data. 56 | - Modification of Pod and Deployment objects. 57 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 58 | For most requests, minimally logging at the Metadata level is recommended 59 | (the most basic level of logging). 60 | scored: false 61 | -------------------------------------------------------------------------------- /cfg/cis-1.8/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.8/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.8" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | - id: 3.1.2 19 | text: "Service account token authentication should not be used for users (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 23 | in place of service account tokens. 24 | scored: false 25 | - id: 3.1.3 26 | text: "Bootstrap token authentication should not be used for users (Manual)" 27 | type: "manual" 28 | remediation: | 29 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 30 | in place of bootstrap tokens. 31 | scored: false 32 | 33 | - id: 3.2 34 | text: "Logging" 35 | checks: 36 | - id: 3.2.1 37 | text: "Ensure that a minimal audit policy is created (Manual)" 38 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 39 | tests: 40 | test_items: 41 | - flag: "--audit-policy-file" 42 | set: true 43 | remediation: | 44 | Create an audit policy file for your cluster. 45 | scored: false 46 | 47 | - id: 3.2.2 48 | text: "Ensure that the audit policy covers key security concerns (Manual)" 49 | type: "manual" 50 | remediation: | 51 | Review the audit policy provided for the cluster and ensure that it covers 52 | at least the following areas, 53 | - Access to Secrets managed by the cluster. Care should be taken to only 54 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 55 | order to avoid risk of logging sensitive data. 56 | - Modification of Pod and Deployment objects. 57 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 58 | For most requests, minimally logging at the Metadata level is recommended 59 | (the most basic level of logging). 60 | scored: false 61 | -------------------------------------------------------------------------------- /cfg/cis-1.9/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/cis-1.9/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "cis-1.9" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.1.2 20 | text: "Service account token authentication should not be used for users (Manual)" 21 | type: "manual" 22 | remediation: | 23 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 24 | in place of service account tokens. 25 | scored: false 26 | 27 | - id: 3.1.3 28 | text: "Bootstrap token authentication should not be used for users (Manual)" 29 | type: "manual" 30 | remediation: | 31 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 32 | in place of bootstrap tokens. 33 | scored: false 34 | 35 | - id: 3.2 36 | text: "Logging" 37 | checks: 38 | - id: 3.2.1 39 | text: "Ensure that a minimal audit policy is created (Manual)" 40 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 41 | tests: 42 | test_items: 43 | - flag: "--audit-policy-file" 44 | set: true 45 | remediation: | 46 | Create an audit policy file for your cluster. 47 | scored: false 48 | 49 | - id: 3.2.2 50 | text: "Ensure that the audit policy covers key security concerns (Manual)" 51 | type: "manual" 52 | remediation: | 53 | Review the audit policy provided for the cluster and ensure that it covers 54 | at least the following areas, 55 | - Access to Secrets managed by the cluster. Care should be taken to only 56 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 57 | order to avoid risk of logging sensitive data. 58 | - Modification of Pod and Deployment objects. 59 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 60 | For most requests, minimally logging at the Metadata level is recommended 61 | (the most basic level of logging). 62 | scored: false 63 | -------------------------------------------------------------------------------- /cfg/eks-1.0.1/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | ## These settings are required if you are using the --asff option to report findings to AWS Security Hub 4 | ## AWS account number is required. 5 | AWS_ACCOUNT: "" 6 | ## AWS region is required. 7 | AWS_REGION: "" 8 | ## EKS Cluster ARN is required. 9 | CLUSTER_ARN: "" 10 | -------------------------------------------------------------------------------- /cfg/eks-1.0.1/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.0.1" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Logging" 10 | checks: 11 | - id: 2.1.1 12 | text: "Enable audit logs (Manual)" 13 | remediation: "Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler." 14 | scored: false 15 | -------------------------------------------------------------------------------- /cfg/eks-1.0.1/managedservices.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.0.1" 4 | id: 5 5 | text: "Managed Services" 6 | type: "managedservices" 7 | groups: 8 | - id: 5.1 9 | text: "Image Registry and Image Scanning" 10 | checks: 11 | - id: 5.1.1 12 | text: "Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third-party provider (Manual)" 13 | type: "manual" 14 | remediation: "No remediation" 15 | scored: false 16 | 17 | - id: 5.1.2 18 | text: "Minimize user access to Amazon ECR (Manual)" 19 | type: "manual" 20 | remediation: "No remediation" 21 | scored: false 22 | 23 | - id: 5.1.3 24 | text: "Minimize cluster access to read-only for Amazon ECR (Manual)" 25 | type: "manual" 26 | remediation: "No remediation" 27 | scored: false 28 | 29 | - id: 5.1.4 30 | text: "Minimize Container Registries to only those approved (Manual)" 31 | type: "manual" 32 | remediation: "No remediation" 33 | scored: false 34 | 35 | - id: 5.2 36 | text: "Identity and Access Management (IAM)" 37 | checks: 38 | - id: 5.2.1 39 | text: "Prefer using dedicated Amazon EKS Service Accounts (Manual)" 40 | type: "manual" 41 | remediation: "No remediation" 42 | scored: false 43 | 44 | - id: 5.3 45 | text: "AWS Key Management Service (KMS)" 46 | checks: 47 | - id: 5.3.1 48 | text: "Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)" 49 | type: "manual" 50 | remediation: "No remediation" 51 | scored: false 52 | 53 | - id: 5.4 54 | text: "Cluster Networking" 55 | checks: 56 | - id: 5.4.1 57 | text: "Restrict Access to the Control Plane Endpoint (Manual)" 58 | type: "manual" 59 | remediation: "No remediation" 60 | scored: false 61 | 62 | - id: 5.4.2 63 | text: "Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)" 64 | type: "manual" 65 | remediation: "No remediation" 66 | scored: false 67 | 68 | - id: 5.4.3 69 | text: "Ensure clusters are created with Private Nodes (Manual)" 70 | type: "manual" 71 | remediation: "No remediation" 72 | scored: false 73 | 74 | - id: 5.4.4 75 | text: "Ensure Network Policy is Enabled and set as appropriate (Manual)" 76 | type: "manual" 77 | remediation: "No remediation" 78 | scored: false 79 | 80 | - id: 5.4.5 81 | text: "Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)" 82 | type: "manual" 83 | remediation: "No remediation" 84 | scored: false 85 | 86 | 87 | - id: 5.5 88 | text: "Authentication and Authorization" 89 | checks: 90 | - id: 5.5.1 91 | text: "Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes (Manual)" 92 | type: "manual" 93 | remediation: "No remediation" 94 | scored: false 95 | 96 | 97 | - id: 5.6 98 | text: "Other Cluster Configurations" 99 | checks: 100 | - id: 5.6.1 101 | text: "Consider Fargate for running untrusted workloads (Manual)" 102 | type: "manual" 103 | remediation: "No remediation" 104 | scored: false 105 | -------------------------------------------------------------------------------- /cfg/eks-1.0.1/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.0.1" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/eks-1.1.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | ## These settings are required if you are using the --asff option to report findings to AWS Security Hub 4 | ## AWS account number is required. 5 | AWS_ACCOUNT: "" 6 | ## AWS region is required. 7 | AWS_REGION: "" 8 | ## EKS Cluster ARN is required. 9 | CLUSTER_ARN: "" 10 | -------------------------------------------------------------------------------- /cfg/eks-1.1.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.1.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Logging" 10 | checks: 11 | - id: 2.1.1 12 | text: "Enable audit logs (Manual)" 13 | remediation: "Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler." 14 | scored: false 15 | -------------------------------------------------------------------------------- /cfg/eks-1.1.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.1.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/eks-1.2.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | ## These settings are required if you are using the --asff option to report findings to AWS Security Hub 4 | ## AWS account number is required. 5 | AWS_ACCOUNT: "" 6 | ## AWS region is required. 7 | AWS_REGION: "" 8 | ## EKS Cluster ARN is required. 9 | CLUSTER_ARN: "" 10 | -------------------------------------------------------------------------------- /cfg/eks-1.2.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.2.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Logging" 10 | checks: 11 | - id: 2.1.1 12 | text: "Enable audit logs (Manual)" 13 | remediation: "Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler." 14 | scored: false 15 | -------------------------------------------------------------------------------- /cfg/eks-1.2.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.2.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/eks-1.5.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | ## These settings are required if you are using the --asff option to report findings to AWS Security Hub 4 | ## AWS account number is required. 5 | AWS_ACCOUNT: "" 6 | ## AWS region is required. 7 | AWS_REGION: "" 8 | ## EKS Cluster ARN is required. 9 | CLUSTER_ARN: "" 10 | -------------------------------------------------------------------------------- /cfg/eks-1.5.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.5.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Logging" 10 | checks: 11 | - id: 2.1.1 12 | text: "Enable audit Logs (Automated)" 13 | remediation: | 14 | From Console: 15 | 1. For each EKS Cluster in each region; 16 | 2. Go to 'Amazon EKS' > 'Clusters' > '' > 'Configuration' > 'Logging'. 17 | 3. Click 'Manage logging'. 18 | 4. Ensure that all options are toggled to 'Enabled'. 19 | API server: Enabled 20 | Audit: Enabled 21 | Authenticator: Enabled 22 | Controller manager: Enabled 23 | Scheduler: Enabled 24 | 5. Click 'Save Changes'. 25 | 26 | From CLI: 27 | # For each EKS Cluster in each region; 28 | aws eks update-cluster-config \ 29 | --region '${REGION_CODE}' \ 30 | --name '${CLUSTER_NAME}' \ 31 | --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' 32 | scored: false 33 | -------------------------------------------------------------------------------- /cfg/eks-1.5.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-1.5.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/eks-stig-kubernetes-v1r6/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | ## These settings are required if you are using the --asff option to report findings to AWS Security Hub 4 | ## AWS account number is required. 5 | AWS_ACCOUNT: "" 6 | ## AWS region is required. 7 | AWS_REGION: "" 8 | ## EKS Cluster ARN is required. 9 | CLUSTER_ARN: "" 10 | -------------------------------------------------------------------------------- /cfg/eks-stig-kubernetes-v1r6/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-stig-kubernetes-v1r6" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/eks-stig-kubernetes-v1r6/policies.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "eks-stig-kubernetes-v1r6" 4 | id: 4 5 | text: "Policies" 6 | type: "policies" 7 | groups: 8 | - id: 4.1 9 | text: "Policies - DISA Category Code I" 10 | checks: 11 | - id: V-242381 12 | text: "The Kubernetes Controller Manager must create unique service accounts for each work payload. (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Create explicit service accounts wherever a Kubernetes workload requires specific access 16 | to the Kubernetes API server. 17 | Modify the configuration of each default service account to include this value 18 | automountServiceAccountToken: false 19 | scored: false 20 | 21 | - id: V-242383 22 | text: "User-managed resources must be created in dedicated namespaces. (Manual)" 23 | type: "manual" 24 | remediation: | 25 | Move any user-managed resources from the default, kube-public and kube-node-lease namespaces, to user namespaces. 26 | scored: false 27 | 28 | - id: V-242417 29 | text: "Kubernetes must separate user functionality. (Manual)" 30 | type: "manual" 31 | remediation: | 32 | Move any user pods that are present in the Kubernetes system namespaces to user specific namespaces. 33 | scored: false 34 | -------------------------------------------------------------------------------- /cfg/gke-1.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/gke-1.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.0" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Not Scored)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | You can remediate the availability of client certificates in your GKE cluster. See 18 | Recommendation 6.8.2. 19 | scored: false 20 | 21 | - id: 3.2 22 | text: "Logging" 23 | type: skip 24 | checks: 25 | - id: 3.2.1 26 | text: "Ensure that a minimal audit policy is created (Not Scored)" 27 | remediation: "This control cannot be modified in GKE." 28 | scored: false 29 | 30 | - id: 3.2.2 31 | text: "Ensure that the audit policy covers key security concerns (Not Scored) " 32 | remediation: "This control cannot be modified in GKE." 33 | scored: false 34 | -------------------------------------------------------------------------------- /cfg/gke-1.0/etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.0" 4 | id: 2 5 | text: "Etcd Node Configuration" 6 | type: "etcd" 7 | groups: 8 | - id: 2 9 | text: "Etcd Node Configuration Files" 10 | type: skip 11 | checks: 12 | - id: 2.1 13 | text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Not Scored)" 14 | remediation: "This control cannot be modified in GKE." 15 | scored: false 16 | 17 | - id: 2.2 18 | text: "Ensure that the --client-cert-auth argument is set to true (Not Scored)" 19 | remediation: "This control cannot be modified in GKE." 20 | scored: false 21 | 22 | - id: 2.3 23 | text: "Ensure that the --auto-tls argument is not set to true (Not Scored)" 24 | remediation: "This control cannot be modified in GKE." 25 | scored: false 26 | 27 | - id: 2.4 28 | text: "Ensure that the --peer-cert-file and --peer-key-file arguments are 29 | set as appropriate (Not Scored)" 30 | remediation: "This control cannot be modified in GKE." 31 | scored: false 32 | 33 | - id: 2.5 34 | text: "Ensure that the --peer-client-cert-auth argument is set to true (Not Scored)" 35 | remediation: "This control cannot be modified in GKE." 36 | scored: false 37 | 38 | - id: 2.6 39 | text: "Ensure that the --peer-auto-tls argument is not set to true (Not Scored)" 40 | remediation: "This control cannot be modified in GKE." 41 | scored: false 42 | 43 | - id: 2.7 44 | text: "Ensure that a unique Certificate Authority is used for etcd (Not Scored)" 45 | remediation: "This control cannot be modified in GKE." 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/gke-1.2.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/gke-1.2.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.2.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 2.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | You can remediate the availability of client certificates in your GKE cluster. See 18 | Recommendation 6.8.2. 19 | scored: false 20 | 21 | - id: 2.2 22 | text: "Logging" 23 | type: skip 24 | checks: 25 | - id: 2.2.1 26 | text: "Ensure that a minimal audit policy is created (Manual)" 27 | type: "manual" 28 | remediation: "This control cannot be modified in GKE." 29 | scored: false 30 | 31 | - id: 2.2.2 32 | text: "Ensure that the audit policy covers key security concerns (Manual)" 33 | type: "manual" 34 | remediation: "This control cannot be modified in GKE." 35 | scored: false 36 | -------------------------------------------------------------------------------- /cfg/gke-1.2.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.2.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/gke-1.6.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | node: 5 | proxy: 6 | defaultkubeconfig: "/var/lib/kubelet/kubeconfig" 7 | 8 | kubelet: 9 | defaultconf: "/etc/kubernetes/kubelet/kubelet-config.yaml" 10 | -------------------------------------------------------------------------------- /cfg/gke-1.6.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.6.0" 4 | id: 2 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 2.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 2.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | 18 | You can remediate the availability of client certificates in your GKE cluster. See 19 | Recommendation 5.8.1. 20 | scored: false 21 | -------------------------------------------------------------------------------- /cfg/gke-1.6.0/master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "gke-1.6.0" 4 | id: 1 5 | text: "Control Plane Components" 6 | type: "master" 7 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.23/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | master: 5 | components: 6 | - apiserver 7 | - scheduler 8 | - controllermanager 9 | - etcd 10 | - policies 11 | 12 | apiserver: 13 | bins: 14 | - containerd 15 | 16 | scheduler: 17 | bins: 18 | - containerd 19 | 20 | controllermanager: 21 | bins: 22 | - containerd 23 | 24 | etcd: 25 | bins: 26 | - containerd 27 | datadirs: 28 | - /var/lib/rancher/k3s/server/db/etcd 29 | node: 30 | components: 31 | - kubelet 32 | - proxy 33 | 34 | kubelet: 35 | bins: 36 | - containerd 37 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 38 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 39 | 40 | proxy: 41 | bins: 42 | - containerd 43 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig 44 | 45 | policies: 46 | components: 47 | - policies 48 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.23/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "k3s-cis-1.23" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'" 25 | type: "manual" 26 | tests: 27 | test_items: 28 | - flag: "--audit-policy-file" 29 | set: true 30 | remediation: | 31 | Create an audit policy file for your cluster. 32 | scored: false 33 | 34 | - id: 3.2.2 35 | text: "Ensure that the audit policy covers key security concerns (Manual)" 36 | type: "manual" 37 | remediation: | 38 | Review the audit policy provided for the cluster and ensure that it covers 39 | at least the following areas, 40 | - Access to Secrets managed by the cluster. Care should be taken to only 41 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 42 | order to avoid risk of logging sensitive data. 43 | - Modification of Pod and Deployment objects. 44 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 45 | For most requests, minimally logging at the Metadata level is recommended 46 | (the most basic level of logging). 47 | scored: false 48 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.24/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | master: 5 | components: 6 | - apiserver 7 | - scheduler 8 | - controllermanager 9 | - etcd 10 | - policies 11 | 12 | apiserver: 13 | bins: 14 | - containerd 15 | 16 | scheduler: 17 | bins: 18 | - containerd 19 | kubeconfig: 20 | - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig 21 | 22 | controllermanager: 23 | bins: 24 | - containerd 25 | kubeconfig: 26 | - /var/lib/rancher/k3s/server/cred/controller.kubeconfig 27 | 28 | 29 | etcd: 30 | bins: 31 | - containerd 32 | 33 | etcd: 34 | components: 35 | - etcd 36 | 37 | etcd: 38 | confs: /var/lib/rancher/k3s/server/db/etcd/config 39 | 40 | node: 41 | components: 42 | - kubelet 43 | - proxy 44 | 45 | kubelet: 46 | bins: 47 | - containerd 48 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 49 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 50 | 51 | proxy: 52 | bins: 53 | - containerd 54 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig 55 | 56 | policies: 57 | components: 58 | - policies 59 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.24/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "k3s-cis-1.24" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Automated)" 24 | audit: "journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: false 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.7/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | master: 5 | components: 6 | - apiserver 7 | - kubelet 8 | - scheduler 9 | - controllermanager 10 | - etcd 11 | - policies 12 | 13 | apiserver: 14 | bins: 15 | - containerd 16 | 17 | kubelet: 18 | bins: 19 | - containerd 20 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 21 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 22 | 23 | scheduler: 24 | bins: 25 | - containerd 26 | kubeconfig: 27 | - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig 28 | 29 | controllermanager: 30 | bins: 31 | - containerd 32 | kubeconfig: 33 | - /var/lib/rancher/k3s/server/cred/controller.kubeconfig 34 | 35 | etcd: 36 | bins: 37 | - containerd 38 | 39 | etcd: 40 | components: 41 | - etcd 42 | 43 | etcd: 44 | confs: /var/lib/rancher/k3s/server/db/etcd/config 45 | 46 | node: 47 | components: 48 | - kubelet 49 | - proxy 50 | 51 | kubelet: 52 | bins: 53 | - containerd 54 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 55 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 56 | 57 | proxy: 58 | bins: 59 | - containerd 60 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig 61 | 62 | policies: 63 | components: 64 | - policies 65 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.7/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "k3s-cis-1.7" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | - id: 3.1.2 19 | text: "Service account token authentication should not be used for users (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 23 | in place of service account tokens. 24 | scored: false 25 | - id: 3.1.3 26 | text: "Bootstrap token authentication should not be used for users (Manual)" 27 | type: "manual" 28 | remediation: | 29 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 30 | in place of bootstrap tokens. 31 | scored: false 32 | 33 | - id: 3.2 34 | text: "Logging" 35 | checks: 36 | - id: 3.2.1 37 | text: "Ensure that a minimal audit policy is created (Manual)" 38 | audit: "journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'" 39 | tests: 40 | test_items: 41 | - flag: "--audit-policy-file" 42 | set: true 43 | remediation: | 44 | Create an audit policy file for your cluster. 45 | scored: false 46 | 47 | - id: 3.2.2 48 | text: "Ensure that the audit policy covers key security concerns (Manual)" 49 | type: "manual" 50 | remediation: | 51 | Review the audit policy provided for the cluster and ensure that it covers 52 | at least the following areas, 53 | - Access to Secrets managed by the cluster. Care should be taken to only 54 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 55 | order to avoid risk of logging sensitive data. 56 | - Modification of Pod and Deployment objects. 57 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 58 | For most requests, minimally logging at the Metadata level is recommended 59 | (the most basic level of logging). 60 | scored: false 61 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.8/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | 4 | master: 5 | components: 6 | - apiserver 7 | - kubelet 8 | - scheduler 9 | - controllermanager 10 | - etcd 11 | - policies 12 | apiserver: 13 | bins: 14 | - containerd 15 | kubelet: 16 | bins: 17 | - containerd 18 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 19 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 20 | scheduler: 21 | bins: 22 | - containerd 23 | kubeconfig: 24 | - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig 25 | controllermanager: 26 | bins: 27 | - containerd 28 | kubeconfig: 29 | - /var/lib/rancher/k3s/server/cred/controller.kubeconfig 30 | etcd: 31 | bins: 32 | - containerd 33 | 34 | etcd: 35 | confs: /var/lib/rancher/k3s/server/db/etcd/config 36 | 37 | node: 38 | components: 39 | - kubelet 40 | - proxy 41 | kubelet: 42 | bins: 43 | - containerd 44 | confs: 45 | - /var/lib/rancher/k3s/agent/kubelet.kubeconfig 46 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig 47 | defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt 48 | proxy: 49 | bins: 50 | - containerd 51 | defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig 52 | policies: 53 | components: 54 | - policies 55 | -------------------------------------------------------------------------------- /cfg/k3s-cis-1.8/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "k3s-cis-1.8" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.1.2 20 | text: "Service account token authentication should not be used for users (Manual)" 21 | type: "manual" 22 | remediation: | 23 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 24 | in place of service account tokens. 25 | scored: false 26 | 27 | - id: 3.1.3 28 | text: "Bootstrap token authentication should not be used for users (Manual)" 29 | type: "manual" 30 | remediation: | 31 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 32 | in place of bootstrap tokens. 33 | scored: false 34 | 35 | - id: 3.2 36 | text: "Logging" 37 | checks: 38 | - id: 3.2.1 39 | text: "Ensure that a minimal audit policy is created (Manual)" 40 | audit: "journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'" 41 | tests: 42 | test_items: 43 | - flag: "--audit-policy-file" 44 | set: true 45 | remediation: | 46 | Create an audit policy file for your cluster. 47 | scored: false 48 | 49 | - id: 3.2.2 50 | text: "Ensure that the audit policy covers key security concerns (Manual)" 51 | type: "manual" 52 | remediation: | 53 | Review the audit policy provided for the cluster and ensure that it covers 54 | at least the following areas, 55 | - Access to Secrets managed by the cluster. Care should be taken to only 56 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 57 | order to avoid risk of logging sensitive data. 58 | - Modification of Pod and Deployment objects. 59 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 60 | For most requests, minimally logging at the Metadata level is recommended 61 | (the most basic level of logging). 62 | scored: false 63 | -------------------------------------------------------------------------------- /cfg/rh-0.7/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rh-1.0/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rh-1.0/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: rh-1.0 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | audit: | 14 | # To verify user authentication is enabled 15 | oc describe authentication 16 | # To verify that an identity provider is configured 17 | oc get identity 18 | # To verify that a custom cluster-admin user exists 19 | oc get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind | grep cluster-admin | grep User 20 | # To verity that kbueadmin is removed, no results should be returned 21 | oc get secrets kubeadmin -n kube-system 22 | type: manual 23 | remediation: | 24 | Configure an identity provider for the OpenShift cluster. 25 | Understanding identity provider configuration | Authentication | OpenShift 26 | Container Platform 4.5. Once an identity provider has been defined, 27 | you can use RBAC to define and apply permissions. 28 | After you define an identity provider and create a new cluster-admin user, 29 | remove the kubeadmin user to improve cluster security. 30 | scored: false 31 | 32 | - id: 3.2 33 | text: "Logging" 34 | checks: 35 | - id: 3.2.1 36 | text: "Ensure that a minimal audit policy is created (Manual)" 37 | audit: | 38 | #To view kube apiserver log files 39 | oc adm node-logs --role=master --path=kube-apiserver/ 40 | #To view openshift apiserver log files 41 | oc adm node-logs --role=master --path=openshift-apiserver/ 42 | #To verify kube apiserver audit config 43 | oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.auditConfig[]?' 44 | #To verify openshift apiserver audit config 45 | oc get configmap config -n openshift-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.auditConfig[]?' 46 | type: manual 47 | remediation: | 48 | No remediation required. 49 | scored: false 50 | 51 | - id: 3.2.2 52 | text: "Ensure that the audit policy covers key security concerns (Manual)" 53 | audit: | 54 | #To verify openshift apiserver audit config 55 | oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.auditConfig.policyConfiguration.rules[]?' 56 | #To verify kube apiserver audit config 57 | oc get configmap config -n openshift-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.auditConfig.policyConfiguration.rules[]?' 58 | type: manual 59 | remediation: | 60 | In OpenShift 4.6 and higher, if appropriate for your needs, 61 | modify the audit policy. 62 | scored: false 63 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.23/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.23/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke-cis-1.23" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Manual)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: true 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.24/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.24/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke-cis-1.24" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Automated)" 24 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 25 | tests: 26 | test_items: 27 | - flag: "--audit-policy-file" 28 | set: true 29 | remediation: | 30 | Create an audit policy file for your cluster. 31 | scored: true 32 | 33 | - id: 3.2.2 34 | text: "Ensure that the audit policy covers key security concerns (Manual)" 35 | type: "manual" 36 | remediation: | 37 | Review the audit policy provided for the cluster and ensure that it covers 38 | at least the following areas, 39 | - Access to Secrets managed by the cluster. Care should be taken to only 40 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 41 | order to avoid risk of logging sensitive data. 42 | - Modification of Pod and Deployment objects. 43 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 44 | For most requests, minimally logging at the Metadata level is recommended 45 | (the most basic level of logging). 46 | scored: false 47 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.7/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke-cis-1.7/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke-cis-1.7" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | - id: 3.1.2 19 | text: "Service account token authentication should not be used for users (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 23 | in place of service account tokens. 24 | scored: false 25 | - id: 3.1.3 26 | text: "Bootstrap token authentication should not be used for users (Manual)" 27 | type: "manual" 28 | remediation: | 29 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 30 | in place of bootstrap tokens. 31 | scored: false 32 | 33 | - id: 3.2 34 | text: "Logging" 35 | checks: 36 | - id: 3.2.1 37 | text: "Ensure that a minimal audit policy is created (Automated)" 38 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 39 | tests: 40 | test_items: 41 | - flag: "--audit-policy-file" 42 | set: true 43 | remediation: | 44 | Create an audit policy file for your cluster. 45 | scored: true 46 | 47 | - id: 3.2.2 48 | text: "Ensure that the audit policy covers key security concerns (Manual)" 49 | type: "manual" 50 | remediation: | 51 | Review the audit policy provided for the cluster and ensure that it covers 52 | at least the following areas, 53 | - Access to Secrets managed by the cluster. Care should be taken to only 54 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 55 | order to avoid risk of logging sensitive data. 56 | - Modification of Pod and Deployment objects. 57 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 58 | For most requests, minimally logging at the Metadata level is recommended 59 | (the most basic level of logging). 60 | scored: false 61 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.23/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.23/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke2-cis-1.23" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Automated)" 24 | audit: "/bin/ps -ef | grep kube-apiserver | grep -v grep | grep -o audit-policy-file" 25 | type: "skip" 26 | tests: 27 | test_items: 28 | - flag: "--audit-policy-file" 29 | compare: 30 | op: eq 31 | value: "--audit-policy-file" 32 | set: true 33 | remediation: | 34 | Create an audit policy file for your cluster. 35 | scored: true 36 | 37 | - id: 3.2.2 38 | text: "Ensure that the audit policy covers key security concerns (Manual)" 39 | type: "manual" 40 | remediation: | 41 | Review the audit policy provided for the cluster and ensure that it covers 42 | at least the following areas, 43 | - Access to Secrets managed by the cluster. Care should be taken to only 44 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 45 | order to avoid risk of logging sensitive data. 46 | - Modification of Pod and Deployment objects. 47 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 48 | For most requests, minimally logging at the Metadata level is recommended 49 | (the most basic level of logging). 50 | scored: false 51 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.24/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.24/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke2-cis-1.24" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | 19 | - id: 3.2 20 | text: "Logging" 21 | checks: 22 | - id: 3.2.1 23 | text: "Ensure that a minimal audit policy is created (Automated)" 24 | audit: "/bin/ps -ef | grep kube-apiserver | grep -v grep | grep -o audit-policy-file" 25 | type: "skip" 26 | tests: 27 | test_items: 28 | - flag: "--audit-policy-file" 29 | compare: 30 | op: eq 31 | value: "--audit-policy-file" 32 | set: true 33 | remediation: | 34 | Create an audit policy file for your cluster. 35 | scored: true 36 | 37 | - id: 3.2.2 38 | text: "Ensure that the audit policy covers key security concerns (Manual)" 39 | type: "manual" 40 | remediation: | 41 | Review the audit policy provided for the cluster and ensure that it covers 42 | at least the following areas, 43 | - Access to Secrets managed by the cluster. Care should be taken to only 44 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 45 | order to avoid risk of logging sensitive data. 46 | - Modification of Pod and Deployment objects. 47 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 48 | For most requests, minimally logging at the Metadata level is recommended 49 | (the most basic level of logging). 50 | scored: false 51 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.7/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/rke2-cis-1.7/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "rke2-cis-1.7" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users (Manual)" 13 | type: "manual" 14 | remediation: | 15 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 16 | implemented in place of client certificates. 17 | scored: false 18 | - id: 3.1.2 19 | text: "Service account token authentication should not be used for users (Manual)" 20 | type: "manual" 21 | remediation: | 22 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 23 | in place of service account tokens. 24 | scored: false 25 | - id: 3.1.3 26 | text: "Bootstrap token authentication should not be used for users (Manual)" 27 | type: "manual" 28 | remediation: | 29 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented 30 | in place of bootstrap tokens. 31 | scored: false 32 | 33 | - id: 3.2 34 | text: "Logging" 35 | checks: 36 | - id: 3.2.1 37 | text: "Ensure that a minimal audit policy is created (Automated)" 38 | type: "skip" 39 | audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" 40 | tests: 41 | test_items: 42 | - flag: "--audit-policy-file" 43 | set: true 44 | remediation: | 45 | Create an audit policy file for your cluster. 46 | Permissive. 47 | scored: true 48 | 49 | - id: 3.2.2 50 | text: "Ensure that the audit policy covers key security concerns (Manual)" 51 | type: "manual" 52 | remediation: | 53 | Review the audit policy provided for the cluster and ensure that it covers 54 | at least the following areas, 55 | - Access to Secrets managed by the cluster. Care should be taken to only 56 | log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in 57 | order to avoid risk of logging sensitive data. 58 | - Modification of Pod and Deployment objects. 59 | - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`. 60 | For most requests, minimally logging at the Metadata level is recommended 61 | (the most basic level of logging). 62 | scored: false 63 | -------------------------------------------------------------------------------- /cfg/tkgi-1.2.53/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ## Version-specific settings that override the values in cfg/config.yaml 3 | -------------------------------------------------------------------------------- /cfg/tkgi-1.2.53/controlplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "tkgi-1.2.53" 4 | id: 3 5 | text: "Control Plane Configuration" 6 | type: "controlplane" 7 | groups: 8 | - id: 3.1 9 | text: "Authentication and Authorization" 10 | checks: 11 | - id: 3.1.1 12 | text: "Client certificate authentication should not be used for users" 13 | audit: ps -ef | grep kube-apiserver | grep -- "--oidc-issuer-url=" 14 | type: "manual" 15 | remediation: | 16 | Alternative mechanisms provided by Kubernetes such as the use of OIDC should be 17 | implemented in place of client certificates. 18 | Exception 19 | This setting is site-specific. It can be set in the "Configure created clusters to use UAA as the OIDC provider." 20 | section of the "UAA" 21 | scored: false 22 | 23 | - id: 3.2 24 | text: "Logging" 25 | checks: 26 | - id: 3.2.1 27 | text: "Ensure that a minimal audit policy is created" 28 | audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- "--audit-policy-file=" 29 | tests: 30 | test_items: 31 | - flag: "--audit-policy-file" 32 | remediation: | 33 | Create an audit policy file for your cluster. 34 | scored: true 35 | 36 | - id: 3.2.2 37 | text: "Ensure that the audit policy covers key security concerns" 38 | audit: | 39 | diff /var/vcap/jobs/kube-apiserver/config/audit_policy.yml \ <(echo "--- apiVersion: audit.k8s.io/v1beta1 kind: 40 | Policy rules: - level: None resources: - group: '' resources: - endpoints - services - services/status users: - 41 | system:kube-proxy verbs: - watch - level: None resources: - group: '' resources: - nodes - nodes/status users: - 42 | kubelet verbs: - get - level: None resources: - group: '' resources: - nodes - nodes/status userGroups: - 43 | system:nodes verbs: - get - level: None namespaces: - kube-system resources: - group: '' resources: - 44 | endpoints users: - system:kube-controller-manager - system:kube-scheduler - system:serviceaccount:kube- 45 | system:endpoint-controller verbs: - get - update - level: None resources: - group: '' resources: - namespaces - 46 | namespaces/status - namespaces/finalize users: - system:apiserver verbs: - get - level: None resources: - 47 | group: metrics.k8s.io users: - system:kube-controller-manager verbs: - get - list - level: None 48 | nonResourceURLs: - \"/healthz*\" - \"/version\" - \"/swagger*\" - level: None resources: - group: '' resources: - 49 | events - level: Request omitStages: - RequestReceived resources: - group: '' resources: - nodes/status - 50 | pods/status userGroups: - system:nodes verbs: - update - patch - level: Request omitStages: - 51 | RequestReceived users: - system:serviceaccount:kube-system:namespace-controller verbs: - deletecollection - 52 | level: Metadata omitStages: - RequestReceived resources: - group: '' resources: - secrets - configmaps - group: 53 | authentication.k8s.io resources: - tokenreviews - level: Request omitStages: - RequestReceived resources: - 54 | group: '' - group: admissionregistration.k8s.io - group: apiextensions.k8s.io - group: apiregistration.k8s.io - 55 | group: apps - group: authentication.k8s.io - group: authorization.k8s.io - group: autoscaling - group: batch - 56 | group: certificates.k8s.io - group: extensions - group: metrics.k8s.io - group: networking.k8s.io - group: policy - 57 | group: rbac.authorization.k8s.io - group: settings.k8s.io - group: storage.k8s.io verbs: - get - list - watch - level: 58 | RequestResponse omitStages: - RequestReceived resources: - group: '' - group: admissionregistration.k8s.io - 59 | group: apiextensions.k8s.io - group: apiregistration.k8s.io - group: apps - group: authentication.k8s.io - group: 60 | authorization.k8s.io - group: autoscaling - group: batch - group: certificates.k8s.io - group: extensions - group: 61 | metrics.k8s.io - group: networking.k8s.io - group: policy - group: rbac.authorization.k8s.io - group: 62 | settings.k8s.io - group: storage.k8s.io - level: Metadata omitStages: - RequestReceived ") 63 | type: "manual" 64 | remediation: | 65 | Consider modification of the audit policy in use on the cluster to include these items, at a 66 | minimum. 67 | scored: false 68 | -------------------------------------------------------------------------------- /cfg/tkgi-1.2.53/etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | controls: 3 | version: "tkgi-1.2.53" 4 | id: 2 5 | text: "Etcd Node Configuration" 6 | type: "etcd" 7 | groups: 8 | - id: 2 9 | text: "Etcd Node Configuration Files" 10 | checks: 11 | - id: 2.1 12 | text: "Ensure that the --cert-file and --key-file arguments are set as appropriate" 13 | audit: ps -ef | grep etcd | grep -- "--cert-file=/var/vcap/jobs/etcd/config/etcd.crt" | grep -- "--key-file=/var/vcap/jobs/etcd/config/etcd.key" 14 | type: manual 15 | tests: 16 | bin_op: and 17 | test_items: 18 | - flag: "--cert-file" 19 | - flag: "--key-file" 20 | remediation: | 21 | Follow the etcd service documentation and configure TLS encryption. 22 | Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml 23 | on the master node and set the below parameters. 24 | --cert-file= 25 | --key-file= 26 | scored: false 27 | 28 | - id: 2.2 29 | text: "Ensure that the --client-cert-auth argument is set to true" 30 | audit: ps -ef | grep etcd | grep -- "--client\-cert\-auth" 31 | tests: 32 | test_items: 33 | - flag: "--client-cert-auth" 34 | compare: 35 | op: eq 36 | value: true 37 | remediation: | 38 | Edit the etcd pod specification file etcd config on the master 39 | node and set the below parameter. 40 | --client-cert-auth="true" 41 | scored: true 42 | 43 | - id: 2.3 44 | text: "Ensure that the --auto-tls argument is not set to true" 45 | audit: ps -ef | grep etcd | grep -v -- "--auto-tls" 46 | tests: 47 | test_items: 48 | - flag: "--auto-tls" 49 | compare: 50 | op: eq 51 | value: true 52 | set: false 53 | remediation: | 54 | Edit the etcd pod specification file etcd config on the master 55 | node and either remove the --auto-tls parameter or set it to false. 56 | --auto-tls=false 57 | scored: true 58 | 59 | - id: 2.4 60 | text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate" 61 | audit: ps -ef | grep etcd | grep -- "--peer-cert-file=/var/vcap/jobs/etcd/config/peer.crt" | grep -- "--peer-key-file=/var/vcap/jobs/etcd/config/peer.key" 62 | type: manual 63 | tests: 64 | bin_op: and 65 | test_items: 66 | - flag: "--peer-cert-file" 67 | - flag: "--peer-key-file" 68 | remediation: | 69 | Follow the etcd service documentation and configure peer TLS encryption as appropriate 70 | for your etcd cluster. 71 | Then, edit the etcd pod specification file etcd config on the 72 | master node and set the below parameters. 73 | --peer-client-file= 74 | --peer-key-file= 75 | scored: false 76 | 77 | - id: 2.5 78 | text: "Ensure that the --peer-client-cert-auth argument is set to true" 79 | audit: ps -ef | grep etcd | grep -- "--peer\-client\-cert\-auth" 80 | tests: 81 | test_items: 82 | - flag: "--peer-client-cert-auth" 83 | compare: 84 | op: eq 85 | value: true 86 | remediation: | 87 | Edit the etcd pod specification file etcd config on the master 88 | node and set the below parameter. 89 | --peer-client-cert-auth=true 90 | scored: true 91 | 92 | - id: 2.6 93 | text: "Ensure that the --peer-auto-tls argument is not set to true" 94 | audit: ps -ef | grep etcd | grep -v -- "--peer-auto-tls" 95 | tests: 96 | test_items: 97 | - flag: "--peer-auto-tls" 98 | compare: 99 | op: eq 100 | value: true 101 | set: false 102 | remediation: | 103 | Edit the etcd pod specification file etcd config on the master 104 | node and either remove the --peer-auto-tls parameter or set it to false. 105 | --peer-auto-tls=false 106 | scored: true 107 | 108 | - id: 2.7 109 | text: "Ensure that a unique Certificate Authority is used for etcd" 110 | audit: diff /var/vcap/jobs/kube-apiserver/config/kubernetes-ca.pem /var/vcap/jobs/etcd/config/etcd-ca.crt | grep -c"^>" | grep -v "^0$" 111 | type: manual 112 | tests: 113 | test_items: 114 | - flag: "--trusted-ca-file" 115 | remediation: | 116 | Follow the etcd documentation and create a dedicated certificate authority setup for the 117 | etcd service. 118 | Then, edit the etcd pod specification file etcd config on the 119 | master node and set the below parameter. 120 | --trusted-ca-file= 121 | scored: false 122 | -------------------------------------------------------------------------------- /cmd/database.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | 8 | "github.com/golang/glog" 9 | "github.com/spf13/viper" 10 | "gorm.io/driver/postgres" 11 | "gorm.io/gorm" 12 | ) 13 | 14 | type PsqlConnInfo struct { 15 | Host string 16 | User string 17 | DbName string 18 | SslMode string 19 | Password string 20 | } 21 | 22 | func getPsqlConnInfo() (PsqlConnInfo, error) { 23 | var host string 24 | if value := viper.GetString("PGSQL_HOST"); value != "" { 25 | host = value 26 | } else { 27 | return PsqlConnInfo{}, fmt.Errorf("%s_PGSQL_HOST env var is required", envVarsPrefix) 28 | } 29 | 30 | var user string 31 | if value := viper.GetString("PGSQL_USER"); value != "" { 32 | user = value 33 | } else { 34 | return PsqlConnInfo{}, fmt.Errorf("%s_PGSQL_USER env var is required", envVarsPrefix) 35 | } 36 | 37 | var dbName string 38 | if value := viper.GetString("PGSQL_DBNAME"); value != "" { 39 | dbName = value 40 | } else { 41 | return PsqlConnInfo{}, fmt.Errorf("%s_PGSQL_DBNAME env var is required", envVarsPrefix) 42 | } 43 | 44 | var sslMode string 45 | if value := viper.GetString("PGSQL_SSLMODE"); value != "" { 46 | sslMode = value 47 | } else { 48 | return PsqlConnInfo{}, fmt.Errorf("%s_PGSQL_SSLMODE env var is required", envVarsPrefix) 49 | } 50 | 51 | var password string 52 | if value := viper.GetString("PGSQL_PASSWORD"); value != "" { 53 | password = value 54 | } else { 55 | return PsqlConnInfo{}, fmt.Errorf("%s_PGSQL_PASSWORD env var is required", envVarsPrefix) 56 | } 57 | 58 | return PsqlConnInfo{ 59 | Host: host, 60 | User: user, 61 | DbName: dbName, 62 | SslMode: sslMode, 63 | Password: password, 64 | }, nil 65 | } 66 | 67 | func (c *PsqlConnInfo) toString() string { 68 | return fmt.Sprintf("host=%s user=%s dbname=%s sslmode=%s password=%s", 69 | c.Host, 70 | c.User, 71 | c.DbName, 72 | c.SslMode, 73 | c.Password, 74 | ) 75 | } 76 | 77 | func savePgsql(jsonInfo string) { 78 | var hostname string 79 | if value := viper.GetString("K8S_HOST"); value != "" { 80 | // Adhere to the ScanHost column definition below 81 | if len(value) > 63 { 82 | exitWithError(fmt.Errorf("%s_K8S_HOST value's length must be less than 63 chars", envVarsPrefix)) 83 | } 84 | 85 | hostname = value 86 | } else { 87 | host, err := os.Hostname() 88 | if err != nil { 89 | exitWithError(fmt.Errorf("received error looking up hostname: %s", err)) 90 | } 91 | 92 | hostname = host 93 | } 94 | 95 | PsqlConnInfo, err := getPsqlConnInfo() 96 | if err != nil { 97 | exitWithError(err) 98 | } 99 | 100 | db, err := gorm.Open(postgres.Open(PsqlConnInfo.toString()), &gorm.Config{}) 101 | if err != nil { 102 | exitWithError(fmt.Errorf("received error connecting to database: %s", err)) 103 | } 104 | 105 | timestamp := time.Now() 106 | type ScanResult struct { 107 | gorm.Model 108 | ScanHost string `gorm:"type:varchar(63) not null"` // https://www.ietf.org/rfc/rfc1035.txt 109 | ScanTime time.Time `gorm:"not null"` 110 | ScanInfo string `gorm:"type:jsonb not null"` 111 | } 112 | 113 | db.Debug().AutoMigrate(&ScanResult{}) 114 | db.Save(&ScanResult{ScanHost: hostname, ScanTime: timestamp, ScanInfo: jsonInfo}) 115 | glog.V(2).Info(fmt.Sprintf("successfully stored result to: %s", PsqlConnInfo.Host)) 116 | } 117 | -------------------------------------------------------------------------------- /cmd/run.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/aquasecurity/kube-bench/check" 10 | "github.com/golang/glog" 11 | "github.com/spf13/cobra" 12 | "github.com/spf13/viper" 13 | ) 14 | 15 | func init() { 16 | RootCmd.AddCommand(runCmd) 17 | runCmd.Flags().StringSliceP("targets", "s", []string{}, 18 | `Specify targets of the benchmark to run. These names need to match the filenames in the cfg/ directory. 19 | For example, to run the tests specified in master.yaml and etcd.yaml, specify --targets=master,etcd 20 | If no targets are specified, run tests from all files in the cfg/ directory. 21 | `) 22 | } 23 | 24 | // runCmd represents the run command 25 | var runCmd = &cobra.Command{ 26 | Use: "run", 27 | Short: "Run tests", 28 | Long: `Run tests. If no arguments are specified, runs tests from all files`, 29 | Run: func(cmd *cobra.Command, args []string) { 30 | targets, err := cmd.Flags().GetStringSlice("targets") 31 | if err != nil { 32 | exitWithError(fmt.Errorf("unable to get `targets` from command line :%v", err)) 33 | } 34 | 35 | bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper()) 36 | if err != nil { 37 | exitWithError(fmt.Errorf("unable to get benchmark version. error: %v", err)) 38 | } 39 | 40 | glog.V(2).Infof("Checking targets %v for %v", targets, bv) 41 | benchmarkVersionToTargetsMap, err := loadTargetMapping(viper.GetViper()) 42 | if err != nil { 43 | exitWithError(fmt.Errorf("error loading targets: %v", err)) 44 | } 45 | valid, err := validTargets(bv, targets, viper.GetViper()) 46 | if err != nil { 47 | exitWithError(fmt.Errorf("error validating targets: %v", err)) 48 | } 49 | if len(targets) > 0 && !valid { 50 | exitWithError(fmt.Errorf(`The specified --targets "%s" are not configured for the CIS Benchmark %s\n Valid targets %v`, strings.Join(targets, ","), bv, benchmarkVersionToTargetsMap[bv])) 51 | } 52 | 53 | // Merge version-specific config if any. 54 | path := filepath.Join(cfgDir, bv) 55 | err = mergeConfig(path) 56 | if err != nil { 57 | exitWithError(fmt.Errorf("Error in mergeConfig: %v\n", err)) 58 | } 59 | 60 | err = run(targets, bv) 61 | if err != nil { 62 | exitWithError(fmt.Errorf("Error in run: %v\n", err)) 63 | } 64 | 65 | os.Exit(exitCodeSelection(controlsCollection)) 66 | }, 67 | } 68 | 69 | func run(targets []string, benchmarkVersion string) (err error) { 70 | yamlFiles, err := getTestYamlFiles(targets, benchmarkVersion) 71 | if err != nil { 72 | return err 73 | } 74 | 75 | glog.V(3).Infof("Running tests from files %v\n", yamlFiles) 76 | 77 | for _, yamlFile := range yamlFiles { 78 | _, name := filepath.Split(yamlFile) 79 | testType := check.NodeType(strings.Split(name, ".")[0]) 80 | runChecks(testType, yamlFile, detecetedKubeVersion) 81 | } 82 | 83 | writeOutput(controlsCollection) 84 | return nil 85 | } 86 | 87 | func getTestYamlFiles(targets []string, benchmarkVersion string) (yamlFiles []string, err error) { 88 | // Check that the specified targets have corresponding YAML files in the config directory 89 | configFileDirectory := filepath.Join(cfgDir, benchmarkVersion) 90 | for _, target := range targets { 91 | filename := translate(target) + ".yaml" 92 | file := filepath.Join(configFileDirectory, filename) 93 | if _, err := os.Stat(file); err != nil { 94 | return nil, fmt.Errorf("file %s not found for version %s", filename, benchmarkVersion) 95 | } 96 | yamlFiles = append(yamlFiles, file) 97 | } 98 | 99 | // If no targets were specified, we will run tests from all the files in the directory 100 | if len(yamlFiles) == 0 { 101 | yamlFiles, err = getYamlFilesFromDir(configFileDirectory) 102 | if err != nil { 103 | return nil, err 104 | } 105 | } 106 | 107 | return yamlFiles, err 108 | } 109 | 110 | func translate(target string) string { 111 | return strings.Replace(strings.ToLower(target), "worker", "node", -1) 112 | } 113 | -------------------------------------------------------------------------------- /cmd/run_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | ) 8 | 9 | func TestGetTestYamlFiles(t *testing.T) { 10 | cases := []struct { 11 | name string 12 | targets []string 13 | benchmark string 14 | succeed bool 15 | expCount int 16 | }{ 17 | { 18 | name: "Specify two targets", 19 | targets: []string{"one", "two"}, 20 | benchmark: "benchmark", 21 | succeed: true, 22 | expCount: 2, 23 | }, 24 | { 25 | name: "Specify a target that doesn't exist", 26 | targets: []string{"one", "missing"}, 27 | benchmark: "benchmark", 28 | succeed: false, 29 | }, 30 | { 31 | name: "No targets specified - should return everything except config.yaml", 32 | targets: []string{}, 33 | benchmark: "benchmark", 34 | succeed: true, 35 | expCount: 3, 36 | }, 37 | { 38 | name: "Specify benchmark that doesn't exist", 39 | targets: []string{"one"}, 40 | benchmark: "missing", 41 | succeed: false, 42 | }, 43 | } 44 | 45 | // Set up temp config directory 46 | var err error 47 | cfgDir, err = os.MkdirTemp("", "kube-bench-test") 48 | if err != nil { 49 | t.Fatalf("Failed to create temp directory") 50 | } 51 | defer os.RemoveAll(cfgDir) 52 | 53 | d := filepath.Join(cfgDir, "benchmark") 54 | err = os.Mkdir(d, 0766) 55 | if err != nil { 56 | t.Fatalf("Failed to create temp dir") 57 | } 58 | 59 | // We never expect config.yaml to be returned 60 | for _, filename := range []string{"one.yaml", "two.yaml", "three.yaml", "config.yaml"} { 61 | err = os.WriteFile(filepath.Join(d, filename), []byte("hello world"), 0666) 62 | if err != nil { 63 | t.Fatalf("error writing temp file %s: %v", filename, err) 64 | } 65 | } 66 | 67 | for _, c := range cases { 68 | t.Run(c.name, func(t *testing.T) { 69 | yamlFiles, err := getTestYamlFiles(c.targets, c.benchmark) 70 | if err != nil && c.succeed { 71 | t.Fatalf("Error %v", err) 72 | } 73 | 74 | if err == nil && !c.succeed { 75 | t.Fatalf("Expected failure") 76 | } 77 | 78 | if len(yamlFiles) != c.expCount { 79 | t.Fatalf("Expected %d, got %d", c.expCount, len(yamlFiles)) 80 | } 81 | }) 82 | } 83 | } 84 | 85 | func TestTranslate(t *testing.T) { 86 | cases := []struct { 87 | name string 88 | original string 89 | expected string 90 | }{ 91 | { 92 | name: "keep", 93 | original: "controlplane", 94 | expected: "controlplane", 95 | }, 96 | { 97 | name: "translate", 98 | original: "worker", 99 | expected: "node", 100 | }, 101 | { 102 | name: "translateLower", 103 | original: "Worker", 104 | expected: "node", 105 | }, 106 | { 107 | name: "Lower", 108 | original: "ETCD", 109 | expected: "etcd", 110 | }, 111 | } 112 | 113 | for _, c := range cases { 114 | t.Run(c.name, func(t *testing.T) { 115 | ret := translate(c.original) 116 | if ret != c.expected { 117 | t.Fatalf("Expected %q, got %q", c.expected, ret) 118 | } 119 | }) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /cmd/securityHub.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/aquasecurity/kube-bench/internal/findings" 9 | "github.com/aws/aws-sdk-go-v2/config" 10 | "github.com/aws/aws-sdk-go-v2/service/securityhub" 11 | "github.com/aws/aws-sdk-go-v2/service/securityhub/types" 12 | "github.com/spf13/viper" 13 | ) 14 | 15 | // REGION ... 16 | const REGION = "AWS_REGION" 17 | 18 | func writeFinding(in []types.AwsSecurityFinding) error { 19 | r := viper.GetString(REGION) 20 | if len(r) == 0 { 21 | return fmt.Errorf("%s not set", REGION) 22 | } 23 | cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(r)) 24 | if err != nil { 25 | return err 26 | } 27 | 28 | svc := securityhub.NewFromConfig(cfg) 29 | p := findings.New(*svc) 30 | out, perr := p.PublishFinding(in) 31 | print(out) 32 | return perr 33 | } 34 | 35 | func print(out *findings.PublisherOutput) { 36 | if out.SuccessCount > 0 { 37 | log.Printf("Number of findings that were successfully imported:%v\n", out.SuccessCount) 38 | } 39 | if out.FailedCount > 0 { 40 | log.Printf("Number of findings that failed to import:%v\n", out.FailedCount) 41 | for _, f := range out.FailedFindings { 42 | log.Printf("ID:%s", *f.Id) 43 | log.Printf("Message:%s", *f.ErrorMessage) 44 | log.Printf("Error Code:%s", *f.ErrorCode) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /cmd/testdata/passedControlsCollection.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "2", 4 | "version": "1.15", 5 | "text": "Etcd Node Configuration", 6 | "node_type": "etcd", 7 | "tests": [ 8 | { 9 | "section": "2", 10 | "pass": 7, 11 | "fail": 0, 12 | "warn": 0, 13 | "info": 0, 14 | "desc": "Etcd Node Configuration Files", 15 | "results": [ 16 | { 17 | "test_number": "2.1", 18 | "test_desc": "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)", 19 | "audit": "/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep", 20 | "AuditConfig": "", 21 | "type": "", 22 | "remediation": "Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=\n--key-file=\n", 23 | "test_info": [ 24 | "Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=\n--key-file=\n" 25 | ], 26 | "status": "PASS", 27 | "actual_value": "root 3277 3218 3 Apr19 ? 03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\nroot 4624 4605 8 Apr21 ? 04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\n", 28 | "scored": true, 29 | "expected_result": "'--cert-file' is present AND '--key-file' is present" 30 | } 31 | ] 32 | } 33 | ], 34 | "total_pass": 7, 35 | "total_fail": 0, 36 | "total_warn": 0, 37 | "total_info": 0 38 | }, 39 | { 40 | "id": "3", 41 | "version": "1.5", 42 | "text": "Control Plane Configuration", 43 | "node_type": "controlplane", 44 | "tests": [ 45 | { 46 | "section": "3.1", 47 | "pass": 0, 48 | "fail": 0, 49 | "warn": 1, 50 | "info": 0, 51 | "desc": "Authentication and Authorization", 52 | "results": [ 53 | { 54 | "test_number": "3.1.1", 55 | "test_desc": "Client certificate authentication should not be used for users (Not Scored)", 56 | "audit": "", 57 | "AuditConfig": "", 58 | "type": "manual", 59 | "remediation": "Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n", 60 | "test_info": [ 61 | "Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n" 62 | ], 63 | "status": "WARN", 64 | "actual_value": "", 65 | "scored": false, 66 | "expected_result": "", 67 | "reason": "Test marked as a manual test" 68 | } 69 | ] 70 | } 71 | ], 72 | "total_pass": 0, 73 | "total_fail": 0, 74 | "total_warn": 3, 75 | "total_info": 0 76 | } 77 | ] 78 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var KubeBenchVersion string 10 | 11 | // versionCmd represents the version command 12 | var versionCmd = &cobra.Command{ 13 | Use: "version", 14 | Short: "Shows the version of kube-bench.", 15 | Long: `Shows the version of kube-bench.`, 16 | Run: func(cmd *cobra.Command, args []string) { 17 | fmt.Println(KubeBenchVersion) 18 | }, 19 | } 20 | 21 | func init() { 22 | RootCmd.AddCommand(versionCmd) 23 | } 24 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | coverage: 3 | status: 4 | project: 5 | default: 6 | target: auto # auto compares coverage to the previous base commit 7 | threshold: 1% 8 | -------------------------------------------------------------------------------- /docs/architecture.md: -------------------------------------------------------------------------------- 1 | ## Test config YAML representation 2 | 3 | The tests (or "controls") are maintained in YAML documents. There are different versions of these test YAML files reflecting different [versions and platforms of the CIS Kubernetes Benchmark](./platforms.md). You will find more information about the test file YAML definitions in our [controls documentation](./controls.md). 4 | 5 | ## Kube-bench benchmarks 6 | 7 | The test files for the various versions of Benchmarks can be found in directories 8 | with same name as the Benchmark versions under the `cfg` directory next to the kube-bench executable, 9 | for example `./cfg/cis-1.5` will contain all test files for [CIS Kubernetes Benchmark v1.5.1](https://workbench.cisecurity.org/benchmarks/4892) which are: 10 | master.yaml, controlplane.yaml, node.yaml, etcd.yaml, policies.yaml and config.yaml 11 | 12 | Check the contents of the benchmark directory under `cfg` to see which targets are available for that benchmark. Each file except `config.yaml` represents a target (also known as a `control` in other parts of this documentation). 13 | 14 | The following table shows the valid targets based on the CIS Benchmark version. 15 | 16 | | CIS Benchmark | Targets | 17 | |----------------------|---------| 18 | | cis-1.5 | master, controlplane, node, etcd, policies | 19 | | cis-1.6 | master, controlplane, node, etcd, policies | 20 | | cis-1.20 | master, controlplane, node, etcd, policies | 21 | | cis-1.23 | master, controlplane, node, etcd, policies | 22 | | cis-1.24 | master, controlplane, node, etcd, policies | 23 | | cis-1.7 | master, controlplane, node, etcd, policies | 24 | | cis-1.8 | master, controlplane, node, etcd, policies | 25 | | cis-1.9 | master, controlplane, node, etcd, policies | 26 | | cis-1.10 | master, controlplane, node, etcd, policies | 27 | | gke-1.0 | master, controlplane, node, etcd, policies, managedservices | 28 | | gke-1.2.0 | controlplane, node, policies, managedservices | 29 | | gke-1.6.0 | controlplane, node, policies, managedservices | 30 | | eks-1.0.1 | controlplane, node, policies, managedservices | 31 | | eks-1.1.0 | controlplane, node, policies, managedservices | 32 | | eks-1.2.0 | controlplane, node, policies, managedservices | 33 | | eks-1.5.0 | controlplane, node, policies, managedservices | 34 | | ack-1.0 | master, controlplane, node, etcd, policies, managedservices | 35 | | aks-1.0 | controlplane, node, policies, managedservices | 36 | | rh-0.7 | master,node| 37 | | rh-1.0 | master, controlplane, node, etcd, policies | 38 | | cis-1.6-k3s | master, controlplane, node, etcd, policies | 39 | | cis-1.24-microk8s | master, controlplane, node, etcd, policies | 40 | 41 | The following table shows the valid DISA STIG versions 42 | 43 | | STIG | Targets | 44 | |----------------------------|---------| 45 | | eks-stig-kubernetes-v1r6 | master, controlplane, node, policies, managedservices | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/asff.md: -------------------------------------------------------------------------------- 1 | # Integrating kube-bench with AWS Security Hub 2 | 3 | You can configure kube-bench with the `--asff` to send findings to AWS Security Hub. There are some additional steps required so that kube-bench has information and permissions to send these findings. 4 | 5 | ## Enable the AWS Security Hub integration 6 | 7 | * You will need AWS Security Hub to be enabled in your account 8 | * In the Security Hub console, under Integrations, search for kube-bench 9 | 10 |

11 | 12 |

13 | 14 | * Click on `Accept findings`. This gives information about the IAM permissions required to send findings to your Security Hub account. kube-bench runs within a pod on your EKS cluster, and will need to be associated with a Role that has these permissions. 15 | 16 | ## Configure permissions in an IAM Role 17 | 18 | * Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two options: 19 | * You can run the kube-bench pod under a specific [service account associated with an IAM role](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) that has these permissions to write Security Hub findings. 20 | * Alternatively the pod can be granted permissions specified by the Role that your [EKS node group uses](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html). 21 | 22 | Here is an example IAM Policy that you can attach to your EKS node group's IAM Role: 23 | 24 | ```json 25 | { 26 | "Version": "2012-10-17", 27 | "Statement": [ 28 | { 29 | "Effect": "Allow", 30 | "Action": "securityhub:BatchImportFindings", 31 | "Resource": [ 32 | "arn:aws:securityhub:us-east-1::product/aqua-security/kube-bench" 33 | ] 34 | } 35 | ] 36 | } 37 | ``` 38 | 39 | ### Modify the job configuration 40 | 41 | * Modify the kube-bench Configmap in `job-eks-asff.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN. 42 | * In the same file, modify the image specifed in the Job to use the kube-bench image pushed to your ECR 43 | * [Optional] - If you have created a dedicated IAM role to be used with kube-bench as described above in [Configure permissions in an IAM Role](#configure-permissions-in-an-iam-role), you will need to add the IAM role arn to the kube-bench ServiceAccount in `job-eks-asff.yaml`. 44 | * Make sure that `job-eks-asff.yaml` specifies the container image you just pushed to your ECR registry. 45 | 46 | You can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks-asff.yaml` 47 | 48 | Findings will be generated for any kube-bench test that generates a `[FAIL]` or `[WARN]` output. If all tests pass, no findings will be generated. However, it's recommended that you consult the pod log output to check whether any findings were generated but could not be written to Security Hub. 49 | 50 |

51 | 52 |

53 | 54 | [eks-instructions]: ../README.md#running-in-an-EKS-cluster 55 | -------------------------------------------------------------------------------- /docs/images/asff-example-finding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/asff-example-finding.png -------------------------------------------------------------------------------- /docs/images/kube-bench-logo-only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/kube-bench-logo-only.png -------------------------------------------------------------------------------- /docs/images/kube-bench-security-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/kube-bench-security-hub.png -------------------------------------------------------------------------------- /docs/images/kube-bench.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/kube-bench.jpg -------------------------------------------------------------------------------- /docs/images/kube-bench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/kube-bench.png -------------------------------------------------------------------------------- /docs/images/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/kube-bench/2077fcf1e0a89d5da8dd33126ebe9c0f40431a64/docs/images/output.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | [download]: https://img.shields.io/github/downloads/aquasecurity/kube-bench/total?logo=github 2 | [release-img]: https://img.shields.io/github/release/aquasecurity/kube-bench.svg?logo=github 3 | [release]: https://github.com/aquasecurity/kube-bench/releases 4 | [docker-pull]: https://img.shields.io/docker/pulls/aquasec/kube-bench?logo=docker&label=docker%20pulls%20%2F%20kube-bench 5 | [docker]: https://hub.docker.com/r/aquasec/kube-bench 6 | [cov-img]: https://codecov.io/github/aquasecurity/kube-bench/branch/main/graph/badge.svg 7 | [cov]: https://codecov.io/github/aquasecurity/kube-bench 8 | [report-card-img]: https://goreportcard.com/badge/github.com/aquasecurity/kube-bench 9 | [report-card]: https://goreportcard.com/report/github.com/aquasecurity/kube-bench 10 | 11 | ![Kube-bench Logo](images/kube-bench.jpg) 12 | [![GitHub Release][release-img]][release] 13 | [![Downloads][download]][release] 14 | [![Docker Pulls][docker-pull]][docker] 15 | [![Go Report Card][report-card-img]][report-card] 16 | [![Build Status](https://github.com/aquasecurity/kube-bench/workflows/Build/badge.svg?branch=main)](https://github.com/aquasecurity/kube-bench/actions) 17 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/aquasecurity/kube-bench/blob/main/LICENSE) 18 | [![Coverage Status][cov-img]][cov] 19 | 20 | 21 | # Kube-bench 22 | 23 | kube-bench is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/). 24 | 25 | Tests are configured with YAML files, making this tool easy to update as test specifications evolve. 26 | 27 | 28 | 1. kube-bench implements the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/) as closely as possible. Please raise issues here if kube-bench is not correctly implementing the test as described in the Benchmark. To report issues in the Benchmark itself (for example, tests that you believe are inappropriate), please join the [CIS community](https://cisecurity.org). 29 | 30 | 1. There is not a one-to-one mapping between releases of Kubernetes and releases of the CIS benchmark. See [CIS Kubernetes Benchmark support](#cis-kubernetes-benchmark-support) to see which releases of Kubernetes are covered by different releases of the benchmark. 31 | 32 | 1. It is impossible to inspect the master nodes of managed clusters, e.g. GKE, EKS, AKS and ACK, using kube-bench as one does not have access to such nodes, although it is still possible to use kube-bench to check worker node configuration in these environments. 33 | 34 | For help and more information go to our [github discussions q&a](https://github.com/aquasecurity/kube-bench/discussions/categories/q-a) 35 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | You can choose to 4 | * Run kube-bench from inside a container (sharing PID namespace with the host). See [Running inside a container](./running.md#running-inside-a-container) for additional details. 5 | * Run a container that installs kube-bench on the host, and then run kube-bench directly on the host. See [Installing from a container](#installing-from-a-container) for additional details. 6 | * install the latest binaries from the [Releases page](https://github.com/aquasecurity/kube-bench/releases), though please note that you also need to download the config and test files from the `cfg` directory. See [Download and Install binaries](#download-and-install-binaries) for details. 7 | * Compile it from source. See [Installing from sources](#installing-from-sources) for details. 8 | 9 | 10 | ### Download and Install binaries 11 | 12 | It is possible to manually install and run kube-bench release binaries. In order to do that, you must have access to your Kubernetes cluster nodes. Note that if you're using one of the managed Kubernetes services (e.g. EKS, AKS, GKE, ACK, OCP), you will not have access to the master nodes of your cluster and you can’t perform any tests on the master nodes. 13 | 14 | First, log into one of the nodes using SSH. 15 | 16 | Install kube-bench binary for your platform using the commands below. Note that there may be newer releases available. See [releases page](https://github.com/aquasecurity/kube-bench/releases). 17 | 18 | Ubuntu/Debian: 19 | 20 | ``` 21 | KUBE_BENCH_VERSION=0.10.1 22 | 23 | curl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb 24 | 25 | sudo apt install ./kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb -f 26 | ``` 27 | 28 | RHEL: 29 | 30 | ``` 31 | KUBE_BENCH_VERSION=0.10.1 32 | 33 | curl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm 34 | 35 | sudo yum install kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm -y 36 | ``` 37 | 38 | Alternatively, you can manually download and extract the kube-bench binary: 39 | 40 | ``` 41 | KUBE_BENCH_VERSION=0.10.1 42 | 43 | curl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz 44 | 45 | tar -xvf kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz 46 | ``` 47 | 48 | You can then run kube-bench directly: 49 | ``` 50 | kube-bench 51 | ``` 52 | 53 | If you manually downloaded the kube-bench binary (using curl command above), you have to specify the location of configuration directory and file. For example: 54 | ``` 55 | ./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml 56 | ``` 57 | 58 | See previous section on [Running kube-bench](./running.md#running-kube-bench) for further details on using the kube-bench binary. 59 | 60 | ### Installing from sources 61 | 62 | If Go is installed on the target machines, you can simply clone this repository and run as follows (assuming your [`GOPATH` is set](https://github.com/golang/go/wiki/GOPATH)) as per this example: 63 | 64 | ```shell 65 | # Create a target directory for the clone, inside the $GOPATH 66 | mkdir -p $GOPATH/src/github.com/aquasecurity/kube-bench 67 | 68 | # Clone this repository, using SSH 69 | git clone git@github.com:aquasecurity/kube-bench.git $GOPATH/src/github.com/aquasecurity/kube-bench 70 | 71 | # Install the pre-requisites 72 | go get github.com/aquasecurity/kube-bench 73 | 74 | # Change to the kube-bench directory 75 | cd $GOPATH/src/github.com/aquasecurity/kube-bench 76 | 77 | # Build the kube-bench binary 78 | go build -o kube-bench . 79 | 80 | # See all supported options 81 | ./kube-bench --help 82 | 83 | # Run all checks 84 | ./kube-bench 85 | ``` 86 | 87 | 88 | ### Installing from a container 89 | 90 | This command copies the kube-bench binary and configuration files to your host from the Docker container: 91 | **binaries compiled for linux-x86-64 only (so they won't run on macOS or Windows)** 92 | ``` 93 | docker run --rm -v `pwd`:/host docker.io/aquasec/kube-bench:latest install 94 | ``` 95 | 96 | You can then run `./kube-bench`. 97 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | if [ "$1" == "install" ]; then 3 | if [ -d /host ]; then 4 | mkdir -p /host/cfg/ 5 | yes | cp -rf cfg/* /host/cfg/ 6 | yes | cp -rf /usr/local/bin/kube-bench /host/ 7 | echo "===============================================" 8 | echo "kube-bench is now installed on your host " 9 | echo "Run ./kube-bench to perform a security check " 10 | echo "===============================================" 11 | else 12 | echo "Usage:" 13 | echo " install: docker run --rm -v \`pwd\`:/host aquasec/kube-bench install" 14 | echo " run: docker run --rm --pid=host aquasec/kube-bench [command]" 15 | exit 16 | fi 17 | else 18 | exec kube-bench "$@" 19 | fi 20 | -------------------------------------------------------------------------------- /fipsonly.go: -------------------------------------------------------------------------------- 1 | //go:build fipsonly 2 | 3 | package main 4 | 5 | import ( 6 | _ "crypto/tls/fipsonly" 7 | ) 8 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/kube-bench 2 | 3 | go 1.24.2 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go-v2 v1.36.3 7 | github.com/aws/aws-sdk-go-v2/config v1.29.14 8 | github.com/aws/aws-sdk-go-v2/service/securityhub v1.57.4 9 | github.com/fatih/color v1.18.0 10 | github.com/golang/glog v1.2.5 11 | github.com/magiconair/properties v1.8.10 12 | github.com/onsi/ginkgo v1.16.5 13 | github.com/pkg/errors v0.9.1 14 | github.com/spf13/cobra v1.9.1 15 | github.com/spf13/viper v1.20.1 16 | github.com/stretchr/testify v1.10.0 17 | gopkg.in/yaml.v2 v2.4.0 18 | gorm.io/driver/postgres v1.5.11 19 | gorm.io/gorm v1.30.0 20 | k8s.io/apimachinery v0.33.1 21 | k8s.io/client-go v0.33.1 22 | ) 23 | 24 | require ( 25 | github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect 26 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect 27 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect 28 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect 29 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect 30 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect 31 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect 32 | github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect 33 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect 34 | github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect 35 | github.com/aws/smithy-go v1.22.2 // indirect 36 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 37 | github.com/emicklei/go-restful/v3 v3.11.0 // indirect 38 | github.com/fsnotify/fsnotify v1.8.0 // indirect 39 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 40 | github.com/go-logr/logr v1.4.2 // indirect 41 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 42 | github.com/go-openapi/jsonreference v0.20.2 // indirect 43 | github.com/go-openapi/swag v0.23.0 // indirect 44 | github.com/go-viper/mapstructure/v2 v2.2.1 // indirect 45 | github.com/gogo/protobuf v1.3.2 // indirect 46 | github.com/google/gnostic-models v0.6.9 // indirect 47 | github.com/google/go-cmp v0.7.0 // indirect 48 | github.com/google/uuid v1.6.0 // indirect 49 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 50 | github.com/jackc/pgpassfile v1.0.0 // indirect 51 | github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect 52 | github.com/jackc/pgx/v5 v5.5.5 // indirect 53 | github.com/jackc/puddle/v2 v2.2.1 // indirect 54 | github.com/jinzhu/inflection v1.0.0 // indirect 55 | github.com/jinzhu/now v1.1.5 // indirect 56 | github.com/josharian/intern v1.0.0 // indirect 57 | github.com/json-iterator/go v1.1.12 // indirect 58 | github.com/mailru/easyjson v0.7.7 // indirect 59 | github.com/mattn/go-colorable v0.1.13 // indirect 60 | github.com/mattn/go-isatty v0.0.20 // indirect 61 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 62 | github.com/modern-go/reflect2 v1.0.2 // indirect 63 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 64 | github.com/pelletier/go-toml/v2 v2.2.3 // indirect 65 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 66 | github.com/sagikazarmark/locafero v0.7.0 // indirect 67 | github.com/sourcegraph/conc v0.3.0 // indirect 68 | github.com/spf13/afero v1.12.0 // indirect 69 | github.com/spf13/cast v1.7.1 // indirect 70 | github.com/spf13/pflag v1.0.6 // indirect 71 | github.com/stretchr/objx v0.5.2 // indirect 72 | github.com/subosito/gotenv v1.6.0 // indirect 73 | github.com/x448/float16 v0.8.4 // indirect 74 | go.uber.org/atomic v1.10.0 // indirect 75 | go.uber.org/multierr v1.9.0 // indirect 76 | golang.org/x/crypto v0.36.0 // indirect 77 | golang.org/x/net v0.38.0 // indirect 78 | golang.org/x/oauth2 v0.27.0 // indirect 79 | golang.org/x/sync v0.12.0 // indirect 80 | golang.org/x/sys v0.31.0 // indirect 81 | golang.org/x/term v0.30.0 // indirect 82 | golang.org/x/text v0.23.0 // indirect 83 | golang.org/x/time v0.9.0 // indirect 84 | google.golang.org/protobuf v1.36.5 // indirect 85 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 86 | gopkg.in/inf.v0 v0.9.1 // indirect 87 | gopkg.in/yaml.v3 v3.0.1 // indirect 88 | k8s.io/api v0.33.1 // indirect 89 | k8s.io/klog/v2 v2.130.1 // indirect 90 | k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect 91 | k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect 92 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect 93 | sigs.k8s.io/randfill v1.0.0 // indirect 94 | sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect 95 | sigs.k8s.io/yaml v1.4.0 // indirect 96 | ) 97 | -------------------------------------------------------------------------------- /hack/debug.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # use this pod with: kubectl run ubuntu -it --pid=host -- /bin/bash 3 | # this allows you to debug what is running on the host. 4 | apiVersion: v1 5 | kind: Pod 6 | metadata: 7 | name: ubuntu 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: ubuntu 12 | image: ubuntu 13 | command: ["/bin/bash", "-c", "--"] 14 | args: ["while true; do sleep 30; done;"] 15 | env: 16 | - name: PATH 17 | value: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/mount-from-host/bin" 18 | volumeMounts: 19 | - name: var-lib-kubelet 20 | mountPath: /var/lib/kubelet 21 | - name: etc-systemd 22 | mountPath: /etc/systemd 23 | - name: etc-kubernetes 24 | mountPath: /etc/kubernetes 25 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 26 | # You can omit this mount if you specify --version as part of the command. 27 | - name: usr-bin 28 | mountPath: /usr/local/mount-from-host/bin 29 | - name: kind-bin 30 | mountPath: /kind/bin 31 | resources: 32 | limits: 33 | memory: "128Mi" 34 | cpu: "500m" 35 | volumes: 36 | - name: var-lib-kubelet 37 | hostPath: 38 | path: "/var/lib/kubelet" 39 | - name: etc-systemd 40 | hostPath: 41 | path: "/etc/systemd" 42 | - name: etc-kubernetes 43 | hostPath: 44 | path: "/etc/kubernetes" 45 | - name: usr-bin 46 | hostPath: 47 | path: "/usr/bin" 48 | - name: kind-bin 49 | hostPath: 50 | path: "/kind/bin" 51 | -------------------------------------------------------------------------------- /hack/kind-stig.test.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | metadata: 9 | labels: 10 | app: kube-bench 11 | spec: 12 | hostPID: true 13 | containers: 14 | - name: kube-bench 15 | image: docker.io/aquasec/kube-bench:latest 16 | command: [ 17 | "kube-bench", 18 | "run", 19 | "--benchmark", 20 | "eks-stig-kubernetes-v1r6", 21 | ] 22 | volumeMounts: 23 | - name: var-lib-etcd 24 | mountPath: /var/lib/etcd 25 | - name: var-lib-kubelet 26 | mountPath: /var/lib/kubelet 27 | - name: etc-systemd 28 | mountPath: /etc/systemd 29 | - name: etc-kubernetes 30 | mountPath: /etc/kubernetes 31 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 32 | # You can omit this mount if you specify --version as part of the command. 33 | - name: usr-bin 34 | mountPath: /usr/local/mount-from-host/bin 35 | - name: kind-bin 36 | mountPath: /kind/bin 37 | restartPolicy: Never 38 | volumes: 39 | - name: var-lib-etcd 40 | hostPath: 41 | path: "/var/lib/etcd" 42 | - name: var-lib-kubelet 43 | hostPath: 44 | path: "/var/lib/kubelet" 45 | - name: etc-systemd 46 | hostPath: 47 | path: "/etc/systemd" 48 | - name: etc-kubernetes 49 | hostPath: 50 | path: "/etc/kubernetes" 51 | - name: usr-bin 52 | hostPath: 53 | path: "/usr/bin" 54 | - name: kind-bin 55 | hostPath: 56 | path: "/kind/bin" 57 | -------------------------------------------------------------------------------- /hack/kind-stig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | metadata: 9 | labels: 10 | app: kube-bench 11 | spec: 12 | hostPID: true 13 | containers: 14 | - name: kube-bench 15 | image: docker.io/aquasec/kube-bench:${VERSION} 16 | command: [ 17 | "kube-bench", 18 | "run", 19 | "--benchmark", 20 | "eks-stig-kubernetes-v1r6", 21 | ] 22 | volumeMounts: 23 | - name: var-lib-etcd 24 | mountPath: /var/lib/etcd 25 | - name: var-lib-kubelet 26 | mountPath: /var/lib/kubelet 27 | - name: etc-systemd 28 | mountPath: /etc/systemd 29 | - name: etc-kubernetes 30 | mountPath: /etc/kubernetes 31 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 32 | # You can omit this mount if you specify --version as part of the command. 33 | - name: usr-bin 34 | mountPath: /usr/local/mount-from-host/bin 35 | - name: kind-bin 36 | mountPath: /kind/bin 37 | restartPolicy: Never 38 | volumes: 39 | - name: var-lib-etcd 40 | hostPath: 41 | path: "/var/lib/etcd" 42 | - name: var-lib-kubelet 43 | hostPath: 44 | path: "/var/lib/kubelet" 45 | - name: etc-systemd 46 | hostPath: 47 | path: "/etc/systemd" 48 | - name: etc-kubernetes 49 | hostPath: 50 | path: "/etc/kubernetes" 51 | - name: usr-bin 52 | hostPath: 53 | path: "/usr/bin" 54 | - name: kind-bin 55 | hostPath: 56 | path: "/kind/bin" 57 | -------------------------------------------------------------------------------- /hack/kind.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | metadata: 9 | labels: 10 | app: kube-bench 11 | spec: 12 | hostPID: true 13 | containers: 14 | - name: kube-bench 15 | image: docker.io/aquasec/kube-bench:${VERSION} 16 | command: ["kube-bench"] 17 | volumeMounts: 18 | - name: var-lib-etcd 19 | mountPath: /var/lib/etcd 20 | - name: var-lib-kubelet 21 | mountPath: /var/lib/kubelet 22 | - name: etc-systemd 23 | mountPath: /etc/systemd 24 | - name: etc-kubernetes 25 | mountPath: /etc/kubernetes 26 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 27 | # You can omit this mount if you specify --version as part of the command. 28 | - name: usr-bin 29 | mountPath: /usr/local/mount-from-host/bin 30 | - name: kind-bin 31 | mountPath: /kind/bin 32 | restartPolicy: Never 33 | volumes: 34 | - name: var-lib-etcd 35 | hostPath: 36 | path: "/var/lib/etcd" 37 | - name: var-lib-kubelet 38 | hostPath: 39 | path: "/var/lib/kubelet" 40 | - name: etc-systemd 41 | hostPath: 42 | path: "/etc/systemd" 43 | - name: etc-kubernetes 44 | hostPath: 45 | path: "/etc/kubernetes" 46 | - name: usr-bin 47 | hostPath: 48 | path: "/usr/bin" 49 | - name: kind-bin 50 | hostPath: 51 | path: "/kind/bin" 52 | -------------------------------------------------------------------------------- /hack/node_only.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | node: 3 | components: 4 | - kubelet 5 | - proxy 6 | # kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark 7 | - kubernetes 8 | 9 | kubernetes: 10 | defaultconf: "/etc/kubernetes/config" 11 | 12 | kubelet: 13 | cafile: 14 | - "/etc/kubernetes/pki/ca.crt" 15 | - "/etc/kubernetes/certs/ca.crt" 16 | - "/etc/kubernetes/cert/ca.pem" 17 | svc: 18 | # These paths must also be included 19 | # in the 'confs' property below 20 | - "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" 21 | - "/etc/systemd/system/kubelet.service" 22 | - "/lib/systemd/system/kubelet.service" 23 | bins: 24 | - "hyperkube kubelet" 25 | - "kubelet" 26 | kubeconfig: 27 | - "/etc/kubernetes/kubelet.conf" 28 | - "/var/lib/kubelet/kubeconfig" 29 | - "/etc/kubernetes/kubelet-kubeconfig" 30 | confs: 31 | - "/var/lib/kubelet/config.yaml" 32 | - "/var/lib/kubelet/config.yml" 33 | - "/etc/kubernetes/kubelet/kubelet-config.json" 34 | - "/home/kubernetes/kubelet-config.yaml" 35 | - "/home/kubernetes/kubelet-config.yml" 36 | - "/etc/default/kubelet" 37 | ## Due to the fact that the kubelet might be configured 38 | ## without a kubelet-config file, we use a work-around 39 | ## of pointing to the systemd service file (which can also 40 | ## hold kubelet configuration). 41 | ## Note: The following paths must match the one under 'svc' 42 | - "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" 43 | - "/etc/systemd/system/kubelet.service" 44 | - "/lib/systemd/system/kubelet.service" 45 | defaultconf: "/var/lib/kubelet/config.yaml" 46 | defaultsvc: "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" 47 | defaultkubeconfig: "/etc/kubernetes/kubelet.conf" 48 | defaultcafile: "/etc/kubernetes/pki/ca.crt" 49 | 50 | proxy: 51 | bins: 52 | - "kube-proxy" 53 | - "hyperkube proxy" 54 | - "hyperkube kube-proxy" 55 | - "proxy" 56 | confs: 57 | - /etc/kubernetes/proxy 58 | - /etc/kubernetes/addons/kube-proxy-daemonset.yaml 59 | kubeconfig: 60 | - /etc/kubernetes/kubelet-kubeconfig 61 | svc: 62 | - "/lib/systemd/system/kube-proxy.service" 63 | defaultconf: /etc/kubernetes/addons/kube-proxy-daemonset.yaml 64 | defaultkubeconfig: "/etc/kubernetes/proxy.conf" 65 | 66 | version_mapping: 67 | "1.15": "cis-1.5" 68 | "1.16": "cis-1.6" 69 | "1.17": "cis-1.6" 70 | "1.18": "cis-1.6" 71 | "1.19": "cis-1.6" 72 | "ocp-3.10": "rh-0.7" 73 | "ocp-3.11": "rh-0.7" 74 | -------------------------------------------------------------------------------- /helper_scripts/check_files_owner_in_dir.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script is used to ensure the owner is set to root:root for 4 | # the given directory and all the files in it 5 | # 6 | # inputs: 7 | # $1 = /full/path/to/directory 8 | # 9 | # outputs: 10 | # true/false 11 | 12 | INPUT_DIR=$1 13 | 14 | if [[ "${INPUT_DIR}" == "" ]]; then 15 | echo "false" 16 | exit 17 | fi 18 | 19 | if [[ $(stat -c %U:%G ${INPUT_DIR}) != "root:root" ]]; then 20 | echo "false" 21 | exit 22 | fi 23 | 24 | statInfoLines=$(stat -c "%n %U:%G" ${INPUT_DIR}/*) 25 | while read -r statInfoLine; do 26 | f=$(echo ${statInfoLine} | cut -d' ' -f1) 27 | p=$(echo ${statInfoLine} | cut -d' ' -f2) 28 | 29 | if [[ $(basename "$f" .pem) == "kube-etcd-"* ]]; then 30 | if [[ "$p" != "root:root" && "$p" != "etcd:etcd" ]]; then 31 | echo "false" 32 | exit 33 | fi 34 | else 35 | if [[ "$p" != "root:root" ]]; then 36 | echo "false" 37 | exit 38 | fi 39 | fi 40 | done <<< "${statInfoLines}" 41 | 42 | 43 | echo "true" 44 | exit 45 | -------------------------------------------------------------------------------- /hooks/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # $IMAGE_NAME var is injected into the build so the tag is correct. 4 | docker build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 5 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 6 | --build-arg KUBEBENCH_VERSION=`git describe --tags --abbrev=0` \ 7 | -t $IMAGE_NAME . 8 | -------------------------------------------------------------------------------- /internal/findings/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package findings handles sending findings to Security Hub. 3 | */ 4 | package findings 5 | -------------------------------------------------------------------------------- /internal/findings/publisher.go: -------------------------------------------------------------------------------- 1 | package findings 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/aws/aws-sdk-go-v2/service/securityhub" 7 | "github.com/aws/aws-sdk-go-v2/service/securityhub/types" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | // A Publisher represents an object that publishes finds to AWS Security Hub. 12 | type Publisher struct { 13 | client securityhub.Client // AWS Security Hub Service Client 14 | } 15 | 16 | // A PublisherOutput represents an object that contains information about the service call. 17 | type PublisherOutput struct { 18 | // The number of findings that failed to import. 19 | // 20 | // FailedCount is a required field 21 | FailedCount int32 22 | 23 | // The list of findings that failed to import. 24 | FailedFindings []types.ImportFindingsError 25 | 26 | // The number of findings that were successfully imported. 27 | // 28 | // SuccessCount is a required field 29 | SuccessCount int32 30 | } 31 | 32 | // New creates a new Publisher. 33 | func New(client securityhub.Client) *Publisher { 34 | return &Publisher{ 35 | client: client, 36 | } 37 | } 38 | 39 | // PublishFinding publishes findings to AWS Security Hub Service 40 | func (p *Publisher) PublishFinding(finding []types.AwsSecurityFinding) (*PublisherOutput, error) { 41 | o := PublisherOutput{} 42 | i := securityhub.BatchImportFindingsInput{} 43 | i.Findings = finding 44 | var errs error 45 | 46 | // Split the slice into batches of 100 finding. 47 | batch := 100 48 | 49 | for i := 0; i < len(finding); i += batch { 50 | i := securityhub.BatchImportFindingsInput{} 51 | i.Findings = finding 52 | r, err := p.client.BatchImportFindings(context.Background(), &i) // Process the batch. 53 | if err != nil { 54 | errs = errors.Wrap(err, "finding publish failed") 55 | } 56 | if r != nil { 57 | if *r.FailedCount != 0 { 58 | o.FailedCount += *r.FailedCount 59 | } 60 | if *r.SuccessCount != 0 { 61 | o.SuccessCount += *r.SuccessCount 62 | } 63 | o.FailedFindings = append(o.FailedFindings, r.FailedFindings...) 64 | } 65 | } 66 | return &o, errs 67 | } 68 | -------------------------------------------------------------------------------- /job-ack.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: 14 | [ 15 | "kube-bench", 16 | "run", 17 | "--targets", 18 | "node,policies,managedservices", 19 | "--benchmark", 20 | "ack-1.0", 21 | ] 22 | volumeMounts: 23 | - name: var-lib-kubelet 24 | mountPath: /var/lib/kubelet 25 | readOnly: true 26 | - name: etc-systemd 27 | mountPath: /etc/systemd 28 | readOnly: true 29 | - name: etc-kubernetes 30 | mountPath: /etc/kubernetes 31 | readOnly: true 32 | restartPolicy: Never 33 | volumes: 34 | - name: var-lib-kubelet 35 | hostPath: 36 | path: "/var/lib/kubelet" 37 | - name: etc-systemd 38 | hostPath: 39 | path: "/etc/systemd" 40 | - name: etc-kubernetes 41 | hostPath: 42 | path: "/etc/kubernetes" 43 | -------------------------------------------------------------------------------- /job-aks.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: 14 | ["kube-bench", "run", "--targets", "node", "--benchmark", "aks-1.0"] 15 | volumeMounts: 16 | - name: var-lib-kubelet 17 | mountPath: /var/lib/kubelet 18 | readOnly: true 19 | - name: etc-systemd 20 | mountPath: /etc/systemd 21 | readOnly: true 22 | - name: etc-default 23 | mountPath: /etc/default 24 | readOnly: true 25 | - name: etc-kubernetes 26 | mountPath: /etc/kubernetes 27 | readOnly: true 28 | restartPolicy: Never 29 | volumes: 30 | - name: var-lib-kubelet 31 | hostPath: 32 | path: "/var/lib/kubelet" 33 | - name: etc-systemd 34 | hostPath: 35 | path: "/etc/systemd" 36 | - name: etc-default 37 | hostPath: 38 | path: "/etc/default" 39 | - name: etc-kubernetes 40 | hostPath: 41 | path: "/etc/kubernetes" 42 | -------------------------------------------------------------------------------- /job-eks-asff.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: kube-bench 6 | # If using a dedicated IAM role for kube-bench, uncomment the annotations 7 | # block below and replace the ROLE_ARN 8 | # annotations: 9 | # eks.amazonaws.com/role-arn: "" 10 | 11 | --- 12 | apiVersion: v1 13 | kind: ConfigMap 14 | metadata: 15 | name: kube-bench-eks-config 16 | data: 17 | config.yaml: | 18 | AWS_ACCOUNT: "" 19 | AWS_REGION: "" 20 | CLUSTER_ARN: "" 21 | 22 | --- 23 | apiVersion: batch/v1 24 | kind: Job 25 | metadata: 26 | name: kube-bench 27 | spec: 28 | template: 29 | spec: 30 | hostPID: true 31 | containers: 32 | - name: kube-bench 33 | # Push the image to your ECR and then refer to it here 34 | # image: 35 | image: docker.io/aquasec/kube-bench:latest 36 | command: 37 | [ 38 | "kube-bench", 39 | "run", 40 | "--targets", 41 | "node", 42 | "--benchmark", 43 | "eks-1.2.0", 44 | "--asff", 45 | ] 46 | env: 47 | - name: NODE_NAME 48 | valueFrom: 49 | fieldRef: 50 | fieldPath: spec.nodeName 51 | volumeMounts: 52 | - name: var-lib-kubelet 53 | mountPath: /var/lib/kubelet 54 | readOnly: true 55 | - name: etc-systemd 56 | mountPath: /etc/systemd 57 | readOnly: true 58 | - name: etc-kubernetes 59 | mountPath: /etc/kubernetes 60 | readOnly: true 61 | - name: kube-bench-eks-config 62 | mountPath: "/opt/kube-bench/cfg/eks-1.2.0/config.yaml" 63 | subPath: config.yaml 64 | readOnly: true 65 | restartPolicy: Never 66 | serviceAccountName: kube-bench 67 | volumes: 68 | - name: var-lib-kubelet 69 | hostPath: 70 | path: "/var/lib/kubelet" 71 | - name: etc-systemd 72 | hostPath: 73 | path: "/etc/systemd" 74 | - name: etc-kubernetes 75 | hostPath: 76 | path: "/etc/kubernetes" 77 | - name: kube-bench-eks-config 78 | configMap: 79 | name: kube-bench-eks-config 80 | items: 81 | - key: config.yaml 82 | path: config.yaml 83 | -------------------------------------------------------------------------------- /job-eks-stig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | # Push the image to your ECR and then refer to it here 13 | # image: 14 | image: docker.io/aquasec/kube-bench:latest 15 | # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead 16 | command: 17 | [ 18 | "kube-bench", 19 | "run", 20 | "--benchmark", 21 | "eks-stig-kubernetes-v1r6", 22 | ] 23 | volumeMounts: 24 | - name: var-lib-kubelet 25 | mountPath: /var/lib/kubelet 26 | readOnly: true 27 | - name: etc-systemd 28 | mountPath: /etc/systemd 29 | readOnly: true 30 | - name: etc-kubernetes 31 | mountPath: /etc/kubernetes 32 | readOnly: true 33 | restartPolicy: Never 34 | volumes: 35 | - name: var-lib-kubelet 36 | hostPath: 37 | path: "/var/lib/kubelet" 38 | - name: etc-systemd 39 | hostPath: 40 | path: "/etc/systemd" 41 | - name: etc-kubernetes 42 | hostPath: 43 | path: "/etc/kubernetes" 44 | -------------------------------------------------------------------------------- /job-eks.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | # Push the image to your ECR and then refer to it here 13 | # image: 14 | image: docker.io/aquasec/kube-bench:latest 15 | # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead 16 | command: 17 | [ 18 | "kube-bench", 19 | "run", 20 | "--targets", 21 | "node,policies,managedservices,controlplane", 22 | "--benchmark", 23 | "eks-1.5.0", 24 | ] 25 | volumeMounts: 26 | - name: var-lib-kubelet 27 | mountPath: /var/lib/kubelet 28 | readOnly: true 29 | - name: etc-systemd 30 | mountPath: /etc/systemd 31 | readOnly: true 32 | - name: etc-kubernetes 33 | mountPath: /etc/kubernetes 34 | readOnly: true 35 | restartPolicy: Never 36 | volumes: 37 | - name: var-lib-kubelet 38 | hostPath: 39 | path: "/var/lib/kubelet" 40 | - name: etc-systemd 41 | hostPath: 42 | path: "/etc/systemd" 43 | - name: etc-kubernetes 44 | hostPath: 45 | path: "/etc/kubernetes" 46 | -------------------------------------------------------------------------------- /job-gke.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: 14 | [ 15 | "kube-bench", 16 | "run", 17 | "--targets", 18 | "node,policies,managedservices", 19 | "--benchmark", 20 | "gke-1.2.0", 21 | ] 22 | volumeMounts: 23 | - name: var-lib-kubelet 24 | mountPath: /var/lib/kubelet 25 | readOnly: true 26 | - name: etc-systemd 27 | mountPath: /etc/systemd 28 | readOnly: true 29 | - name: etc-kubernetes 30 | mountPath: /etc/kubernetes 31 | readOnly: true 32 | - name: home-kubernetes 33 | mountPath: /home/kubernetes 34 | readOnly: true 35 | restartPolicy: Never 36 | volumes: 37 | - name: var-lib-kubelet 38 | hostPath: 39 | path: "/var/lib/kubelet" 40 | - name: etc-systemd 41 | hostPath: 42 | path: "/etc/systemd" 43 | - name: etc-kubernetes 44 | hostPath: 45 | path: "/etc/kubernetes" 46 | - name: home-kubernetes 47 | hostPath: 48 | path: "/home/kubernetes" 49 | -------------------------------------------------------------------------------- /job-iks.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: 14 | ["kube-bench", "run", "--targets", "node", "--version", "1.20"] 15 | volumeMounts: 16 | - name: var-lib-kubelet 17 | mountPath: /var/lib/kubelet 18 | readOnly: true 19 | - name: etc-systemd 20 | mountPath: /etc/systemd 21 | readOnly: true 22 | - name: etc-kubernetes 23 | mountPath: /etc/kubernetes 24 | readOnly: true 25 | restartPolicy: Never 26 | volumes: 27 | - name: var-lib-kubelet 28 | hostPath: 29 | path: "/var/lib/kubelet" 30 | - name: etc-systemd 31 | hostPath: 32 | path: "/lib/systemd" 33 | - name: etc-kubernetes 34 | hostPath: 35 | path: "/etc/kubernetes" 36 | - name: usr-bin 37 | hostPath: 38 | path: "/usr/bin" 39 | -------------------------------------------------------------------------------- /job-master.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench-master 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | affinity: 11 | nodeAffinity: 12 | requiredDuringSchedulingIgnoredDuringExecution: 13 | nodeSelectorTerms: 14 | - matchExpressions: 15 | - key: node-role.kubernetes.io/control-plane 16 | operator: Exists 17 | - matchExpressions: 18 | - key: node-role.kubernetes.io/master 19 | operator: Exists 20 | tolerations: 21 | - key: node-role.kubernetes.io/master 22 | operator: Exists 23 | effect: NoSchedule 24 | - key: node-role.kubernetes.io/control-plane 25 | operator: Exists 26 | effect: NoSchedule 27 | containers: 28 | - name: kube-bench 29 | image: docker.io/aquasec/kube-bench:latest 30 | command: ["kube-bench", "run", "--targets", "master"] 31 | volumeMounts: 32 | - name: var-lib-cni 33 | mountPath: /var/lib/cni 34 | readOnly: true 35 | - name: var-lib-etcd 36 | mountPath: /var/lib/etcd 37 | readOnly: true 38 | - name: var-lib-kubelet 39 | mountPath: /var/lib/kubelet 40 | readOnly: true 41 | - name: var-lib-kube-scheduler 42 | mountPath: /var/lib/kube-scheduler 43 | readOnly: true 44 | - name: var-lib-kube-controller-manager 45 | mountPath: /var/lib/kube-controller-manager 46 | readOnly: true 47 | - name: etc-systemd 48 | mountPath: /etc/systemd 49 | readOnly: true 50 | - name: lib-systemd 51 | mountPath: /lib/systemd/ 52 | readOnly: true 53 | - name: srv-kubernetes 54 | mountPath: /srv/kubernetes/ 55 | readOnly: true 56 | - name: etc-kubernetes 57 | mountPath: /etc/kubernetes 58 | readOnly: true 59 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 60 | # You can omit this mount if you specify --version as part of the command. 61 | - name: usr-bin 62 | mountPath: /usr/local/mount-from-host/bin 63 | readOnly: true 64 | - name: etc-cni-netd 65 | mountPath: /etc/cni/net.d/ 66 | readOnly: true 67 | - name: opt-cni-bin 68 | mountPath: /opt/cni/bin/ 69 | readOnly: true 70 | - name: etc-passwd 71 | mountPath: /etc/passwd 72 | readOnly: true 73 | - name: etc-group 74 | mountPath: /etc/group 75 | readOnly: true 76 | restartPolicy: Never 77 | volumes: 78 | - name: var-lib-cni 79 | hostPath: 80 | path: "/var/lib/cni" 81 | - name: var-lib-etcd 82 | hostPath: 83 | path: "/var/lib/etcd" 84 | - name: var-lib-kubelet 85 | hostPath: 86 | path: "/var/lib/kubelet" 87 | - name: var-lib-kube-scheduler 88 | hostPath: 89 | path: "/var/lib/kube-scheduler" 90 | - name: var-lib-kube-controller-manager 91 | hostPath: 92 | path: "/var/lib/kube-controller-manager" 93 | - name: etc-systemd 94 | hostPath: 95 | path: "/etc/systemd" 96 | - name: lib-systemd 97 | hostPath: 98 | path: "/lib/systemd" 99 | - name: srv-kubernetes 100 | hostPath: 101 | path: "/srv/kubernetes" 102 | - name: etc-kubernetes 103 | hostPath: 104 | path: "/etc/kubernetes" 105 | - name: usr-bin 106 | hostPath: 107 | path: "/usr/bin" 108 | - name: etc-cni-netd 109 | hostPath: 110 | path: "/etc/cni/net.d/" 111 | - name: opt-cni-bin 112 | hostPath: 113 | path: "/opt/cni/bin/" 114 | - name: etc-passwd 115 | hostPath: 116 | path: "/etc/passwd" 117 | - name: etc-group 118 | hostPath: 119 | path: "/etc/group" 120 | -------------------------------------------------------------------------------- /job-node.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench-node 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: ["kube-bench", "run", "--targets", "node"] 14 | volumeMounts: 15 | - name: var-lib-cni 16 | mountPath: /var/lib/cni 17 | readOnly: true 18 | - name: var-lib-etcd 19 | mountPath: /var/lib/etcd 20 | readOnly: true 21 | - name: var-lib-kubelet 22 | mountPath: /var/lib/kubelet 23 | readOnly: true 24 | - name: var-lib-kube-scheduler 25 | mountPath: /var/lib/kube-scheduler 26 | readOnly: true 27 | - name: var-lib-kube-controller-manager 28 | mountPath: /var/lib/kube-controller-manager 29 | readOnly: true 30 | - name: etc-systemd 31 | mountPath: /etc/systemd 32 | readOnly: true 33 | - name: lib-systemd 34 | mountPath: /lib/systemd/ 35 | readOnly: true 36 | - name: srv-kubernetes 37 | mountPath: /srv/kubernetes/ 38 | readOnly: true 39 | - name: etc-kubernetes 40 | mountPath: /etc/kubernetes 41 | readOnly: true 42 | # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version. 43 | # You can omit this mount if you specify --version as part of the command. 44 | - name: usr-bin 45 | mountPath: /usr/local/mount-from-host/bin 46 | readOnly: true 47 | - name: etc-cni-netd 48 | mountPath: /etc/cni/net.d/ 49 | readOnly: true 50 | - name: opt-cni-bin 51 | mountPath: /opt/cni/bin/ 52 | readOnly: true 53 | restartPolicy: Never 54 | volumes: 55 | - name: var-lib-cni 56 | hostPath: 57 | path: "/var/lib/cni" 58 | - name: var-lib-etcd 59 | hostPath: 60 | path: "/var/lib/etcd" 61 | - name: var-lib-kubelet 62 | hostPath: 63 | path: "/var/lib/kubelet" 64 | - name: var-lib-kube-scheduler 65 | hostPath: 66 | path: "/var/lib/kube-scheduler" 67 | - name: var-lib-kube-controller-manager 68 | hostPath: 69 | path: "/var/lib/kube-controller-manager" 70 | - name: etc-systemd 71 | hostPath: 72 | path: "/etc/systemd" 73 | - name: lib-systemd 74 | hostPath: 75 | path: "/lib/systemd" 76 | - name: srv-kubernetes 77 | hostPath: 78 | path: "/srv/kubernetes" 79 | - name: etc-kubernetes 80 | hostPath: 81 | path: "/etc/kubernetes" 82 | - name: usr-bin 83 | hostPath: 84 | path: "/usr/bin" 85 | - name: etc-cni-netd 86 | hostPath: 87 | path: "/etc/cni/net.d/" 88 | - name: opt-cni-bin 89 | hostPath: 90 | path: "/opt/cni/bin/" 91 | -------------------------------------------------------------------------------- /job-tkgi.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | spec: 9 | hostPID: true 10 | containers: 11 | - name: kube-bench 12 | image: docker.io/aquasec/kube-bench:latest 13 | command: 14 | [ 15 | "kube-bench", 16 | "run", 17 | "--targets", 18 | "node,policies", 19 | "--benchmark", 20 | "tkgi-1.2.53", 21 | ] 22 | volumeMounts: 23 | - name: var-vcap-jobs 24 | mountPath: /var/vcap/jobs 25 | readOnly: true 26 | - name: var-vcap-data-jobs 27 | mountPath: /var/vcap/data/jobs 28 | readOnly: true 29 | - name: var-vcap-packages 30 | mountPath: /var/vcap/packages 31 | readOnly: true 32 | - name: var-vcap-store-etcd 33 | mountPath: /var/vcap/store/etcd 34 | readOnly: true 35 | - name: var-vcap-sys 36 | mountPath: /var/vcap/sys 37 | readOnly: true 38 | - name: var-vcap-data-sys 39 | mountPath: /var/vcap/data/sys 40 | readOnly: true 41 | - name: etc-kubernetes 42 | mountPath: /etc/kubernetes 43 | readOnly: true 44 | restartPolicy: Never 45 | volumes: 46 | - name: var-vcap-jobs 47 | hostPath: 48 | path: "/var/vcap/jobs" 49 | - name: var-vcap-data-jobs 50 | hostPath: 51 | path: "/var/vcap/data/jobs" 52 | - name: var-vcap-packages 53 | hostPath: 54 | path: "/var/vcap/packages" 55 | - name: var-vcap-store-etcd 56 | hostPath: 57 | path: "/var/vcap/store/etcd" 58 | - name: var-vcap-sys 59 | hostPath: 60 | path: "/var/vcap/sys" 61 | - name: var-vcap-data-sys 62 | hostPath: 63 | path: "/var/vcap/data/sys" 64 | - name: etc-kubernetes 65 | hostPath: 66 | path: "/etc/kubernetes" 67 | -------------------------------------------------------------------------------- /job.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: kube-bench 6 | spec: 7 | template: 8 | metadata: 9 | labels: 10 | app: kube-bench 11 | spec: 12 | containers: 13 | - command: ["kube-bench"] 14 | image: docker.io/aquasec/kube-bench:v0.10.6 15 | name: kube-bench 16 | volumeMounts: 17 | - name: var-lib-cni 18 | mountPath: /var/lib/cni 19 | readOnly: true 20 | - mountPath: /var/lib/etcd 21 | name: var-lib-etcd 22 | readOnly: true 23 | - mountPath: /var/lib/kubelet 24 | name: var-lib-kubelet 25 | readOnly: true 26 | - mountPath: /var/lib/kube-scheduler 27 | name: var-lib-kube-scheduler 28 | readOnly: true 29 | - mountPath: /var/lib/kube-controller-manager 30 | name: var-lib-kube-controller-manager 31 | readOnly: true 32 | - mountPath: /etc/systemd 33 | name: etc-systemd 34 | readOnly: true 35 | - mountPath: /lib/systemd/ 36 | name: lib-systemd 37 | readOnly: true 38 | - mountPath: /srv/kubernetes/ 39 | name: srv-kubernetes 40 | readOnly: true 41 | - mountPath: /etc/kubernetes 42 | name: etc-kubernetes 43 | readOnly: true 44 | - mountPath: /usr/local/mount-from-host/bin 45 | name: usr-bin 46 | readOnly: true 47 | - mountPath: /etc/cni/net.d/ 48 | name: etc-cni-netd 49 | readOnly: true 50 | - mountPath: /opt/cni/bin/ 51 | name: opt-cni-bin 52 | readOnly: true 53 | hostPID: true 54 | restartPolicy: Never 55 | volumes: 56 | - name: var-lib-cni 57 | hostPath: 58 | path: /var/lib/cni 59 | - hostPath: 60 | path: /var/lib/etcd 61 | name: var-lib-etcd 62 | - hostPath: 63 | path: /var/lib/kubelet 64 | name: var-lib-kubelet 65 | - hostPath: 66 | path: /var/lib/kube-scheduler 67 | name: var-lib-kube-scheduler 68 | - hostPath: 69 | path: /var/lib/kube-controller-manager 70 | name: var-lib-kube-controller-manager 71 | - hostPath: 72 | path: /etc/systemd 73 | name: etc-systemd 74 | - hostPath: 75 | path: /lib/systemd 76 | name: lib-systemd 77 | - hostPath: 78 | path: /srv/kubernetes 79 | name: srv-kubernetes 80 | - hostPath: 81 | path: /etc/kubernetes 82 | name: etc-kubernetes 83 | - hostPath: 84 | path: /usr/bin 85 | name: usr-bin 86 | - hostPath: 87 | path: /etc/cni/net.d/ 88 | name: etc-cni-netd 89 | - hostPath: 90 | path: /opt/cni/bin/ 91 | name: opt-cni-bin 92 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2017 Aqua Security Software Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "github.com/aquasecurity/kube-bench/cmd" 19 | ) 20 | 21 | func main() { 22 | cmd.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | SOURCES := $(shell find . -name '*.go') 2 | BINARY := kube-bench 3 | DOCKER_ORG ?= aquasec 4 | VERSION ?= $(shell git rev-parse --short=7 HEAD) 5 | KUBEBENCH_VERSION ?= $(shell git describe --tags --abbrev=0) 6 | IMAGE_NAME ?= $(DOCKER_ORG)/$(BINARY):$(VERSION) 7 | IMAGE_NAME_UBI ?= $(DOCKER_ORG)/$(BINARY):$(VERSION)-ubi 8 | GOOS ?= linux 9 | BUILD_OS := linux 10 | uname := $(shell uname -s) 11 | BUILDX_PLATFORM ?= linux/amd64,linux/arm64,linux/arm,linux/ppc64le,linux/s390x 12 | DOCKER_ORGS ?= aquasec public.ecr.aws/aquasecurity 13 | GOARCH ?= $@ 14 | KUBECTL_VERSION ?= 1.33.0 15 | ARCH ?= $(shell go env GOARCH) 16 | 17 | ifneq ($(findstring Microsoft,$(shell uname -r)),) 18 | BUILD_OS := windows 19 | else ifeq ($(uname),Linux) 20 | BUILD_OS := linux 21 | else ifeq ($(uname),Darwin) 22 | BUILD_OS := darwin 23 | endif 24 | 25 | # kind cluster name to use 26 | KIND_PROFILE ?= kube-bench 27 | KIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane 28 | KIND_IMAGE ?= kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6 29 | 30 | # build a multi-arch image and push to Docker hub 31 | .PHONY: docker 32 | docker: 33 | set -xe; \ 34 | for org in $(DOCKER_ORGS); do \ 35 | docker buildx build --tag $${org}/kube-bench:${VERSION} \ 36 | --platform $(BUILDX_PLATFORM) --push . ; \ 37 | done 38 | 39 | build: $(BINARY) 40 | 41 | $(BINARY): $(SOURCES) 42 | GOOS=$(GOOS) CGO_ENABLED=0 go build -ldflags "-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion=$(KUBEBENCH_VERSION)" -o $(BINARY) . 43 | 44 | build-fips: 45 | GOOS=$(GOOS) CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -tags fipsonly -ldflags "-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion=$(KUBEBENCH_VERSION)" -o $(BINARY) . 46 | 47 | # builds the current dev docker version 48 | build-docker: 49 | docker build --build-arg BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") \ 50 | --build-arg VCS_REF=$(VERSION) \ 51 | --build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \ 52 | --build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \ 53 | --build-arg TARGETARCH=$(ARCH) \ 54 | -t $(IMAGE_NAME) . 55 | 56 | build-docker-ubi: 57 | docker build -f Dockerfile.ubi --build-arg BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") \ 58 | --build-arg VCS_REF=$(VERSION) \ 59 | --build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \ 60 | --build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \ 61 | --build-arg TARGETARCH=$(ARCH) \ 62 | -t $(IMAGE_NAME_UBI) . 63 | 64 | # unit tests 65 | tests: 66 | GO111MODULE=on go test -vet all -short -race -timeout 30s -coverprofile=coverage.txt -covermode=atomic ./... 67 | 68 | integration-test: kind-test-cluster kind-run 69 | 70 | # creates a kind cluster to be used for development. 71 | HAS_KIND := $(shell command -v kind;) 72 | kind-test-cluster: 73 | ifndef HAS_KIND 74 | go get -u sigs.k8s.io/kind 75 | endif 76 | @if [ -z $$(kind get clusters | grep $(KIND_PROFILE)) ]; then\ 77 | echo "Could not find $(KIND_PROFILE) cluster. Creating...";\ 78 | kind create cluster --name $(KIND_PROFILE) --image $(KIND_IMAGE) --wait 5m;\ 79 | fi 80 | 81 | # pushes the current dev version to the kind cluster. 82 | kind-push: build-docker 83 | kind load docker-image $(IMAGE_NAME) --name $(KIND_PROFILE) 84 | 85 | # runs the current version on kind using a job and follow logs 86 | kind-run: KUBECONFIG = "./kubeconfig.kube-bench" 87 | kind-run: kind-push 88 | sed "s/\$${VERSION}/$(VERSION)/" ./hack/kind.yaml > ./hack/kind.test.yaml 89 | kind get kubeconfig --name="$(KIND_PROFILE)" > $(KUBECONFIG) 90 | -KUBECONFIG=$(KUBECONFIG) \ 91 | kubectl delete job kube-bench 92 | KUBECONFIG=$(KUBECONFIG) \ 93 | kubectl apply -f ./hack/kind.test.yaml && \ 94 | kubectl wait --for=condition=complete job.batch/kube-bench --timeout=60s && \ 95 | kubectl logs job/kube-bench > ./test.data && \ 96 | diff ./test.data integration/testdata/Expected_output.data 97 | 98 | kind-run-stig: KUBECONFIG = "./kubeconfig.kube-bench" 99 | kind-run-stig: kind-push 100 | sed "s/\$${VERSION}/$(VERSION)/" ./hack/kind-stig.yaml > ./hack/kind-stig.test.yaml 101 | kind get kubeconfig --name="$(KIND_PROFILE)" > $(KUBECONFIG) 102 | -KUBECONFIG=$(KUBECONFIG) \ 103 | kubectl delete job kube-bench 104 | KUBECONFIG=$(KUBECONFIG) \ 105 | kubectl apply -f ./hack/kind-stig.test.yaml && \ 106 | kubectl wait --for=condition=complete job.batch/kube-bench --timeout=60s && \ 107 | kubectl logs job/kube-bench > ./test.data && \ 108 | diff ./test.data integration/testdata/Expected_output_stig.data 109 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | site_name: Kube-bench 3 | site_url: https://aquasecurity.github.io/kube-bench/ 4 | site_description: Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark 5 | docs_dir: docs/ 6 | repo_name: GitHub 7 | repo_url: https://github.com/aquasecurity/kube-bench/ 8 | edit_uri: "" 9 | 10 | nav: 11 | - Overview: index.md 12 | - Getting Started: 13 | - Installation: installation.md 14 | - Platforms: platforms.md 15 | - How to run: running.md 16 | - ASFF: asff.md 17 | - Flags: flags-and-commands.md 18 | - Configuration Options: 19 | - Understanding the yamls: controls.md 20 | - Architecture: architecture.md 21 | - Contributing: CONTRIBUTING.md 22 | 23 | markdown_extensions: 24 | - pymdownx.highlight 25 | - pymdownx.superfences 26 | - admonition 27 | 28 | extra: 29 | generator: false 30 | version: 31 | method: mike 32 | provider: mike 33 | 34 | theme: 35 | name: material 36 | language: 'en' 37 | logo: images/kube-bench-logo-only.png 38 | 39 | plugins: 40 | - search 41 | - macros 42 | --------------------------------------------------------------------------------