mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2026-02-25 15:23:57 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
366e79ddda | ||
|
|
871027447f | ||
|
|
7027b6b2ec | ||
|
|
d8fc37649a | ||
|
|
0f8dfaf115 | ||
|
|
ed51191d7c | ||
|
|
2a8615befd | ||
|
|
ff9341a5d0 | ||
|
|
65c484e85a | ||
|
|
d2d3e72271 | ||
|
|
73e1377ce0 | ||
|
|
dc8f4d37f0 | ||
|
|
dc7441620f | ||
|
|
45afbd76c2 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
- name: Setup golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: latest
|
||||
version: v1.57.2
|
||||
args: --verbose
|
||||
unit:
|
||||
name: Unit tests
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Dry-run release snapshot
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: v1.7.0
|
||||
|
||||
9
.github/workflows/publish.yml
vendored
9
.github/workflows/publish.yml
vendored
@@ -9,6 +9,7 @@ env:
|
||||
ALIAS: aquasecurity
|
||||
DOCKERHUB_ALIAS: aquasec
|
||||
REP: kube-bench
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
@@ -46,7 +47,10 @@ jobs:
|
||||
images: ${{ env.REP }}
|
||||
tag-semver: |
|
||||
{{version}}
|
||||
|
||||
- name: Extract variables from makefile (kubectl)
|
||||
id: extract_vars
|
||||
run: |
|
||||
echo "KUBECTL_VERSION=$(grep -oP '^KUBECTL_VERSION\s*\?=\s*\K.*' makefile)" >> $GITHUB_ENV
|
||||
- name: Build and push - Docker/ECR
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v5
|
||||
@@ -57,6 +61,7 @@ jobs:
|
||||
push: true
|
||||
build-args: |
|
||||
KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}
|
||||
KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}
|
||||
public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}
|
||||
@@ -76,6 +81,7 @@ jobs:
|
||||
file: Dockerfile.ubi
|
||||
build-args: |
|
||||
KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}
|
||||
KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi
|
||||
public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi
|
||||
@@ -95,6 +101,7 @@ jobs:
|
||||
file: Dockerfile.fips.ubi
|
||||
build-args: |
|
||||
KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}
|
||||
KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips
|
||||
public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
second_file_path: integration/testdata/Expected_output.data
|
||||
expected_result: PASSED
|
||||
- name: Release
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: v1.7.0
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
project_name: kube-bench
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- CGO_ENABLED=0
|
||||
- KUBEBENCH_CFG=/etc/kube-bench/cfg
|
||||
builds:
|
||||
- main: main.go
|
||||
binary: kube-bench
|
||||
tags:
|
||||
- osusergo
|
||||
- netgo
|
||||
- static_build
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
@@ -19,6 +24,9 @@ builds:
|
||||
- 6
|
||||
- 7
|
||||
ldflags:
|
||||
- "-s"
|
||||
- "-w"
|
||||
- "-extldflags '-static'"
|
||||
- "-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion={{.Version}}"
|
||||
- "-X github.com/aquasecurity/kube-bench/cmd.cfgDir={{.Env.KUBEBENCH_CFG}}"
|
||||
# Archive customization
|
||||
|
||||
13
Dockerfile
13
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.22.0 AS build
|
||||
FROM golang:1.22.2 AS build
|
||||
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
|
||||
COPY makefile makefile
|
||||
COPY go.mod go.sum ./
|
||||
@@ -9,7 +9,15 @@ COPY internal/ internal/
|
||||
ARG KUBEBENCH_VERSION
|
||||
RUN make build && cp kube-bench /go/bin/kube-bench
|
||||
|
||||
FROM alpine:3.19.1 AS run
|
||||
# Add kubectl to run policies checks
|
||||
ARG KUBECTL_VERSION TARGETARCH
|
||||
RUN wget -O /usr/local/bin/kubectl "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl"
|
||||
RUN wget -O kubectl.sha256 "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256"
|
||||
# Verify kubectl sha256sum
|
||||
RUN /bin/bash -c 'echo "$(<kubectl.sha256) /usr/local/bin/kubectl" | sha256sum -c -'
|
||||
RUN chmod +x /usr/local/bin/kubectl
|
||||
|
||||
FROM alpine:3.20.0 AS run
|
||||
WORKDIR /opt/kube-bench/
|
||||
# add GNU ps for -C, -o cmd, and --no-headers support
|
||||
# https://github.com/aquasecurity/kube-bench/issues/109
|
||||
@@ -32,6 +40,7 @@ RUN apk add jq
|
||||
ENV PATH=$PATH:/usr/local/mount-from-host/bin
|
||||
|
||||
COPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench
|
||||
COPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl
|
||||
COPY entrypoint.sh .
|
||||
COPY cfg/ cfg/
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.22.0 AS build
|
||||
FROM golang:1.22.2 AS build
|
||||
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
|
||||
COPY makefile makefile
|
||||
COPY go.mod go.sum ./
|
||||
@@ -9,6 +9,14 @@ COPY internal/ internal/
|
||||
ARG KUBEBENCH_VERSION
|
||||
RUN make build-fips && cp kube-bench /go/bin/kube-bench
|
||||
|
||||
# Add kubectl to run policies checks
|
||||
ARG KUBECTL_VERSION TARGETARCH
|
||||
RUN wget -O /usr/local/bin/kubectl "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl"
|
||||
RUN wget -O kubectl.sha256 "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256"
|
||||
# Verify kubectl sha256sum
|
||||
RUN /bin/bash -c 'echo "$(<kubectl.sha256) /usr/local/bin/kubectl" | sha256sum -c -'
|
||||
RUN chmod +x /usr/local/bin/kubectl
|
||||
|
||||
|
||||
# ubi8-minimal base image for build with ubi standards
|
||||
FROM registry.access.redhat.com/ubi9/ubi-minimal as run
|
||||
@@ -31,6 +39,7 @@ ENV PATH=$PATH:/usr/local/mount-from-host/bin
|
||||
|
||||
COPY LICENSE /licenses/LICENSE
|
||||
COPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench
|
||||
COPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl
|
||||
COPY entrypoint.sh .
|
||||
COPY cfg/ cfg/
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.22.0 AS build
|
||||
FROM golang:1.22.2 AS build
|
||||
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
|
||||
COPY makefile makefile
|
||||
COPY go.mod go.sum ./
|
||||
@@ -9,6 +9,14 @@ COPY internal/ internal/
|
||||
ARG KUBEBENCH_VERSION
|
||||
RUN make build && cp kube-bench /go/bin/kube-bench
|
||||
|
||||
# Add kubectl to run policies checks
|
||||
ARG KUBECTL_VERSION TARGETARCH
|
||||
RUN wget -O /usr/local/bin/kubectl "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl"
|
||||
RUN wget -O kubectl.sha256 "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256"
|
||||
# Verify kubectl sha256sum
|
||||
RUN /bin/bash -c 'echo "$(<kubectl.sha256) /usr/local/bin/kubectl" | sha256sum -c -'
|
||||
RUN chmod +x /usr/local/bin/kubectl
|
||||
|
||||
|
||||
# ubi8-minimal base image for build with ubi standards
|
||||
FROM registry.access.redhat.com/ubi9/ubi-minimal as run
|
||||
@@ -31,6 +39,7 @@ ENV PATH=$PATH:/usr/local/mount-from-host/bin
|
||||
|
||||
COPY LICENSE /licenses/LICENSE
|
||||
COPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench
|
||||
COPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl
|
||||
COPY entrypoint.sh .
|
||||
COPY cfg/ cfg/
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
||||
2
cfg/cis-1.9/config.yaml
Normal file
2
cfg/cis-1.9/config.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
## Version-specific settings that override the values in cfg/config.yaml
|
||||
60
cfg/cis-1.9/controlplane.yaml
Normal file
60
cfg/cis-1.9/controlplane.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
controls:
|
||||
version: "cis-1.9"
|
||||
id: 3
|
||||
text: "Control Plane Configuration"
|
||||
type: "controlplane"
|
||||
groups:
|
||||
- id: 3.1
|
||||
text: "Authentication and Authorization"
|
||||
checks:
|
||||
- id: 3.1.1
|
||||
text: "Client certificate authentication should not be used for users (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Alternative mechanisms provided by Kubernetes such as the use of OIDC should be
|
||||
implemented in place of client certificates.
|
||||
scored: false
|
||||
- id: 3.1.2
|
||||
text: "Service account token authentication should not be used for users (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented
|
||||
in place of service account tokens.
|
||||
scored: false
|
||||
- id: 3.1.3
|
||||
text: "Bootstrap token authentication should not be used for users (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented
|
||||
in place of bootstrap tokens.
|
||||
scored: false
|
||||
|
||||
- id: 3.2
|
||||
text: "Logging"
|
||||
checks:
|
||||
- id: 3.2.1
|
||||
text: "Ensure that a minimal audit policy is created (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--audit-policy-file"
|
||||
set: true
|
||||
remediation: |
|
||||
Create an audit policy file for your cluster.
|
||||
scored: false
|
||||
|
||||
- id: 3.2.2
|
||||
text: "Ensure that the audit policy covers key security concerns (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Review the audit policy provided for the cluster and ensure that it covers
|
||||
at least the following areas,
|
||||
- Access to Secrets managed by the cluster. Care should be taken to only
|
||||
log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in
|
||||
order to avoid risk of logging sensitive data.
|
||||
- Modification of Pod and Deployment objects.
|
||||
- Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.
|
||||
For most requests, minimally logging at the Metadata level is recommended
|
||||
(the most basic level of logging).
|
||||
scored: false
|
||||
135
cfg/cis-1.9/etcd.yaml
Normal file
135
cfg/cis-1.9/etcd.yaml
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
controls:
|
||||
version: "cis-1.9"
|
||||
id: 2
|
||||
text: "Etcd Node Configuration"
|
||||
type: "etcd"
|
||||
groups:
|
||||
- id: 2
|
||||
text: "Etcd Node Configuration"
|
||||
checks:
|
||||
- id: 2.1
|
||||
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "--cert-file"
|
||||
env: "ETCD_CERT_FILE"
|
||||
- flag: "--key-file"
|
||||
env: "ETCD_KEY_FILE"
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure TLS encryption.
|
||||
Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml
|
||||
on the master node and set the below parameters.
|
||||
--cert-file=</path/to/ca-file>
|
||||
--key-file=</path/to/key-file>
|
||||
scored: true
|
||||
|
||||
- id: 2.2
|
||||
text: "Ensure that the --client-cert-auth argument is set to true (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
env: "ETCD_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
remediation: |
|
||||
Edit the etcd pod specification file $etcdconf on the master
|
||||
node and set the below parameter.
|
||||
--client-cert-auth="true"
|
||||
scored: true
|
||||
|
||||
- id: 2.3
|
||||
text: "Ensure that the --auto-tls argument is not set to true (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the etcd pod specification file $etcdconf on the master
|
||||
node and either remove the --auto-tls parameter or set it to false.
|
||||
--auto-tls=false
|
||||
scored: true
|
||||
|
||||
- id: 2.4
|
||||
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are
|
||||
set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "--peer-cert-file"
|
||||
env: "ETCD_PEER_CERT_FILE"
|
||||
- flag: "--peer-key-file"
|
||||
env: "ETCD_PEER_KEY_FILE"
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure peer TLS encryption as appropriate
|
||||
for your etcd cluster.
|
||||
Then, edit the etcd pod specification file $etcdconf on the
|
||||
master node and set the below parameters.
|
||||
--peer-client-file=</path/to/peer-cert-file>
|
||||
--peer-key-file=</path/to/peer-key-file>
|
||||
scored: true
|
||||
|
||||
- id: 2.5
|
||||
text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--peer-client-cert-auth"
|
||||
env: "ETCD_PEER_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
remediation: |
|
||||
Edit the etcd pod specification file $etcdconf on the master
|
||||
node and set the below parameter.
|
||||
--peer-client-cert-auth=true
|
||||
scored: true
|
||||
|
||||
- id: 2.6
|
||||
text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the etcd pod specification file $etcdconf on the master
|
||||
node and either remove the --peer-auto-tls parameter or set it to false.
|
||||
--peer-auto-tls=false
|
||||
scored: true
|
||||
|
||||
- id: 2.7
|
||||
text: "Ensure that a unique Certificate Authority is used for etcd (Manual)"
|
||||
audit: "/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--trusted-ca-file"
|
||||
env: "ETCD_TRUSTED_CA_FILE"
|
||||
remediation: |
|
||||
[Manual test]
|
||||
Follow the etcd documentation and create a dedicated certificate authority setup for the
|
||||
etcd service.
|
||||
Then, edit the etcd pod specification file $etcdconf on the
|
||||
master node and set the below parameter.
|
||||
--trusted-ca-file=</path/to/ca-file>
|
||||
scored: false
|
||||
919
cfg/cis-1.9/master.yaml
Normal file
919
cfg/cis-1.9/master.yaml
Normal file
@@ -0,0 +1,919 @@
|
||||
---
|
||||
controls:
|
||||
version: "cis-1.9"
|
||||
id: 1
|
||||
text: "Control Plane Security Configuration"
|
||||
type: "master"
|
||||
groups:
|
||||
- id: 1.1
|
||||
text: "Control Plane Node Configuration Files"
|
||||
checks:
|
||||
- id: 1.1.1
|
||||
text: "Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the
|
||||
control plane node.
|
||||
For example, chmod 600 $apiserverconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.2
|
||||
text: "Ensure that the API server pod specification file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chown root:root $apiserverconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.3
|
||||
text: "Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chmod 600 $controllermanagerconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.4
|
||||
text: "Ensure that the controller manager pod specification file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chown root:root $controllermanagerconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.5
|
||||
text: "Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chmod 600 $schedulerconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.6
|
||||
text: "Ensure that the scheduler pod specification file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chown root:root $schedulerconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.7
|
||||
text: "Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'"
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chmod 600 $etcdconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.8
|
||||
text: "Ensure that the etcd pod specification file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'"
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chown root:root $etcdconf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.9
|
||||
text: "Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)"
|
||||
audit: |
|
||||
ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a
|
||||
find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chmod 600 <path/to/cni/files>
|
||||
scored: false
|
||||
|
||||
- id: 1.1.10
|
||||
text: "Ensure that the Container Network Interface file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G
|
||||
find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chown root:root <path/to/cni/files>
|
||||
scored: false
|
||||
|
||||
- id: 1.1.11
|
||||
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)"
|
||||
audit: |
|
||||
DATA_DIR=''
|
||||
for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do
|
||||
if test -d "$d"; then DATA_DIR="$d"; fi
|
||||
done
|
||||
if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi
|
||||
stat -c permissions=%a "$DATA_DIR"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "700"
|
||||
remediation: |
|
||||
On the etcd server node, get the etcd data directory, passed as an argument --data-dir,
|
||||
from the command 'ps -ef | grep etcd'.
|
||||
Run the below command (based on the etcd data directory found above). For example,
|
||||
chmod 700 /var/lib/etcd
|
||||
scored: true
|
||||
|
||||
- id: 1.1.12
|
||||
text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)"
|
||||
audit: |
|
||||
DATA_DIR=''
|
||||
for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do
|
||||
if test -d "$d"; then DATA_DIR="$d"; fi
|
||||
done
|
||||
if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi
|
||||
stat -c %U:%G "$DATA_DIR"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "etcd:etcd"
|
||||
remediation: |
|
||||
On the etcd server node, get the etcd data directory, passed as an argument --data-dir,
|
||||
from the command 'ps -ef | grep etcd'.
|
||||
Run the below command (based on the etcd data directory found above).
|
||||
For example, chown etcd:etcd /var/lib/etcd
|
||||
scored: true
|
||||
|
||||
- id: 1.1.13
|
||||
text: "Ensure that the default administrative credential file permissions are set to 600 (Automated)"
|
||||
audit: |
|
||||
for adminconf in /etc/kubernetes/{admin.conf,super-admin.conf}; do if test -e $adminconf; then stat -c \"permissions=%a %n\" $adminconf; fi; done
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chmod 600 /etc/kubernetes/admin.conf
|
||||
On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.
|
||||
For example, chmod 600 /etc/kubernetes/super-admin.conf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.14
|
||||
text: "Ensure that the default administrative credential file ownership is set to root:root (Automated)"
|
||||
audit: |
|
||||
for adminconf in /tmp/{admin.conf,super-admin.conf}; do if test -e $adminconf; then stat -c "ownership=%U:%G %n" $adminconf; fi; done
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "ownership"
|
||||
compare:
|
||||
op: eq
|
||||
value: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example, chown root:root /etc/kubernetes/admin.conf
|
||||
On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.
|
||||
For example, chmod 600 /etc/kubernetes/super-admin.conf
|
||||
scored: true
|
||||
|
||||
- id: 1.1.15
|
||||
text: "Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chmod 600 $schedulerkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 1.1.16
|
||||
text: "Ensure that the scheduler.conf file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chown root:root $schedulerkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 1.1.17
|
||||
text: "Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chmod 600 $controllermanagerkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 1.1.18
|
||||
text: "Ensure that the controller-manager.conf file ownership is set to root:root (Automated)"
|
||||
audit: "/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chown root:root $controllermanagerkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 1.1.19
|
||||
text: "Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)"
|
||||
audit: "find /etc/kubernetes/pki/ | xargs stat -c %U:%G"
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "root:root"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chown -R root:root /etc/kubernetes/pki/
|
||||
scored: true
|
||||
|
||||
- id: 1.1.20
|
||||
text: "Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)"
|
||||
audit: "find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a"
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chmod -R 600 /etc/kubernetes/pki/*.crt
|
||||
scored: false
|
||||
|
||||
- id: 1.1.21
|
||||
text: "Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)"
|
||||
audit: "find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a"
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the control plane node.
|
||||
For example,
|
||||
chmod -R 600 /etc/kubernetes/pki/*.key
|
||||
scored: false
|
||||
|
||||
- id: 1.2
|
||||
text: "API Server"
|
||||
checks:
|
||||
- id: 1.2.1
|
||||
text: "Ensure that the --anonymous-auth argument is set to false (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--anonymous-auth"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the below parameter.
|
||||
--anonymous-auth=false
|
||||
scored: false
|
||||
|
||||
- id: 1.2.2
|
||||
text: "Ensure that the --token-auth-file parameter is not set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--token-auth-file"
|
||||
set: false
|
||||
remediation: |
|
||||
Follow the documentation and configure alternate mechanisms for authentication. Then,
|
||||
edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and remove the --token-auth-file=<filename> parameter.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.3
|
||||
text: "Ensure that the --DenyServiceExternalIPs is set (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--enable-admission-plugins"
|
||||
compare:
|
||||
op: have
|
||||
value: "DenyServiceExternalIPs"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and remove the `DenyServiceExternalIPs`
|
||||
from enabled admission plugins.
|
||||
scored: false
|
||||
|
||||
- id: 1.2.4
|
||||
text: "Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "--kubelet-client-certificate"
|
||||
- flag: "--kubelet-client-key"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set up the TLS connection between the
|
||||
apiserver and kubelets. Then, edit API server pod specification file
|
||||
$apiserverconf on the control plane node and set the
|
||||
kubelet client certificate and key parameters as below.
|
||||
--kubelet-client-certificate=<path/to/client-certificate-file>
|
||||
--kubelet-client-key=<path/to/client-key-file>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.5
|
||||
text: "Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--kubelet-certificate-authority"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and setup the TLS connection between
|
||||
the apiserver and kubelets. Then, edit the API server pod specification file
|
||||
$apiserverconf on the control plane node and set the
|
||||
--kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.
|
||||
--kubelet-certificate-authority=<ca-string>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.6
|
||||
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--authorization-mode"
|
||||
compare:
|
||||
op: nothave
|
||||
value: "AlwaysAllow"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.
|
||||
One such example could be as below.
|
||||
--authorization-mode=RBAC
|
||||
scored: true
|
||||
|
||||
- id: 1.2.7
|
||||
text: "Ensure that the --authorization-mode argument includes Node (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--authorization-mode"
|
||||
compare:
|
||||
op: has
|
||||
value: "Node"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --authorization-mode parameter to a value that includes Node.
|
||||
--authorization-mode=Node,RBAC
|
||||
scored: true
|
||||
|
||||
- id: 1.2.8
|
||||
text: "Ensure that the --authorization-mode argument includes RBAC (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--authorization-mode"
|
||||
compare:
|
||||
op: has
|
||||
value: "RBAC"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,
|
||||
for example `--authorization-mode=Node,RBAC`.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.9
|
||||
text: "Ensure that the admission control plugin EventRateLimit is set (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--enable-admission-plugins"
|
||||
compare:
|
||||
op: has
|
||||
value: "EventRateLimit"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set the desired limits in a configuration file.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
and set the below parameters.
|
||||
--enable-admission-plugins=...,EventRateLimit,...
|
||||
--admission-control-config-file=<path/to/configuration/file>
|
||||
scored: false
|
||||
|
||||
- id: 1.2.10
|
||||
text: "Ensure that the admission control plugin AlwaysAdmit is not set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--enable-admission-plugins"
|
||||
compare:
|
||||
op: nothave
|
||||
value: AlwaysAdmit
|
||||
- flag: "--enable-admission-plugins"
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a
|
||||
value that does not include AlwaysAdmit.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.11
|
||||
text: "Ensure that the admission control plugin AlwaysPullImages is set (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--enable-admission-plugins"
|
||||
compare:
|
||||
op: has
|
||||
value: "AlwaysPullImages"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --enable-admission-plugins parameter to include
|
||||
AlwaysPullImages.
|
||||
--enable-admission-plugins=...,AlwaysPullImages,...
|
||||
scored: false
|
||||
|
||||
- id: 1.2.12
|
||||
text: "Ensure that the admission control plugin ServiceAccount is set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--disable-admission-plugins"
|
||||
compare:
|
||||
op: nothave
|
||||
value: "ServiceAccount"
|
||||
- flag: "--disable-admission-plugins"
|
||||
set: false
|
||||
remediation: |
|
||||
Follow the documentation and create ServiceAccount objects as per your environment.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and ensure that the --disable-admission-plugins parameter is set to a
|
||||
value that does not include ServiceAccount.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.13
|
||||
text: "Ensure that the admission control plugin NamespaceLifecycle is set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--disable-admission-plugins"
|
||||
compare:
|
||||
op: nothave
|
||||
value: "NamespaceLifecycle"
|
||||
- flag: "--disable-admission-plugins"
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --disable-admission-plugins parameter to
|
||||
ensure it does not include NamespaceLifecycle.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.14
|
||||
text: "Ensure that the admission control plugin NodeRestriction is set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--enable-admission-plugins"
|
||||
compare:
|
||||
op: has
|
||||
value: "NodeRestriction"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --enable-admission-plugins parameter to a
|
||||
value that includes NodeRestriction.
|
||||
--enable-admission-plugins=...,NodeRestriction,...
|
||||
scored: true
|
||||
|
||||
- id: 1.2.15
|
||||
text: "Ensure that the --profiling argument is set to false (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--profiling"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the below parameter.
|
||||
--profiling=false
|
||||
scored: true
|
||||
|
||||
- id: 1.2.16
|
||||
text: "Ensure that the --audit-log-path argument is set (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--audit-log-path"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --audit-log-path parameter to a suitable path and
|
||||
file where you would like audit logs to be written, for example,
|
||||
--audit-log-path=/var/log/apiserver/audit.log
|
||||
scored: true
|
||||
|
||||
- id: 1.2.17
|
||||
text: "Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--audit-log-maxage"
|
||||
compare:
|
||||
op: gte
|
||||
value: 30
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --audit-log-maxage parameter to 30
|
||||
or as an appropriate number of days, for example,
|
||||
--audit-log-maxage=30
|
||||
scored: true
|
||||
|
||||
- id: 1.2.18
|
||||
text: "Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--audit-log-maxbackup"
|
||||
compare:
|
||||
op: gte
|
||||
value: 10
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate
|
||||
value. For example,
|
||||
--audit-log-maxbackup=10
|
||||
scored: true
|
||||
|
||||
- id: 1.2.19
|
||||
text: "Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--audit-log-maxsize"
|
||||
compare:
|
||||
op: gte
|
||||
value: 100
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.
|
||||
For example, to set it as 100 MB, --audit-log-maxsize=100
|
||||
scored: true
|
||||
|
||||
- id: 1.2.20
|
||||
text: "Ensure that the --request-timeout argument is set as appropriate (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
type: manual
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
and set the below parameter as appropriate and if needed.
|
||||
For example, --request-timeout=300s
|
||||
scored: false
|
||||
|
||||
- id: 1.2.21
|
||||
text: "Ensure that the --service-account-lookup argument is set to true (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--service-account-lookup"
|
||||
set: false
|
||||
- flag: "--service-account-lookup"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the below parameter.
|
||||
--service-account-lookup=true
|
||||
Alternatively, you can delete the --service-account-lookup parameter from this file so
|
||||
that the default takes effect.
|
||||
scored: true
|
||||
|
||||
- id: 1.2.22
|
||||
text: "Ensure that the --service-account-key-file argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--service-account-key-file"
|
||||
remediation: |
|
||||
Edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --service-account-key-file parameter
|
||||
to the public key file for service accounts. For example,
|
||||
--service-account-key-file=<filename>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.23
|
||||
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "--etcd-certfile"
|
||||
- flag: "--etcd-keyfile"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the etcd certificate and key file parameters.
|
||||
--etcd-certfile=<path/to/client-certificate-file>
|
||||
--etcd-keyfile=<path/to/client-key-file>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.24
|
||||
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "--tls-cert-file"
|
||||
- flag: "--tls-private-key-file"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the TLS certificate and private key file parameters.
|
||||
--tls-cert-file=<path/to/tls-certificate-file>
|
||||
--tls-private-key-file=<path/to/tls-key-file>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.25
|
||||
text: "Ensure that the --client-ca-file argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--client-ca-file"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the client certificate authority file.
|
||||
--client-ca-file=<path/to/client-ca-file>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.26
|
||||
text: "Ensure that the --etcd-cafile argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--etcd-cafile"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the etcd certificate authority file parameter.
|
||||
--etcd-cafile=<path/to/ca-file>
|
||||
scored: true
|
||||
|
||||
- id: 1.2.27
|
||||
text: "Ensure that the --encryption-provider-config argument is set as appropriate (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--encryption-provider-config"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and configure a EncryptionConfig file.
|
||||
Then, edit the API server pod specification file $apiserverconf
|
||||
on the control plane node and set the --encryption-provider-config parameter to the path of that file.
|
||||
For example, --encryption-provider-config=</path/to/EncryptionConfig/File>
|
||||
scored: false
|
||||
|
||||
- id: 1.2.28
|
||||
text: "Ensure that encryption providers are appropriately configured (Manual)"
|
||||
audit: |
|
||||
ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\([^ ]*\).*%\1%')
|
||||
if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o "[A-Za-z]*" | sed 's/^/provider=/'; fi
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "provider"
|
||||
compare:
|
||||
op: valid_elements
|
||||
value: "aescbc,kms,secretbox"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and configure a EncryptionConfig file.
|
||||
In this file, choose aescbc, kms or secretbox as the encryption provider.
|
||||
scored: false
|
||||
|
||||
- id: 1.2.29
|
||||
text: "Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)"
|
||||
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--tls-cipher-suites"
|
||||
compare:
|
||||
op: valid_elements
|
||||
value: "TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384"
|
||||
remediation: |
|
||||
Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
|
||||
on the control plane node and set the below parameter.
|
||||
--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
scored: false
|
||||
|
||||
- id: 1.3
|
||||
text: "Controller Manager"
|
||||
checks:
|
||||
- id: 1.3.1
|
||||
text: "Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--terminated-pod-gc-threshold"
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,
|
||||
for example, --terminated-pod-gc-threshold=10
|
||||
scored: false
|
||||
|
||||
- id: 1.3.2
|
||||
text: "Ensure that the --profiling argument is set to false (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--profiling"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and set the below parameter.
|
||||
--profiling=false
|
||||
scored: true
|
||||
|
||||
- id: 1.3.3
|
||||
text: "Ensure that the --use-service-account-credentials argument is set to true (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--use-service-account-credentials"
|
||||
compare:
|
||||
op: noteq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node to set the below parameter.
|
||||
--use-service-account-credentials=true
|
||||
scored: true
|
||||
|
||||
- id: 1.3.4
|
||||
text: "Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--service-account-private-key-file"
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and set the --service-account-private-key-file parameter
|
||||
to the private key file for service accounts.
|
||||
--service-account-private-key-file=<filename>
|
||||
scored: true
|
||||
|
||||
- id: 1.3.5
|
||||
text: "Ensure that the --root-ca-file argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--root-ca-file"
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.
|
||||
--root-ca-file=<path/to/file>
|
||||
scored: true
|
||||
|
||||
- id: 1.3.6
|
||||
text: "Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--feature-gates"
|
||||
compare:
|
||||
op: nothave
|
||||
value: "RotateKubeletServerCertificate=false"
|
||||
set: true
|
||||
- flag: "--feature-gates"
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.
|
||||
--feature-gates=RotateKubeletServerCertificate=true
|
||||
scored: true
|
||||
|
||||
- id: 1.3.7
|
||||
text: "Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)"
|
||||
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--bind-address"
|
||||
compare:
|
||||
op: eq
|
||||
value: "127.0.0.1"
|
||||
- flag: "--bind-address"
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the Controller Manager pod specification file $controllermanagerconf
|
||||
on the control plane node and ensure the correct value for the --bind-address parameter
|
||||
scored: true
|
||||
|
||||
- id: 1.4
|
||||
text: "Scheduler"
|
||||
checks:
|
||||
- id: 1.4.1
|
||||
text: "Ensure that the --profiling argument is set to false (Automated)"
|
||||
audit: "/bin/ps -ef | grep $schedulerbin | grep -v grep"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--profiling"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
Edit the Scheduler pod specification file $schedulerconf file
|
||||
on the control plane node and set the below parameter.
|
||||
--profiling=false
|
||||
scored: true
|
||||
|
||||
- id: 1.4.2
|
||||
text: "Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)"
|
||||
audit: "/bin/ps -ef | grep $schedulerbin | grep -v grep"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--bind-address"
|
||||
compare:
|
||||
op: eq
|
||||
value: "127.0.0.1"
|
||||
- flag: "--bind-address"
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the Scheduler pod specification file $schedulerconf
|
||||
on the control plane node and ensure the correct value for the --bind-address parameter
|
||||
scored: true
|
||||
478
cfg/cis-1.9/node.yaml
Normal file
478
cfg/cis-1.9/node.yaml
Normal file
@@ -0,0 +1,478 @@
|
||||
---
|
||||
controls:
|
||||
version: "cis-1.9"
|
||||
id: 4
|
||||
text: "Worker Node Security Configuration"
|
||||
type: "node"
|
||||
groups:
|
||||
- id: 4.1
|
||||
text: "Worker Node Configuration Files"
|
||||
checks:
|
||||
- id: 4.1.1
|
||||
text: "Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example, chmod 600 $kubeletsvc
|
||||
scored: true
|
||||
|
||||
- id: 4.1.2
|
||||
text: "Ensure that the kubelet service file ownership is set to root:root (Automated)"
|
||||
audit: '/bin/sh -c "if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \"File not found\"; fi"'
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: root:root
|
||||
- flag: "File not found"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example,
|
||||
chown root:root $kubeletsvc
|
||||
scored: true
|
||||
|
||||
- id: 4.1.3
|
||||
text: "If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)"
|
||||
audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
set: true
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example,
|
||||
chmod 600 $proxykubeconfig
|
||||
scored: false
|
||||
|
||||
- id: 4.1.4
|
||||
text: "If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)"
|
||||
audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: root:root
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example, chown root:root $proxykubeconfig
|
||||
scored: false
|
||||
|
||||
- id: 4.1.5
|
||||
text: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)"
|
||||
audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example,
|
||||
chmod 600 $kubeletkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 4.1.6
|
||||
text: "Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)"
|
||||
audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '
|
||||
tests:
|
||||
test_items:
|
||||
- flag: root:root
|
||||
remediation: |
|
||||
Run the below command (based on the file location on your system) on the each worker node.
|
||||
For example,
|
||||
chown root:root $kubeletkubeconfig
|
||||
scored: true
|
||||
|
||||
- id: 4.1.7
|
||||
text: "Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)"
|
||||
audit: |
|
||||
CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)
|
||||
if test -z $CAFILE; then CAFILE=$kubeletcafile; fi
|
||||
if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the following command to modify the file permissions of the
|
||||
--client-ca-file chmod 600 <filename>
|
||||
scored: false
|
||||
|
||||
- id: 4.1.8
|
||||
text: "Ensure that the client certificate authorities file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)
|
||||
if test -z $CAFILE; then CAFILE=$kubeletcafile; fi
|
||||
if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi
|
||||
tests:
|
||||
test_items:
|
||||
- flag: root:root
|
||||
compare:
|
||||
op: eq
|
||||
value: root:root
|
||||
remediation: |
|
||||
Run the following command to modify the ownership of the --client-ca-file.
|
||||
chown root:root <filename>
|
||||
scored: false
|
||||
|
||||
- id: 4.1.9
|
||||
text: "If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)"
|
||||
audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
compare:
|
||||
op: bitmask
|
||||
value: "600"
|
||||
remediation: |
|
||||
Run the following command (using the config file location identified in the Audit step)
|
||||
chmod 600 $kubeletconf
|
||||
scored: true
|
||||
|
||||
- id: 4.1.10
|
||||
text: "If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)"
|
||||
audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '
|
||||
tests:
|
||||
test_items:
|
||||
- flag: root:root
|
||||
remediation: |
|
||||
Run the following command (using the config file location identified in the Audit step)
|
||||
chown root:root $kubeletconf
|
||||
scored: true
|
||||
|
||||
- id: 4.2
|
||||
text: "Kubelet"
|
||||
checks:
|
||||
- id: 4.2.1
|
||||
text: "Ensure that the --anonymous-auth argument is set to false (Automated)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "--anonymous-auth"
|
||||
path: '{.authentication.anonymous.enabled}'
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to
|
||||
`false`.
|
||||
If using executable arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
`--anonymous-auth=false`
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: true
|
||||
|
||||
- id: 4.2.2
|
||||
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --authorization-mode
|
||||
path: '{.authorization.mode}'
|
||||
compare:
|
||||
op: nothave
|
||||
value: AlwaysAllow
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If
|
||||
using executable arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_AUTHZ_ARGS variable.
|
||||
--authorization-mode=Webhook
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: true
|
||||
|
||||
- id: 4.2.3
|
||||
text: "Ensure that the --client-ca-file argument is set as appropriate (Automated)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --client-ca-file
|
||||
path: '{.authentication.x509.clientCAFile}'
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to
|
||||
the location of the client CA file.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_AUTHZ_ARGS variable.
|
||||
--client-ca-file=<path/to/client-ca-file>
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: true
|
||||
|
||||
- id: 4.2.4
|
||||
text: "Verify that the --read-only-port argument is set to 0 (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--read-only-port"
|
||||
path: '{.readOnlyPort}'
|
||||
compare:
|
||||
op: eq
|
||||
value: 0
|
||||
- flag: "--read-only-port"
|
||||
path: '{.readOnlyPort}'
|
||||
set: false
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
--read-only-port=0
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.5
|
||||
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --streaming-connection-idle-timeout
|
||||
path: '{.streamingConnectionIdleTimeout}'
|
||||
compare:
|
||||
op: noteq
|
||||
value: 0
|
||||
- flag: --streaming-connection-idle-timeout
|
||||
path: '{.streamingConnectionIdleTimeout}'
|
||||
set: false
|
||||
bin_op: or
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a
|
||||
value other than 0.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
--streaming-connection-idle-timeout=5m
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.6
|
||||
text: "Ensure that the --make-iptables-util-chains argument is set to true (Automated)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --make-iptables-util-chains
|
||||
path: '{.makeIPTablesUtilChains}'
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
- flag: --make-iptables-util-chains
|
||||
path: '{.makeIPTablesUtilChains}'
|
||||
set: false
|
||||
bin_op: or
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
remove the --make-iptables-util-chains argument from the
|
||||
KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
Based on your system, restart the kubelet service. For example:
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: true
|
||||
|
||||
- id: 4.2.7
|
||||
text: "Ensure that the --hostname-override argument is not set (Manual)"
|
||||
# This is one of those properties that can only be set as a command line argument.
|
||||
# To check if the property is set as expected, we need to parse the kubelet command
|
||||
# instead reading the Kubelet Configuration file.
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --hostname-override
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the kubelet service file $kubeletsvc
|
||||
on each worker node and remove the --hostname-override argument from the
|
||||
KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.8
|
||||
text: "Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --event-qps
|
||||
path: '{.eventRecordQPS}'
|
||||
compare:
|
||||
op: gte
|
||||
value: 0
|
||||
- flag: --event-qps
|
||||
path: '{.eventRecordQPS}'
|
||||
set: false
|
||||
bin_op: or
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.9
|
||||
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --tls-cert-file
|
||||
path: '{.tlsCertFile}'
|
||||
- flag: --tls-private-key-file
|
||||
path: '{.tlsPrivateKeyFile}'
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `tlsCertFile` to the location
|
||||
of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`
|
||||
to the location of the corresponding private key file.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the below parameters in KUBELET_CERTIFICATE_ARGS variable.
|
||||
--tls-cert-file=<path/to/tls-certificate-file>
|
||||
--tls-private-key-file=<path/to/tls-key-file>
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.10
|
||||
text: "Ensure that the --rotate-certificates argument is not set to false (Automated)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --rotate-certificates
|
||||
path: '{.rotateCertificates}'
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
- flag: --rotate-certificates
|
||||
path: '{.rotateCertificates}'
|
||||
set: false
|
||||
bin_op: or
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or
|
||||
remove it altogether to use the default value.
|
||||
If using command line arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS
|
||||
variable.
|
||||
Based on your system, restart the kubelet service. For example,
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: true
|
||||
|
||||
- id: 4.2.11
|
||||
text: "Verify that the RotateKubeletServerCertificate argument is set to true (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: RotateKubeletServerCertificate
|
||||
path: '{.featureGates.RotateKubeletServerCertificate}'
|
||||
compare:
|
||||
op: nothave
|
||||
value: false
|
||||
- flag: RotateKubeletServerCertificate
|
||||
path: '{.featureGates.RotateKubeletServerCertificate}'
|
||||
set: false
|
||||
remediation: |
|
||||
Edit the kubelet service file $kubeletsvc
|
||||
on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.
|
||||
--feature-gates=RotateKubeletServerCertificate=true
|
||||
Based on your system, restart the kubelet service. For example:
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.12
|
||||
text: "Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --tls-cipher-suites
|
||||
path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'
|
||||
compare:
|
||||
op: valid_elements
|
||||
value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
remediation: |
|
||||
If using a Kubelet config file, edit the file to set `TLSCipherSuites` to
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
or to a subset of these values.
|
||||
If using executable arguments, edit the kubelet service file
|
||||
$kubeletsvc on each worker node and
|
||||
set the --tls-cipher-suites parameter as follows, or to a subset of these values.
|
||||
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
Based on your system, restart the kubelet service. For example:
|
||||
systemctl daemon-reload
|
||||
systemctl restart kubelet.service
|
||||
scored: false
|
||||
|
||||
- id: 4.2.13
|
||||
text: "Ensure that a limit is set on pod PIDs (Manual)"
|
||||
audit: "/bin/ps -fC $kubeletbin"
|
||||
audit_config: "/bin/cat $kubeletconf"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: --pod-max-pids
|
||||
path: '{.podPidsLimit}'
|
||||
remediation: |
|
||||
Decide on an appropriate level for this parameter and set it,
|
||||
either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.
|
||||
scored: false
|
||||
|
||||
- id: 4.3
|
||||
text: "kube-proxy"
|
||||
checks:
|
||||
- id: 4.3.1
|
||||
text: "Ensure that the kube-proxy metrics service is bound to localhost (Automated)"
|
||||
audit: "/bin/ps -fC $proxybin"
|
||||
audit_config: "/bin/sh -c 'if test -e $proxykubeconfig; then cat $proxykubeconfig; fi'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--metrics-bind-address"
|
||||
path: '{.metricsBindAddress}'
|
||||
compare:
|
||||
op: has
|
||||
value: "127.0.0.1"
|
||||
- flag: "--metrics-bind-address"
|
||||
path: '{.metricsBindAddress}'
|
||||
set: false
|
||||
remediation: |
|
||||
Modify or remove any values which bind the metrics service to a non-localhost address.
|
||||
The default value is 127.0.0.1:10249.
|
||||
scored: true
|
||||
372
cfg/cis-1.9/policies.yaml
Normal file
372
cfg/cis-1.9/policies.yaml
Normal file
@@ -0,0 +1,372 @@
|
||||
---
|
||||
controls:
|
||||
version: "cis-1.9"
|
||||
id: 5
|
||||
text: "Kubernetes Policies"
|
||||
type: "policies"
|
||||
groups:
|
||||
- id: 5.1
|
||||
text: "RBAC and Service Accounts"
|
||||
checks:
|
||||
- id: 5.1.1
|
||||
text: "Ensure that the cluster-admin role is only used where required (Automated)"
|
||||
audit: |
|
||||
kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name --no-headers | while read -r role_name role_binding subject
|
||||
do
|
||||
if [[ "${role_name}" != "cluster-admin" && "${role_binding}" == "cluster-admin" ]]; then
|
||||
is_compliant="false"
|
||||
else
|
||||
is_compliant="true"
|
||||
fi;
|
||||
echo "**role_name: ${role_name} role_binding: ${rolebinding} subject: ${subject} is_compliant: ${is_compliant}"
|
||||
done
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "is_compliant"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
remediation: |
|
||||
Identify all clusterrolebindings to the cluster-admin role. Check if they are used and
|
||||
if they need this role or if they could use a role with fewer privileges.
|
||||
Where possible, first bind users to a lower privileged role and then remove the
|
||||
clusterrolebinding to the cluster-admin role : kubectl delete clusterrolebinding [name]
|
||||
Condition: is_compliant is false if rolename is not cluster-admin and rolebinding is cluster-admin.
|
||||
scored: true
|
||||
- id: 5.1.2
|
||||
text: "Minimize access to secrets (Automated)"
|
||||
audit: "echo \"canGetListWatchSecretsAsSystemAuthenticated: $(kubectl auth can-i get,list,watch secrets --all-namespaces --as=system:authenticated)\""
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "canGetListWatchSecretsAsSystemAuthenticated"
|
||||
compare:
|
||||
op: eq
|
||||
value: no
|
||||
remediation: |
|
||||
Where possible, remove get, list and watch access to Secret objects in the cluster.
|
||||
scored: true
|
||||
- id: 5.1.3
|
||||
text: "Minimize wildcard use in Roles and ClusterRoles (Automated)"
|
||||
audit: |
|
||||
# Check Roles
|
||||
kubectl get roles --all-namespaces -o custom-columns=ROLE_NAMESPACE:.metadata.namespace,ROLE_NAME:.metadata.name --no-headers | while read -r role_namespace role_name
|
||||
do
|
||||
role_rules=$(kubectl get role -n "${role_namespace}" "${role_name}" -o=json | jq -c '.rules')
|
||||
if echo "${role_rules}" | grep -q "\[\"\*\"\]"; then
|
||||
role_is_compliant="false"
|
||||
else
|
||||
role_is_compliant="true"
|
||||
fi;
|
||||
echo "**role_name: ${role_name} role_namespace: ${role_namespace} role_rules: ${role_rules} role_is_compliant: ${role_is_compliant}"
|
||||
done
|
||||
|
||||
# Check ClusterRoles
|
||||
kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name
|
||||
do
|
||||
clusterrole_rules=$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')
|
||||
if echo "${clusterrole_rules}" | grep -q "\[\"\*\"\]"; then
|
||||
clusterrole_is_compliant="false"
|
||||
else
|
||||
clusterrole_is_compliant="true"
|
||||
fi;
|
||||
echo "**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}"
|
||||
done
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "role_is_compliant"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
set: true
|
||||
- flag: "clusterrole_is_compliant"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
set: true
|
||||
remediation: |
|
||||
Where possible replace any use of wildcards ["*"] in roles and clusterroles with specific
|
||||
objects or actions.
|
||||
Condition: role_is_compliant is false if ["*"] is found in rules.
|
||||
Condition: clusterrole_is_compliant is false if ["*"] is found in rules.
|
||||
scored: true
|
||||
- id: 5.1.4
|
||||
text: "Minimize access to create pods (Automated)"
|
||||
audit: |
|
||||
echo "canCreatePodsAsSystemAuthenticated: $(kubectl auth can-i create pods --all-namespaces --as=system:authenticated)"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "canCreatePodsAsSystemAuthenticated"
|
||||
compare:
|
||||
op: eq
|
||||
value: no
|
||||
remediation: |
|
||||
Where possible, remove create access to pod objects in the cluster.
|
||||
scored: true
|
||||
- id: 5.1.5
|
||||
text: "Ensure that default service accounts are not actively used. (Automated)"
|
||||
audit: |
|
||||
kubectl get serviceaccount --all-namespaces --field-selector metadata.name=default -o=json | jq -r '.items[] | " namespace: \(.metadata.namespace), kind: \(.kind), name: \(.metadata.name), automountServiceAccountToken: \(.automountServiceAccountToken | if . == null then "notset" else . end )"' | xargs -L 1
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "automountServiceAccountToken"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
set: true
|
||||
remediation: |
|
||||
Create explicit service accounts wherever a Kubernetes workload requires specific access
|
||||
to the Kubernetes API server.
|
||||
Modify the configuration of each default service account to include this value
|
||||
`automountServiceAccountToken: false`.
|
||||
scored: true
|
||||
- id: 5.1.6
|
||||
text: "Ensure that Service Account Tokens are only mounted where necessary (Automated)"
|
||||
audit: |
|
||||
kubectl get pods --all-namespaces -o custom-columns=POD_NAMESPACE:.metadata.namespace,POD_NAME:.metadata.name,POD_SERVICE_ACCOUNT:.spec.serviceAccount,POD_IS_AUTOMOUNTSERVICEACCOUNTTOKEN:.spec.automountServiceAccountToken --no-headers | while read -r pod_namespace pod_name pod_service_account pod_is_automountserviceaccounttoken
|
||||
do
|
||||
# Retrieve automountServiceAccountToken's value for ServiceAccount and Pod, set to notset if null or <none>.
|
||||
svacc_is_automountserviceaccounttoken=$(kubectl get serviceaccount -n ${pod_namespace} ${pod_service_account} -o json | jq -r '.automountServiceAccountToken' | sed -e 's/<none>/notset/g' -e 's/null/notset/g')
|
||||
pod_is_automountserviceaccounttoken=$(echo ${pod_is_automountserviceaccounttoken} | sed -e 's/<none>/notset/g' -e 's/null/notset/g')
|
||||
if [[ "${svacc_is_automountserviceaccounttoken}" == "false" && ( "${pod_is_automountserviceaccounttoken}" == "false" || "${pod_is_automountserviceaccounttoken}" == "notset" ) ]]; then
|
||||
is_compliant="true"
|
||||
elif [[ "${svacc_is_automountserviceaccounttoken}" == "true" && "${pod_is_automountserviceaccounttoken}" == "false" ]]; then
|
||||
is_compliant="true"
|
||||
else
|
||||
is_compliant="false"
|
||||
fi
|
||||
echo "**namespace: ${pod_namespace} pod_name: ${pod_name} service_account: ${pod_service_account} pod_is_automountserviceaccounttoken: ${pod_is_automountserviceaccounttoken} svacc_is_automountServiceAccountToken: ${svacc_is_automountserviceaccounttoken} is_compliant: ${is_compliant}"
|
||||
done
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "is_compliant"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
remediation: |
|
||||
Modify the definition of ServiceAccounts and Pods which do not need to mount service
|
||||
account tokens to disable it, with `automountServiceAccountToken: false`.
|
||||
If both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken, the Pod spec takes precedence.
|
||||
Condition: Pod is_compliant to true when
|
||||
- ServiceAccount is automountServiceAccountToken: false and Pod is automountServiceAccountToken: false or notset
|
||||
- ServiceAccount is automountServiceAccountToken: true notset and Pod is automountServiceAccountToken: false
|
||||
scored: true
|
||||
- id: 5.1.7
|
||||
text: "Avoid use of system:masters group (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Remove the system:masters group from all users in the cluster.
|
||||
scored: false
|
||||
- id: 5.1.8
|
||||
text: "Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove the impersonate, bind and escalate rights from subjects.
|
||||
scored: false
|
||||
- id: 5.1.9
|
||||
text: "Minimize access to create persistent volumes (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove create access to PersistentVolume objects in the cluster.
|
||||
scored: false
|
||||
- id: 5.1.10
|
||||
text: "Minimize access to the proxy sub-resource of nodes (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove access to the proxy sub-resource of node objects.
|
||||
scored: false
|
||||
- id: 5.1.11
|
||||
text: "Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.
|
||||
scored: false
|
||||
- id: 5.1.12
|
||||
text: "Minimize access to webhook configuration objects (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects
|
||||
scored: false
|
||||
- id: 5.1.13
|
||||
text: "Minimize access to the service account token creation (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Where possible, remove access to the token sub-resource of serviceaccount objects.
|
||||
scored: false
|
||||
- id: 5.2
|
||||
text: "Pod Security Standards"
|
||||
checks:
|
||||
- id: 5.2.1
|
||||
text: "Ensure that the cluster has at least one active policy control mechanism in place (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Ensure that either Pod Security Admission or an external policy control system is in place
|
||||
for every namespace which contains user workloads.
|
||||
scored: false
|
||||
- id: 5.2.2
|
||||
text: "Minimize the admission of privileged containers (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of privileged containers.
|
||||
scored: false
|
||||
- id: 5.2.3
|
||||
text: "Minimize the admission of containers wishing to share the host process ID namespace (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of `hostPID` containers.
|
||||
scored: false
|
||||
- id: 5.2.4
|
||||
text: "Minimize the admission of containers wishing to share the host IPC namespace (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of `hostIPC` containers.
|
||||
scored: false
|
||||
- id: 5.2.5
|
||||
text: "Minimize the admission of containers wishing to share the host network namespace (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of `hostNetwork` containers.
|
||||
scored: false
|
||||
- id: 5.2.6
|
||||
text: "Minimize the admission of containers with allowPrivilegeEscalation (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.
|
||||
scored: false
|
||||
- id: 5.2.7
|
||||
text: "Minimize the admission of root containers (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`
|
||||
or `MustRunAs` with the range of UIDs not including 0, is set.
|
||||
scored: false
|
||||
- id: 5.2.8
|
||||
text: "Minimize the admission of containers with the NET_RAW capability (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of containers with the `NET_RAW` capability.
|
||||
scored: false
|
||||
- id: 5.2.9
|
||||
text: "Minimize the admission of containers with added capabilities (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Ensure that `allowedCapabilities` is not present in policies for the cluster unless
|
||||
it is set to an empty array.
|
||||
scored: false
|
||||
- id: 5.2.10
|
||||
text: "Minimize the admission of containers with capabilities assigned (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Review the use of capabilites in applications running on your cluster. Where a namespace
|
||||
contains applicaions which do not require any Linux capabities to operate consider adding
|
||||
a PSP which forbids the admission of containers which do not drop all capabilities.
|
||||
scored: false
|
||||
- id: 5.2.11
|
||||
text: "Minimize the admission of Windows HostProcess containers (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.
|
||||
scored: false
|
||||
- id: 5.2.12
|
||||
text: "Minimize the admission of HostPath volumes (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of containers with `hostPath` volumes.
|
||||
scored: false
|
||||
- id: 5.2.13
|
||||
text: "Minimize the admission of containers which use HostPorts (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Add policies to each namespace in the cluster which has user workloads to restrict the
|
||||
admission of containers which use `hostPort` sections.
|
||||
scored: false
|
||||
- id: 5.3
|
||||
text: "Network Policies and CNI"
|
||||
checks:
|
||||
- id: 5.3.1
|
||||
text: "Ensure that the CNI in use supports NetworkPolicies (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
If the CNI plugin in use does not support network policies, consideration should be given to
|
||||
making use of a different plugin, or finding an alternate mechanism for restricting traffic
|
||||
in the Kubernetes cluster.
|
||||
scored: false
|
||||
- id: 5.3.2
|
||||
text: "Ensure that all Namespaces have NetworkPolicies defined (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Follow the documentation and create NetworkPolicy objects as you need them.
|
||||
scored: false
|
||||
- id: 5.4
|
||||
text: "Secrets Management"
|
||||
checks:
|
||||
- id: 5.4.1
|
||||
text: "Prefer using Secrets as files over Secrets as environment variables (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
If possible, rewrite application code to read Secrets from mounted secret files, rather than
|
||||
from environment variables.
|
||||
scored: false
|
||||
- id: 5.4.2
|
||||
text: "Consider external secret storage (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Refer to the Secrets management options offered by your cloud provider or a third-party
|
||||
secrets management solution.
|
||||
scored: false
|
||||
- id: 5.5
|
||||
text: "Extensible Admission Control"
|
||||
checks:
|
||||
- id: 5.5.1
|
||||
text: "Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and setup image provenance.
|
||||
scored: false
|
||||
- id: 5.7
|
||||
text: "General Policies"
|
||||
checks:
|
||||
- id: 5.7.1
|
||||
text: "Create administrative boundaries between resources using namespaces (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Follow the documentation and create namespaces for objects in your deployment as you need
|
||||
them.
|
||||
scored: false
|
||||
- id: 5.7.2
|
||||
text: "Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.
|
||||
An example is as below:
|
||||
securityContext:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
scored: false
|
||||
- id: 5.7.3
|
||||
text: "Apply SecurityContext to your Pods and Containers (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a
|
||||
suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker
|
||||
Containers.
|
||||
scored: false
|
||||
- id: 5.7.4
|
||||
text: "The default namespace should not be used (Manual)"
|
||||
type: "manual"
|
||||
remediation: |
|
||||
Ensure that namespaces are created to allow for appropriate segregation of Kubernetes
|
||||
resources and that all new resources are created in a specific namespace.
|
||||
scored: false
|
||||
@@ -95,6 +95,7 @@ master:
|
||||
datadirs:
|
||||
- /var/lib/etcd/default.etcd
|
||||
- /var/lib/etcd/data.etcd
|
||||
- /var/lib/rancher/k3s/server/db/etcd
|
||||
confs:
|
||||
- /etc/kubernetes/manifests/etcd.yaml
|
||||
- /etc/kubernetes/manifests/etcd.yml
|
||||
@@ -105,6 +106,7 @@ master:
|
||||
- /var/snap/microk8s/current/args/etcd
|
||||
- /usr/lib/systemd/system/etcd.service
|
||||
- /var/lib/rancher/rke2/server/db/etcd/config
|
||||
- /var/lib/rancher/k3s/server/db/etcd/config
|
||||
defaultconf: /etc/kubernetes/manifests/etcd.yaml
|
||||
defaultdatadir: /var/lib/etcd/default.etcd
|
||||
|
||||
@@ -234,6 +236,7 @@ etcd:
|
||||
datadirs:
|
||||
- /var/lib/etcd/default.etcd
|
||||
- /var/lib/etcd/data.etcd
|
||||
- /var/lib/rancher/k3s/server/db/etcd
|
||||
confs:
|
||||
- /etc/kubernetes/manifests/etcd.yaml
|
||||
- /etc/kubernetes/manifests/etcd.yml
|
||||
@@ -278,6 +281,9 @@ version_mapping:
|
||||
"1.24": "cis-1.24"
|
||||
"1.25": "cis-1.7"
|
||||
"1.26": "cis-1.8"
|
||||
"1.27": "cis-1.9"
|
||||
"1.28": "cis-1.9"
|
||||
"1.29": "cis-1.9"
|
||||
"eks-1.0.1": "eks-1.0.1"
|
||||
"eks-1.1.0": "eks-1.1.0"
|
||||
"eks-1.2.0": "eks-1.2.0"
|
||||
@@ -356,6 +362,12 @@ target_mapping:
|
||||
- "controlplane"
|
||||
- "etcd"
|
||||
- "policies"
|
||||
"cis-1.9":
|
||||
- "master"
|
||||
- "node"
|
||||
- "controlplane"
|
||||
- "etcd"
|
||||
- "policies"
|
||||
"gke-1.0":
|
||||
- "master"
|
||||
- "node"
|
||||
|
||||
@@ -24,7 +24,8 @@ master:
|
||||
etcd:
|
||||
bins:
|
||||
- containerd
|
||||
|
||||
datadirs:
|
||||
- /var/lib/rancher/k3s/server/db/etcd
|
||||
node:
|
||||
components:
|
||||
- kubelet
|
||||
|
||||
@@ -10,15 +10,13 @@ groups:
|
||||
checks:
|
||||
- id: 2.1
|
||||
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.1"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure TLS encryption.
|
||||
@@ -30,14 +28,13 @@ groups:
|
||||
|
||||
- id: 2.2
|
||||
text: "Ensure that the --client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.2"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -50,15 +47,13 @@ groups:
|
||||
|
||||
- id: 2.3
|
||||
text: "Ensure that the --auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.3"
|
||||
audit: "if grep -q '^auto-tls' $etcdconf;then grep '^auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -70,15 +65,13 @@ groups:
|
||||
|
||||
- id: 2.4
|
||||
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.4"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_PEER_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_PEER_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure peer TLS encryption as appropriate
|
||||
@@ -91,14 +84,13 @@ groups:
|
||||
|
||||
- id: 2.5
|
||||
text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.5"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_PEER_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -111,15 +103,13 @@ groups:
|
||||
|
||||
- id: 2.6
|
||||
text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.6"
|
||||
audit: "if grep -q '^peer-auto-tls' $etcdconf;then grep '^peer-auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -132,11 +122,10 @@ groups:
|
||||
|
||||
- id: 2.7
|
||||
text: "Ensure that a unique Certificate Authority is used for etcd (Manual)"
|
||||
audit: "check_for_k3s_etcd.sh 2.7"
|
||||
audit: "if grep -q 'trusted-ca-file' $etcdconf;then grep 'trusted-ca-file' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "trusted-ca-file"
|
||||
env: "ETCD_TRUSTED_CA_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
[Manual test]
|
||||
|
||||
@@ -155,7 +155,7 @@ groups:
|
||||
|
||||
- id: 1.1.11
|
||||
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.1.11"
|
||||
audit: "stat -c %a $etcddatadir"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "700"
|
||||
@@ -736,7 +736,7 @@ groups:
|
||||
|
||||
- id: 1.2.26
|
||||
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.2.29"
|
||||
audit: "journalctl -D /var/log/journal -u k3s | grep -m1 'Running kube-apiserver'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
|
||||
@@ -24,6 +24,8 @@ master:
|
||||
etcd:
|
||||
bins:
|
||||
- containerd
|
||||
datadirs:
|
||||
- /var/lib/rancher/k3s/server/db/etcd
|
||||
|
||||
node:
|
||||
components:
|
||||
|
||||
@@ -10,15 +10,13 @@ groups:
|
||||
checks:
|
||||
- id: 2.1
|
||||
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.1"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure TLS encryption.
|
||||
@@ -30,14 +28,13 @@ groups:
|
||||
|
||||
- id: 2.2
|
||||
text: "Ensure that the --client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.2"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -50,15 +47,13 @@ groups:
|
||||
|
||||
- id: 2.3
|
||||
text: "Ensure that the --auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.3"
|
||||
audit: "if grep -q '^auto-tls' $etcdconf;then grep '^auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -70,15 +65,13 @@ groups:
|
||||
|
||||
- id: 2.4
|
||||
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.4"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_PEER_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_PEER_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure peer TLS encryption as appropriate
|
||||
@@ -91,14 +84,13 @@ groups:
|
||||
|
||||
- id: 2.5
|
||||
text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.5"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_PEER_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -111,15 +103,13 @@ groups:
|
||||
|
||||
- id: 2.6
|
||||
text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.6"
|
||||
audit: "if grep -q '^peer-auto-tls' $etcdconf;then grep '^peer-auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -132,11 +122,10 @@ groups:
|
||||
|
||||
- id: 2.7
|
||||
text: "Ensure that a unique Certificate Authority is used for etcd (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.7"
|
||||
audit: "if grep -q 'trusted-ca-file' $etcdconf;then grep 'trusted-ca-file' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "trusted-ca-file"
|
||||
env: "ETCD_TRUSTED_CA_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
[Manual test]
|
||||
|
||||
@@ -155,7 +155,7 @@ groups:
|
||||
|
||||
- id: 1.1.11
|
||||
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.1.11"
|
||||
audit: "stat -c %a $etcddatadir"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "700"
|
||||
@@ -735,7 +735,7 @@ groups:
|
||||
|
||||
- id: 1.2.26
|
||||
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.2.29"
|
||||
audit: "journalctl -D /var/log/journal -u k3s | grep -m1 'Running kube-apiserver'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
|
||||
@@ -31,7 +31,8 @@ master:
|
||||
etcd:
|
||||
bins:
|
||||
- containerd
|
||||
|
||||
datadirs:
|
||||
- /var/lib/rancher/k3s/server/db/etcd
|
||||
node:
|
||||
components:
|
||||
- kubelet
|
||||
|
||||
@@ -10,15 +10,13 @@ groups:
|
||||
checks:
|
||||
- id: 2.1
|
||||
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.1"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure TLS encryption.
|
||||
@@ -30,14 +28,13 @@ groups:
|
||||
|
||||
- id: 2.2
|
||||
text: "Ensure that the --client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.2"
|
||||
audit: "grep -A 4 'client-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -50,15 +47,13 @@ groups:
|
||||
|
||||
- id: 2.3
|
||||
text: "Ensure that the --auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.3"
|
||||
audit: "if grep -q '^auto-tls' $etcdconf;then grep '^auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--auto-tls"
|
||||
env: "ETCD_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -70,15 +65,13 @@ groups:
|
||||
|
||||
- id: 2.4
|
||||
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.4"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file'"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
- flag: "cert-file"
|
||||
env: "ETCD_PEER_CERT_FILE"
|
||||
set: true
|
||||
- flag: "key-file"
|
||||
env: "ETCD_PEER_KEY_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
Follow the etcd service documentation and configure peer TLS encryption as appropriate
|
||||
@@ -91,14 +84,13 @@ groups:
|
||||
|
||||
- id: 2.5
|
||||
text: "Ensure that the --peer-client-cert-auth argument is set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.5"
|
||||
audit: "grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth'"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--client-cert-auth"
|
||||
set: true
|
||||
- flag: "client-cert-auth"
|
||||
env: "ETCD_PEER_CLIENT_CERT_AUTH"
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
@@ -111,15 +103,13 @@ groups:
|
||||
|
||||
- id: 2.6
|
||||
text: "Ensure that the --peer-auto-tls argument is not set to true (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.6"
|
||||
audit: "if grep -q '^peer-auto-tls' $etcdconf;then grep '^peer-auto-tls' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
set: false
|
||||
- flag: "--peer-auto-tls"
|
||||
env: "ETCD_PEER_AUTO_TLS"
|
||||
compare:
|
||||
op: eq
|
||||
value: false
|
||||
@@ -132,11 +122,10 @@ groups:
|
||||
|
||||
- id: 2.7
|
||||
text: "Ensure that a unique Certificate Authority is used for etcd (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 2.7"
|
||||
audit: "if grep -q 'trusted-ca-file' $etcdconf;then grep 'trusted-ca-file' $etcdconf;else echo 'notset';fi"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "trusted-ca-file"
|
||||
env: "ETCD_TRUSTED_CA_FILE"
|
||||
set: true
|
||||
remediation: |
|
||||
[Manual test]
|
||||
|
||||
@@ -167,7 +167,7 @@ groups:
|
||||
|
||||
- id: 1.1.11
|
||||
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.1.11"
|
||||
audit: "stat -c %a $etcddatadir"
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "700"
|
||||
@@ -738,7 +738,7 @@ groups:
|
||||
|
||||
- id: 1.2.25
|
||||
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)"
|
||||
audit: "check_for_k3s_etcd.sh 1.2.29"
|
||||
audit: "journalctl -D /var/log/journal -u k3s | grep 'Running kube-apiserver' | tail -n1"
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
|
||||
@@ -11,16 +11,17 @@ groups:
|
||||
- id: 2.1
|
||||
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Manual)"
|
||||
audit: |
|
||||
# For --cert-file
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--cert-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# For --key-file
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--key-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--cert-file=[^ ]*\).*/\1/'
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--key-file=[^ ]*\).*/\1/'
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -36,10 +37,16 @@ groups:
|
||||
- id: 2.2
|
||||
text: "Ensure that the --client-cert-auth argument is set to true (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--client-cert-auth=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--client-cert-auth=[^ ]*\).*/\1/'
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -55,10 +62,16 @@ groups:
|
||||
text: "Ensure that the --auto-tls argument is not set to true (Manual)"
|
||||
audit: |
|
||||
# Returns 0 if found, 1 if not found
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | grep -- --auto-tls=true 2>/dev/null ; echo exit_code=$?
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | grep -- --auto-tls=true 2>/dev/null ; echo exit_code=$?
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -73,16 +86,17 @@ groups:
|
||||
- id: 2.4
|
||||
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Manual)"
|
||||
audit: |
|
||||
# For --peer-cert-file
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--peer-cert-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# For --peer-key-file
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--peer-key-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--peer-cert-file=[^ ]*\).*/\1/'
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--peer-key-file=[^ ]*\).*/\1/'
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -97,10 +111,16 @@ groups:
|
||||
- id: 2.5
|
||||
text: "Ensure that the --peer-client-cert-auth argument is set to true (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--peer-client-cert-auth=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--peer-client-cert-auth=[^ ]*\).*/\1/'
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -116,10 +136,16 @@ groups:
|
||||
text: "Ensure that the --peer-auto-tls argument is not set to true (Manual)"
|
||||
audit: |
|
||||
# Returns 0 if found, 1 if not found
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | grep -- --peer-auto-tls=true 2>/dev/null ; echo exit_code=$?
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | grep -- --peer-auto-tls=true 2>/dev/null ; echo exit_code=$?
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -134,14 +160,17 @@ groups:
|
||||
- id: 2.7
|
||||
text: "Ensure that a unique Certificate Authority is used for etcd (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--trusted-ca-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
for i in $(oc get pods -oname -n openshift-etcd)
|
||||
do
|
||||
oc exec -n openshift-etcd -c etcd $i -- ps -o command= -C etcd | sed 's/.*\(--peer-trusted-ca-file=[^ ]*\).*/\1/'
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching file found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--trusted-ca-file=[^ ]*\).*/\1/'
|
||||
oc exec -n openshift-etcd -c etcd "$POD_NAME" -- ps -o command= -C etcd | sed 's/.*\(--peer-trusted-ca-file=[^ ]*\).*/\1/'
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
|
||||
@@ -11,10 +11,18 @@ groups:
|
||||
- id: 1.1.1
|
||||
text: "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o name )
|
||||
do
|
||||
oc exec -n openshift-kube-apiserver $i -- stat -c "$i %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml;
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-apiserver namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -29,11 +37,18 @@ groups:
|
||||
- id: 1.1.2
|
||||
text: "Ensure that the API server pod specification file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o name )
|
||||
do
|
||||
oc exec -n openshift-kube-apiserver $i -- \
|
||||
stat -c "$i %n %U:%G" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-apiserver namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -45,10 +60,18 @@ groups:
|
||||
- id: 1.1.3
|
||||
text: "Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-controller-manager -o name -l app=kube-controller-manager)
|
||||
do
|
||||
oc exec -n openshift-kube-controller-manager $i -- stat -c "$i %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml;
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-controller-manager namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-controller-manager "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -63,11 +86,18 @@ groups:
|
||||
- id: 1.1.4
|
||||
text: "Ensure that the controller manager pod specification file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-controller-manager -o name -l app=kube-controller-manager)
|
||||
do
|
||||
oc exec -n openshift-kube-controller-manager $i -- \
|
||||
stat -c "$i %n %U:%G" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-controller-manager namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-controller-manager "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -79,10 +109,18 @@ groups:
|
||||
- id: 1.1.5
|
||||
text: "Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler -o name )
|
||||
do
|
||||
oc exec -n openshift-kube-scheduler $i -- stat -c "$i %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml;
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-scheduler namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-scheduler "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -97,11 +135,18 @@ groups:
|
||||
- id: 1.1.6
|
||||
text: "Ensure that the scheduler pod specification file ownership is set to root:root (Manual))"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler -o name )
|
||||
do
|
||||
oc exec -n openshift-kube-scheduler $i -- \
|
||||
stat -c "$i %n %U:%G" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-scheduler namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-scheduler "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -113,10 +158,18 @@ groups:
|
||||
- id: 1.1.7
|
||||
text: "Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Manual))"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-etcd -l app=etcd -o name | grep etcd )
|
||||
do
|
||||
oc rsh -n openshift-etcd $i stat -c "$i %n permissions=%a" /etc/kubernetes/manifests/etcd-pod.yaml
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc rsh -n openshift-etcd "$POD_NAME" stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/manifests/etcd-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -131,10 +184,18 @@ groups:
|
||||
- id: 1.1.8
|
||||
text: "Ensure that the etcd pod specification file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $( oc get pods -n openshift-etcd -l app=etcd -o name | grep etcd )
|
||||
do
|
||||
oc rsh -n openshift-etcd $i stat -c "$i %n %U:%G" /etc/kubernetes/manifests/etcd-pod.yaml
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc rsh -n openshift-etcd "$POD_NAME" stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/manifests/etcd-pod.yaml
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -146,16 +207,41 @@ groups:
|
||||
- id: 1.1.9
|
||||
text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# For CNI multus
|
||||
for i in $(oc get pods -n openshift-multus -l app=multus -oname); do oc exec -n openshift-multus $i -- /bin/bash -c "stat -c \"$i %n permissions=%a\" /host/etc/cni/net.d/*.conf"; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-multus -l app=multus -oname); do oc exec -n openshift-multus $i -- /bin/bash -c "stat -c \"$i %n permissions=%a\" /host/var/run/multus/cni/net.d/*.conf"; done 2>/dev/null
|
||||
# Get the pod name in the openshift-multus namespace
|
||||
POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-multus "$POD_NAME" -- /bin/bash -c "stat -c \"$i %n permissions=%a\" /host/etc/cni/net.d/*.conf"; 2>/dev/null
|
||||
oc exec -n openshift-multus "$POD_NAME" -- /bin/bash -c "stat -c \"$i %n permissions=%a\" /host/var/run/multus/cni/net.d/*.conf"; 2>/dev/null
|
||||
fi
|
||||
# For SDN pods
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname); do oc exec -n openshift-sdn $i -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c "$i %n permissions=%a" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname); do oc exec -n openshift-sdn $i -- find /var/run/openshift-sdn -type f -exec stat -c "$i %n permissions=%a" {} \;; done 2>/dev/null
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c "$i %n permissions=%a" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/run/openshift-sdn -type f -exec stat -c "$i %n permissions=%a" {} \; 2>/dev/null
|
||||
fi
|
||||
|
||||
# For OVS pods
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /var/run/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /etc/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /run/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \;; done 2>/dev/null
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/run/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /etc/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /run/openvswitch -type f -exec stat -c "$i %n permissions=%a" {} \; 2>/dev/null
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -170,17 +256,40 @@ groups:
|
||||
- id: 1.1.10
|
||||
text: "Ensure that the Container Network Interface file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# For CNI multus
|
||||
for i in $(oc get pods -n openshift-multus -l app=multus -oname); do oc exec -n openshift-multus $i -- /bin/bash -c "stat -c \""$i %n %U:%G\" /host/etc/cni/net.d/*.conf"; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-multus -l app=multus -oname); do oc exec -n openshift-multus $i -- /bin/bash -c "stat -c \""$i %n %U:%G\" /host/var/run/multus/cni/net.d/*.conf"; done 2>/dev/null
|
||||
# Get the pod name in the openshift-multus namespace
|
||||
POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-multus "$POD_NAME" -- /bin/bash -c "stat -c '$i %n %U:%G' /host/etc/cni/net.d/*.conf" 2>/dev/null
|
||||
oc exec -n openshift-multus $i -- /bin/bash -c "stat -c '$i %n %U:%G' /host/var/run/multus/cni/net.d/*.conf" 2>/dev/null
|
||||
fi
|
||||
# For SDN pods
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname); do oc exec -n openshift-sdn $i -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c "$i %n %U:%G" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname); do oc exec -n openshift-sdn $i -- find /var/run/openshift-sdn -type f -exec stat -c "$i %n %U:%G"{} \;; done 2>/dev/null
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c "$i %n %U:%G" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/run/openshift-sdn -type f -exec stat -c "$i %n %U:%G" {} \; 2>/dev/null
|
||||
fi
|
||||
# For OVS pods in 4.5
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /var/run/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /etc/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \;; done 2>/dev/null
|
||||
for i in $(oc get pods -n openshift-sdn -l app=ovs -oname); do oc exec -n openshift-sdn $i -- find /run/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \;; done 2>/dev/null
|
||||
# For OVS pods in 4.6 TBD
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /var/run/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /etc/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \; 2>/dev/null
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- find /run/openvswitch -type f -exec stat -c "$i %n %U:%G" {} \; 2>/dev/null
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -192,7 +301,18 @@ groups:
|
||||
- id: 1.1.11
|
||||
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-etcd -l app=etcd -oname); do oc exec -n openshift-etcd -c etcd $i -- stat -c "$i %n permissions=%a" /var/lib/etcd/member; done
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /var/lib/etcd/member
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -207,7 +327,18 @@ groups:
|
||||
- id: 1.1.12
|
||||
text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-etcd -l app=etcd -oname); do oc exec -n openshift-etcd -c etcd $i -- stat -c "$i %n %U:%G" /var/lib/etcd/member; done
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-etcd namespace
|
||||
POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-etcd "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /var/lib/etcd/member
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -219,10 +350,8 @@ groups:
|
||||
- id: 1.1.13
|
||||
text: "Ensure that the admin.conf file permissions are set to 644 or more restrictive (Manual))"
|
||||
audit: |
|
||||
for i in $(oc get nodes -o name)
|
||||
do
|
||||
oc debug $i -- chroot /host stat -c "$i %n permissions=%a" /etc/kubernetes/kubeconfig
|
||||
done 2>/dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n permissions=%a" /etc/kubernetes/kubeconfig 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -237,10 +366,8 @@ groups:
|
||||
- id: 1.1.14
|
||||
text: "Ensure that the admin.conf file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get nodes -o name)
|
||||
do
|
||||
oc debug $i -- chroot /host stat -c "$i %n %U:%G" /etc/kubernetes/kubeconfig
|
||||
done 2>/dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n %U:%G" /etc/kubernetes/kubeconfig 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -252,10 +379,18 @@ groups:
|
||||
- id: 1.1.15
|
||||
text: "Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler -o name)
|
||||
do
|
||||
oc exec -n openshift-kube-scheduler $i -- stat -c "$i %n permissions=%a" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-scheduler namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-scheduler "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -270,10 +405,18 @@ groups:
|
||||
- id: 1.1.16
|
||||
text: "Ensure that the scheduler.conf file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler -o name)
|
||||
do
|
||||
oc exec -n openshift-kube-scheduler $i -- stat -c "$i %n %U:%G" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-scheduler namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-scheduler "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -285,10 +428,18 @@ groups:
|
||||
- id: 1.1.17
|
||||
text: "Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o name)
|
||||
do
|
||||
oc exec -n openshift-kube-controller-manager $i -- stat -c "$i %n permissions=%a" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-controller-manager namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-controller-manager "$POD_NAME" -- stat -c "$POD_NAME %n permissions=%a" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -303,10 +454,18 @@ groups:
|
||||
- id: 1.1.18
|
||||
text: "Ensure that the controller-manager.conf file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o name)
|
||||
do
|
||||
oc exec -n openshift-kube-controller-manager $i -- stat -c "$i %n %U:%G" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig
|
||||
done 2>/dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-controller-manager namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-controller-manager "$POD_NAME" -- stat -c "$POD_NAME %n %U:%G" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -319,15 +478,22 @@ groups:
|
||||
text: "Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
# Should return root:root for all files and directories
|
||||
for i in $(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
# echo $i static-pod-certs
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type d -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
# echo $i static-pod-resources
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type d -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type f -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
done
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-controller-manager namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# echo $i static-pod-certs
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type d -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
# echo $i static-pod-resources
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type d -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type f -wholename '*/secrets*' -exec stat -c "$i %n %U:%G" {} \;
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -339,11 +505,18 @@ groups:
|
||||
- id: 1.1.20
|
||||
text: "Ensure that the OpenShift PKI certificate file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
# echo $i static-pod-certs
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.crt' -exec stat -c "$i %n permissions=%a" {} \;
|
||||
done
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-apiserver namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.crt' -exec stat -c "$POD_NAME %n permissions=%a" {} \;
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -358,11 +531,18 @@ groups:
|
||||
- id: 1.1.21
|
||||
text: "Ensure that the OpenShift PKI key file permissions are set to 600 (Manual)"
|
||||
audit: |
|
||||
for i in $(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
# echo $i static-pod-certs
|
||||
oc exec -n openshift-kube-apiserver $i -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.key' -exec stat -c "$i %n permissions=%a" {} \;
|
||||
done
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
|
||||
# Get the pod name in the openshift-kube-apiserver namespace
|
||||
POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-kube-apiserver "$POD_NAME" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.key' -exec stat -c "$POD_NAME %n permissions=%a" {} \;
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -532,11 +712,9 @@ groups:
|
||||
oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.apiServerArguments'
|
||||
oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'
|
||||
# For OCP 4.5 and earlier verify that authorization-mode is not used
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host cat /etc/kubernetes/kubelet.conf | grep authorization-mode
|
||||
oc debug node/${node} -- chroot /host ps -aux | grep kubelet | grep authorization-mode
|
||||
done
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host cat /etc/kubernetes/kubelet.conf | grep authorization-mode 2> /dev/null
|
||||
oc debug node/$NODE_NAME -- chroot /host ps -aux | grep kubelet | grep authorization-mode 2> /dev/null
|
||||
#Check that no overrides are configured
|
||||
oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'
|
||||
audit_config: |
|
||||
|
||||
@@ -11,11 +11,8 @@ groups:
|
||||
- id: 4.1.1
|
||||
text: "Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/systemd/system/kubelet.service
|
||||
done 2> /dev/null
|
||||
use_multiple_values: true
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n permissions=%a" /etc/systemd/system/kubelet.service 2> /dev/null
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "permissions"
|
||||
@@ -30,11 +27,8 @@ groups:
|
||||
text: "Ensure that the kubelet service file ownership is set to root:root (Automated)"
|
||||
audit: |
|
||||
# Should return root:root for each node
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/systemd/system/kubelet.service
|
||||
done 2> /dev/null
|
||||
use_multiple_values: true
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n %U:%G" /etc/systemd/system/kubelet.service 2> /dev/null
|
||||
tests:
|
||||
test_items:
|
||||
- flag: root:root
|
||||
@@ -45,11 +39,17 @@ groups:
|
||||
- id: 4.1.3
|
||||
text: "If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname)
|
||||
do
|
||||
oc exec -n openshift-sdn $i -- stat -Lc "$i %n permissions=%a" /config/kube-proxy-config.yaml
|
||||
done 2> /dev/null
|
||||
use_multiple_values: true
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-sdn namespace
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" - stat -Lc "$i %n permissions=%a" /config/kube-proxy-config.yaml 2>/dev/null
|
||||
fi
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
@@ -65,10 +65,17 @@ groups:
|
||||
- id: 4.1.4
|
||||
text: "Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for i in $(oc get pods -n openshift-sdn -l app=sdn -oname)
|
||||
do
|
||||
oc exec -n openshift-sdn $i -- stat -Lc "$i %n %U:%G" /config/kube-proxy-config.yaml
|
||||
done 2> /dev/null
|
||||
# Get the node name where the pod is running
|
||||
NODE_NAME=$(oc get pod "$HOSTNAME" -o=jsonpath='{.spec.nodeName}')
|
||||
# Get the pod name in the openshift-sdn namespace
|
||||
POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
|
||||
if [ -z "$POD_NAME" ]; then
|
||||
echo "No matching pods found on the current node."
|
||||
else
|
||||
# Execute the stat command
|
||||
oc exec -n openshift-sdn "$POD_NAME" -- stat -Lc "$i %n %U:%G" /config/kube-proxy-config.yaml 2>/dev/null
|
||||
fi
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
bin_op: or
|
||||
@@ -82,10 +89,8 @@ groups:
|
||||
text: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Manual)"
|
||||
audit: |
|
||||
# Check permissions
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/kubernetes/kubelet.conf
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n permissions=%a" /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -100,10 +105,8 @@ groups:
|
||||
- id: 4.1.6
|
||||
text: "Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/kubernetes/kubelet.conf
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n %U:%G" /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -115,10 +118,8 @@ groups:
|
||||
- id: 4.1.7
|
||||
text: "Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/kubernetes/kubelet-ca.crt
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n permissions=%a" /etc/kubernetes/kubelet-ca.crt 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -133,10 +134,8 @@ groups:
|
||||
- id: 4.1.8
|
||||
text: "Ensure that the client certificate authorities file ownership is set to root:root (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/kubernetes/kubelet-ca.crt
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n %U:%G" /etc/kubernetes/kubelet-ca.crt 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -148,10 +147,8 @@ groups:
|
||||
- id: 4.1.9
|
||||
text: "Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /var/lib/kubelet/kubeconfig
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n permissions=%a" /var/lib/kubelet/kubeconfig 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -166,10 +163,8 @@ groups:
|
||||
- id: 4.1.10
|
||||
text: "Ensure that the kubelet configuration file ownership is set to root:root (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /var/lib/kubelet/kubeconfig
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host stat -c "$NODE_NAME %n %U:%G" /var/lib/kubelet/kubeconfig 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -184,10 +179,8 @@ groups:
|
||||
- id: 4.2.1
|
||||
text: "Ensure that the --anonymous-auth argument is set to false (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host grep -B4 -A1 anonymous /etc/kubernetes/kubelet.conf
|
||||
done
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host grep -B4 -A1 anonymous /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -205,10 +198,8 @@ groups:
|
||||
audit: |
|
||||
POD=$(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')
|
||||
TOKEN=$(oc whoami -t)
|
||||
for name in $(oc get nodes -ojsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc exec -n openshift-kube-apiserver $POD -- curl -sS https://172.25.0.1/api/v1/nodes/$name/proxy/configz -k -H "Authorization:Bearer $TOKEN" | jq -r '.kubeletconfig.authorization.mode'
|
||||
done
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc exec -n openshift-kube-apiserver $POD -- curl -sS https://172.25.0.1/api/v1/nodes/$NODE_NAME/proxy/configz -k -H "Authorization:Bearer $TOKEN" | jq -r '.kubeletconfig.authorization.mode' 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
@@ -220,14 +211,12 @@ groups:
|
||||
- id: 4.2.3
|
||||
text: "Ensure that the --client-ca-file argument is set as appropriate (Automated)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host grep clientCAFile /etc/kubernetes/kubelet.conf | awk -F': ' '{ print "clientCAFile=" $2 }'
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host grep clientCAFile /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
test_items:
|
||||
- flag: clientCAFile="/etc/kubernetes/kubelet-ca.crt"
|
||||
- flag: '"clientCAFile": "/etc/kubernetes/kubelet-ca.crt"'
|
||||
remediation: |
|
||||
None required. Changing the clientCAFile value is unsupported.
|
||||
scored: true
|
||||
@@ -255,18 +244,13 @@ groups:
|
||||
- id: 4.2.5
|
||||
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)"
|
||||
audit: |
|
||||
# Should return 1 for each node
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host ps -ef | grep kubelet | grep streaming-connection-idle-timeout
|
||||
echo exit_code=$?
|
||||
done 2>/dev/null
|
||||
# Should return 1 for each node
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host grep streamingConnectionIdleTimeout /etc/kubernetes/kubelet.conf
|
||||
echo exit_code=$?
|
||||
done 2>/dev/null
|
||||
# Should return 1 for node
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/${NODE_NAME} -- chroot /host ps -ef | grep kubelet | grep streaming-connection-idle-timeout 2> /dev/null
|
||||
echo exit_code=$?
|
||||
# Should return 1 for node
|
||||
oc debug node/${NODE_NAME} -- chroot /host grep streamingConnectionIdleTimeout /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
echo exit_code=$?
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
bin_op: or
|
||||
@@ -291,10 +275,8 @@ groups:
|
||||
- id: 4.2.6
|
||||
text: "Ensure that the --protect-kernel-defaults argument is not set (Manual)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
|
||||
do
|
||||
oc debug node/${node} -- chroot /host more /etc/kubernetes/kubelet.conf;
|
||||
done
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/$NODE_NAME -- chroot /host more /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
tests:
|
||||
test_items:
|
||||
- flag: protectKernelDefaults
|
||||
@@ -349,10 +331,8 @@ groups:
|
||||
- id: 4.2.9
|
||||
text: "Ensure that the kubeAPIQPS [--event-qps] argument is set to 0 or a level which ensures appropriate event capture (Manual)"
|
||||
audit: |
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
|
||||
do
|
||||
oc debug node/${node} -- chroot /host more /etc/kubernetes/kubelet.conf;
|
||||
done
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/${NODE_NAME} -- chroot /host cat /etc/kubernetes/kubelet.conf;
|
||||
oc get machineconfig 01-worker-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050
|
||||
oc get machineconfig 01-master-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050
|
||||
type: "manual"
|
||||
@@ -365,7 +345,12 @@ groups:
|
||||
- id: 4.2.10
|
||||
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)"
|
||||
audit: |
|
||||
oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.kubeletClientInfo'
|
||||
oc get configmap config -n openshift-kube-apiserver -o json \
|
||||
| jq -r '.data["config.yaml"]' \
|
||||
| jq -r '.apiServerArguments |
|
||||
.["kubelet-client-certificate"][0],
|
||||
.["kubelet-client-key"][0]
|
||||
'
|
||||
tests:
|
||||
bin_op: and
|
||||
test_items:
|
||||
@@ -380,15 +365,10 @@ groups:
|
||||
text: "Ensure that the --rotate-certificates argument is not set to false (Manual)"
|
||||
audit: |
|
||||
#Verify the rotateKubeletClientCertificate feature gate is not set to false
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot /host cat /etc/kubernetes/kubelet.conf | grep RotateKubeletClientCertificate
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/${NODE_NAME} -- chroot /host cat /etc/kubernetes/kubelet.conf | grep RotateKubeletClientCertificate 2> /dev/null
|
||||
# Verify the rotateCertificates argument is set to true
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot host grep rotate /etc/kubernetes/kubelet.conf;
|
||||
done 2> /dev/null
|
||||
oc debug node/${NODE_NAME} -- chroot host grep rotate /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
bin_op: or
|
||||
@@ -411,24 +391,19 @@ groups:
|
||||
text: "Verify that the RotateKubeletServerCertificate argument is set to true (Manual)"
|
||||
audit: |
|
||||
#Verify the rotateKubeletServerCertificate feature gate is on
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
|
||||
do
|
||||
oc debug node/${node} -- chroot /host grep RotateKubeletServerCertificate /etc/kubernetes/kubelet.conf;
|
||||
done 2> /dev/null
|
||||
NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')
|
||||
oc debug node/${NODE_NAME} -- chroot /host grep RotateKubeletServerCertificate /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
# Verify the rotateCertificates argument is set to true
|
||||
for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
|
||||
do
|
||||
oc debug node/${node} -- chroot host grep rotate /etc/kubernetes/kubelet.conf;
|
||||
done 2> /dev/null
|
||||
oc debug node/${NODE_NAME} -- chroot host grep rotate /etc/kubernetes/kubelet.conf 2> /dev/null
|
||||
use_multiple_values: true
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
- flag: RotateKubeletServerCertificate
|
||||
- flag: rotateCertificates
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
- flag: rotateCertificates
|
||||
- flag: RotateKubeletServerCertificate
|
||||
compare:
|
||||
op: eq
|
||||
value: true
|
||||
|
||||
@@ -78,10 +78,7 @@ groups:
|
||||
text: "Minimize the admission of privileged containers (Manual)"
|
||||
audit: |
|
||||
# needs verification
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i"; oc describe scc $i | grep "Allow Privileged";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,allowPrivilegedContainer:.allowPrivilegedContainer
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "false"
|
||||
@@ -93,10 +90,7 @@ groups:
|
||||
- id: 5.2.2
|
||||
text: "Minimize the admission of containers wishing to share the host process ID namespace (Manual)"
|
||||
audit: |
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i"; oc describe scc $i | grep "Allow Host PID";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,allowHostPID:.allowHostPID
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "false"
|
||||
@@ -108,10 +102,7 @@ groups:
|
||||
- id: 5.2.3
|
||||
text: "Minimize the admission of containers wishing to share the host IPC namespace (Manual)"
|
||||
audit: |
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i"; oc describe scc $i | grep "Allow Host IPC";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,allowHostIPC:.allowHostIPC
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "false"
|
||||
@@ -123,10 +114,7 @@ groups:
|
||||
- id: 5.2.4
|
||||
text: "Minimize the admission of containers wishing to share the host network namespace (Manual)"
|
||||
audit: |
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i"; oc describe scc $i | grep "Allow Host Network";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,allowHostNetwork:.allowHostNetwork
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "false"
|
||||
@@ -138,10 +126,7 @@ groups:
|
||||
- id: 5.2.5
|
||||
text: "Minimize the admission of containers with allowPrivilegeEscalation (Manual)"
|
||||
audit: |
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i"; oc describe scc $i | grep "Allow Privilege Escalation";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,allowPrivilegeEscalation:.allowPrivilegeEscalation
|
||||
tests:
|
||||
test_items:
|
||||
- flag: "false"
|
||||
@@ -153,18 +138,10 @@ groups:
|
||||
- id: 5.2.6
|
||||
text: "Minimize the admission of root containers (Manual)"
|
||||
audit: |
|
||||
# needs verification
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i";
|
||||
oc describe scc $i | grep "Run As User Strategy";
|
||||
done
|
||||
# needs verification # | awk 'NR>1 {gsub("map\\[type:", "", $2); gsub("\\]$", "", $2); print $1 ":" $2}'
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,runAsUser:.runAsUser.type
|
||||
#For SCCs with MustRunAs verify that the range of UIDs does not include 0
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i";
|
||||
oc describe scc $i | grep "\sUID";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,uidRangeMin:.runAsUser.uidRangeMin,uidRangeMax:.runAsUser.uidRangeMax
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
@@ -183,11 +160,7 @@ groups:
|
||||
text: "Minimize the admission of containers with the NET_RAW capability (Manual)"
|
||||
audit: |
|
||||
# needs verification
|
||||
for i in `oc get scc --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'`;
|
||||
do
|
||||
echo "$i";
|
||||
oc describe scc $i | grep "Required Drop Capabilities";
|
||||
done
|
||||
oc get scc -o=custom-columns=NAME:.metadata.name,requiredDropCapabilities:.requiredDropCapabilities
|
||||
tests:
|
||||
bin_op: or
|
||||
test_items:
|
||||
|
||||
@@ -242,6 +242,9 @@ func TestMapToCISVersion(t *testing.T) {
|
||||
{kubeVersion: "1.24", succeed: true, exp: "cis-1.24"},
|
||||
{kubeVersion: "1.25", succeed: true, exp: "cis-1.7"},
|
||||
{kubeVersion: "1.26", succeed: true, exp: "cis-1.8"},
|
||||
{kubeVersion: "1.27", succeed: true, exp: "cis-1.9"},
|
||||
{kubeVersion: "1.28", succeed: true, exp: "cis-1.9"},
|
||||
{kubeVersion: "1.29", succeed: true, exp: "cis-1.9"},
|
||||
{kubeVersion: "gke-1.2.0", succeed: true, exp: "gke-1.2.0"},
|
||||
{kubeVersion: "ocp-3.10", succeed: true, exp: "rh-0.7"},
|
||||
{kubeVersion: "ocp-3.11", succeed: true, exp: "rh-0.7"},
|
||||
|
||||
@@ -22,6 +22,7 @@ The following table shows the valid targets based on the CIS Benchmark version.
|
||||
| cis-1.24 | master, controlplane, node, etcd, policies |
|
||||
| cis-1.7 | master, controlplane, node, etcd, policies |
|
||||
| cis-1.8 | master, controlplane, node, etcd, policies |
|
||||
| cis-1.9 | master, controlplane, node, etcd, policies |
|
||||
| gke-1.0 | master, controlplane, node, etcd, policies, managedservices |
|
||||
| gke-1.2.0 | controlplane, node, policies, managedservices |
|
||||
| eks-1.0.1 | controlplane, node, policies, managedservices |
|
||||
|
||||
@@ -17,6 +17,7 @@ Some defined by other hardenening guides.
|
||||
| CIS | [1.24](https://workbench.cisecurity.org/benchmarks/10873) | cis-1.24 | 1.24 |
|
||||
| CIS | [1.7](https://workbench.cisecurity.org/benchmarks/11107) | cis-1.7 | 1.25 |
|
||||
| CIS | [1.8](https://workbench.cisecurity.org/benchmarks/12958) | cis-1.8 | 1.26 |
|
||||
| CIS | [1.9](https://workbench.cisecurity.org/benchmarks/16828) | cis-1.9 | 1.27-1.29 |
|
||||
| CIS | [GKE 1.0.0](https://workbench.cisecurity.org/benchmarks/4536) | gke-1.0 | GKE |
|
||||
| CIS | [GKE 1.2.0](https://workbench.cisecurity.org/benchmarks/7534) | gke-1.2.0 | GKE |
|
||||
| CIS | [EKS 1.0.1](https://workbench.cisecurity.org/benchmarks/6041) | eks-1.0.1 | EKS |
|
||||
|
||||
40
go.mod
40
go.mod
@@ -3,8 +3,8 @@ module github.com/aquasecurity/kube-bench
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6
|
||||
github.com/aws/aws-sdk-go-v2 v1.26.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.4
|
||||
github.com/aws/aws-sdk-go-v2/service/securityhub v1.29.1
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/golang/glog v1.2.0
|
||||
@@ -17,22 +17,22 @@ require (
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gorm.io/driver/postgres v1.5.6
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde
|
||||
k8s.io/apimachinery v0.29.1
|
||||
k8s.io/client-go v0.29.1
|
||||
k8s.io/apimachinery v0.29.3
|
||||
k8s.io/client-go v0.29.3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
|
||||
github.com/aws/smithy-go v1.19.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 // indirect
|
||||
github.com/aws/smithy-go v1.20.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
@@ -41,7 +41,7 @@ require (
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
@@ -49,7 +49,8 @@ require (
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.4.3 // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.4 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -77,16 +78,17 @@ require (
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/oauth2 v0.15.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/term v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.29.1 // indirect
|
||||
k8s.io/api v0.29.3 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
|
||||
84
go.sum
84
go.sum
@@ -1,35 +1,35 @@
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
|
||||
github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA=
|
||||
github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.4 h1:AhfWb5ZwimdsYTgP7Od8E9L1u4sKmDW2ZVeLcf2O42M=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.4/go.mod h1:zq2FFXK3A416kiukwpsd+rD4ny6JC7QSkp4QdN1Mp2g=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.4 h1:h5Vztbd8qLppiPwX+y0Q6WiwMZgpd9keKe2EAENgAuI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.4/go.mod h1:+30tpwrkOgvkJL1rUZuRLoxcJwtI/OkeBLYnHxJtVe0=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 h1:AK0J8iYBFeUk2Ax7O8YpLtFsfhdOByh2QIkHmigpRYk=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2/go.mod h1:iRlGzMix0SExQEviAyptRWRGdYNo3+ufW/lCzvKVTUc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30/go.mod h1:LUBAO3zNXQjoONBKn/kR1y0Q4cj/D02Ts0uHYjcCQLM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 h1:bNo4LagzUKbjdxE0tIcR9pMzLR2U/Tgie1Hq1HQ3iH8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2/go.mod h1:wRQv0nN6v9wDXuWThpovGQjqF1HFdcgWjporw14lS8k=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 h1:EtOU5jsPdIQNP+6Q2C5e3d65NKT1PeCiQk+9OdzO12Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2/go.mod h1:tyF5sKccmDz0Bv4NrstEr+/9YkSPJHrcO7UsUKf7pWM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 h1:5ffmXjPtwRExp1zc7gENLgCPyHFbhEPwVTkTiH9niSk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2/go.mod h1:Ru7vg1iQ7cR4i7SZ/JTLYN9kaXtbL69UdgG0OQWQxW0=
|
||||
github.com/aws/aws-sdk-go-v2/service/securityhub v1.29.1 h1:+lpa31bGPPvgpZwUJ4ldKRCsPukzJ0PqoO5AQ9S79oQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/securityhub v1.29.1/go.mod h1:vKGWzDG4Ytw3hgv/FvNy0HX/XEoJ6k/e7KAANzXWP8Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 h1:utEGkfdQ4L6YW/ietH7111ZYglLJvS+sLriHJ1NBJEQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.20.1/go.mod h1:RsYqzYr2F2oPDdpy+PdhephuZxTfjHQe7SOBcZGoAU8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 h1:9/GylMS45hGGFCcMrUZDVayQE1jYSIN6da9jo7RAYIw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1/go.mod h1:YjAPFn4kGFqKC54VsHs5fn5B6d+PCY2tziEa3U/GB5Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 h1:3I2cBEYgKhrWlwyZgfpSO2BpaMY1LHPqXYk/QGlu2ew=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.1/go.mod h1:uQ7YYKZt3adCRrdCBREm1CD3efFLOUNH77MrUCvx5oA=
|
||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
|
||||
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
|
||||
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
|
||||
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -69,15 +69,13 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
@@ -98,8 +96,10 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
||||
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
||||
github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8=
|
||||
github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
@@ -220,6 +220,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -261,10 +263,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
@@ -288,12 +288,12 @@ gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU=
|
||||
gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw=
|
||||
k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ=
|
||||
k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc=
|
||||
k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
|
||||
k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A=
|
||||
k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks=
|
||||
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
|
||||
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
|
||||
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
||||
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
|
||||
2
job.yaml
2
job.yaml
@@ -11,7 +11,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- command: ["kube-bench"]
|
||||
image: docker.io/aquasec/kube-bench:v0.7.2
|
||||
image: docker.io/aquasec/kube-bench:v0.8.0
|
||||
name: kube-bench
|
||||
volumeMounts:
|
||||
- name: var-lib-cni
|
||||
|
||||
18
makefile
18
makefile
@@ -11,6 +11,8 @@ uname := $(shell uname -s)
|
||||
BUILDX_PLATFORM ?= linux/amd64,linux/arm64,linux/arm,linux/ppc64le,linux/s390x
|
||||
DOCKER_ORGS ?= aquasec public.ecr.aws/aquasecurity
|
||||
GOARCH ?= $@
|
||||
KUBECTL_VERSION ?= 1.28.7
|
||||
ARCH ?= $(shell go env GOARCH)
|
||||
|
||||
ifneq ($(findstring Microsoft,$(shell uname -r)),)
|
||||
BUILD_OS := windows
|
||||
@@ -45,15 +47,19 @@ build-fips:
|
||||
# builds the current dev docker version
|
||||
build-docker:
|
||||
docker build --build-arg BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||
--build-arg VCS_REF=$(VERSION) \
|
||||
--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \
|
||||
-t $(IMAGE_NAME) .
|
||||
--build-arg VCS_REF=$(VERSION) \
|
||||
--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \
|
||||
--build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \
|
||||
--build-arg TARGETARCH=$(ARCH) \
|
||||
-t $(IMAGE_NAME) .
|
||||
|
||||
build-docker-ubi:
|
||||
docker build -f Dockerfile.ubi --build-arg BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||
--build-arg VCS_REF=$(VERSION) \
|
||||
--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \
|
||||
-t $(IMAGE_NAME_UBI) .
|
||||
--build-arg VCS_REF=$(VERSION) \
|
||||
--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \
|
||||
--build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \
|
||||
--build-arg TARGETARCH=$(ARCH) \
|
||||
-t $(IMAGE_NAME_UBI) .
|
||||
|
||||
# unit tests
|
||||
tests:
|
||||
|
||||
Reference in New Issue
Block a user