Compare commits

...

76 Commits

Author SHA1 Message Date
Liz Rice
c13632318e Merge pull request #122 from wmedlar/bugfix/docker-entrypoint-fail-on-error
Fail fast in container entrypoint
2018-05-11 20:13:58 +01:00
Liz Rice
b649cef047 Merge branch 'master' into bugfix/docker-entrypoint-fail-on-error 2018-05-11 19:58:35 +01:00
Liz Rice
056da1b28d Merge pull request #124 from aquasecurity/travis-docker
Adding a test install to travis job
2018-05-11 19:58:05 +01:00
Liz Rice
9810bafabe Adding a test install to travis job 2018-05-11 19:49:11 +01:00
Liz Rice
5eb4ab7479 Merge branch 'master' into bugfix/docker-entrypoint-fail-on-error 2018-05-11 19:25:38 +01:00
Liz Rice
9f5c856206 Merge pull request #123 from Tenzer/add-info-about-version-flag
Add tip about the `--version` flag to error output
2018-05-11 19:25:06 +01:00
Jeppe Fihl-Pearson
39d94df81b Add tip about the --version flag to error output
If people are trying to use the Docker image to check their cluster, there's a
big likelyhood of them hitting the error message saying that either `kubectl`
or `kubelet` need to be found in order for `kube-bench` to be able to determine
the Kubernetes version in use.

This adds a tip that the version can be specified manually with the `--version`
flag which is a lot easier than having to make a new Docker image with the
right version of `kubelet`/`kubectl` in order for `kube-bench` to work.
2018-05-11 18:58:24 +01:00
Will Medlar
7823ca388c Set -e to fail fast 2018-05-11 13:44:04 -04:00
Liz Rice
b3fc84277d Merge pull request #121 from aquasecurity/request-timeout
--request-timeout is a duration
2018-05-11 16:20:40 +01:00
Liz Rice
863a643adb Merge branch 'master' into request-timeout 2018-05-11 16:13:12 +01:00
Liz Rice
1935c952d6 --request-timeout is a duration 2018-05-11 16:03:03 +01:00
Liz Rice
5be0a9fbdf Merge pull request #119 from aquasecurity/fix-install
Script needs to actually install kube-bench & its config
2018-05-11 15:45:14 +01:00
Liz Rice
b26b23e573 Script needs to actually install kube-bench & its config! 2018-05-11 15:39:11 +01:00
Liz Rice
3ee43235b5 Merge pull request #117 from aquasecurity/lizrice-patch-1
Add link to releases page
2018-05-11 15:33:19 +01:00
Liz Rice
7460037528 Add link to releases page 2018-05-11 12:47:04 +01:00
Liz Rice
479469b3ec Merge pull request #115 from wmedlar/feature/running-in-docker
Allow kube-bench to be run from inside its container
2018-05-11 12:38:18 +01:00
Will Medlar
0c52ace48f Install binary and configs as the default behavior 2018-05-06 21:18:47 -05:00
Will Medlar
3eb8a08a9d Freeze alpine to tag 3.7 2018-05-06 21:17:38 -05:00
Will Medlar
1cff0c4da1 Clarify that only Linux is supported when installing from container 2018-05-06 14:01:49 -05:00
Will Medlar
0714683371 Modify entrypoint to allow execution of kube-bench as default 2018-05-06 13:57:58 -05:00
Will Medlar
3560bbbbfa Allow kube-bench to be run inside its distribution container 2018-05-06 13:35:23 -05:00
Liz Rice
67786fd3ef Merge pull request #111 from aquasecurity/logo
Add logo
2018-04-20 13:31:48 +01:00
Liz Rice
033245f71c logo in svg format 2018-04-20 13:18:55 +01:00
Liz Rice
cb4bec9120 logo instead of heading 2018-04-20 13:07:49 +01:00
Liz Rice
f065893f52 Add logo to readme 2018-04-20 13:05:30 +01:00
Liz Rice
5ee7c1b0db kube-bench logo 2018-04-20 13:02:22 +01:00
Liz Rice
ec51a4eabb Merge pull request #108 from wmedlar/feature/issue-107
Allow kubernetes version and config directory to be specified (resolves #107). Thank you @wmedlar!
2018-04-16 17:17:45 +01:00
Liz Rice
0b4872104d Merge branch 'master' into feature/issue-107 2018-04-16 17:15:30 +01:00
Liz Rice
46bbcdd9bc Merge pull request #106 from aquasecurity/additional-flags
Add extra output manipulation flags
2018-04-15 19:17:43 +02:00
Will Medlar
9469b1c124 Allow kubernetes version and config directory to be specified (resolves #107) 2018-04-12 15:01:58 -04:00
Abubakr-Sadik Nii Nai Davis
ade064006e Add extra output manipulation flags, --noremediations, --nosummary and
--noresults.

These flags disable printing sections of the final output of kube-bench.
2018-04-10 20:01:47 +00:00
Liz Rice
ef6c017f54 Merge pull request #104 from aquasecurity/update-goreleaser
Add homepage to goreleaser config to fix build
2018-04-04 15:02:41 +01:00
Liz Rice
b587e7a996 Add homepage to goreleaser config to fix build 2018-04-04 14:57:28 +01:00
Liz Rice
bad3508ba3 Merge pull request #102 from aquasecurity/update-goreleaser
Update to nfpm as fpm is deprecated
2018-04-04 14:01:17 +01:00
Liz Rice
0d84dc4d42 Update to nfpm as fpm is deprecated 2018-04-04 11:31:47 +01:00
Liz Rice
51212b861f Merge pull request #101 from aquasecurity/version-fallback2
Use 1.8 tests for k8s 1.9 and 1.10
2018-04-04 10:54:55 +01:00
Liz Rice
728cb0765f Use 1.8 tests for k8s 1.9 and 1.10 2018-04-04 10:49:05 +01:00
Liz Rice
d846b221e5 Merge pull request #100 from philalex/use_kubelet
Use kubelet
2018-04-04 08:58:56 +01:00
Philippe ALEXANDRE
f091c8adea Remove the old lines of fmt.Sprintf in cmd/common.go 2018-03-27 15:33:01 +02:00
Philippe ALEXANDRE
d6c16f7563 Try to use kubelet when kubectl is unavailable 2018-03-23 09:29:17 +01:00
Philippe ALEXANDRE
c86d0ff81b Replace fmt.Sprintf by filepath.Join 2018-03-23 09:27:48 +01:00
Liz Rice
c808d9527d Merge pull request #96 from clemensw/patch-1
Update README.md to reflect that the --installation option has been r…
2018-02-23 17:17:28 +00:00
clemensw
95769cae83 Update README.md to reflect that the --installation option has been removed. 2018-02-23 17:12:52 +01:00
Liz Rice
1f52a13400 Merge pull request #94 from jaxxstorm/test_updates
Test fixes for 1.8
2018-01-30 19:58:12 +00:00
Liz Rice
7f41564a62 Merge branch 'master' into test_updates 2018-01-30 19:50:13 +00:00
Liz Rice
8c56ca650a Merge pull request #84 from jaxxstorm/u/jaxxstorm/golint
Lint all code for golint tests
2018-01-30 19:49:58 +00:00
Liz Rice
58b6358a02 Merge branch 'master' into u/jaxxstorm/golint 2018-01-30 19:46:44 +00:00
Liz Rice
731fcb4437 Merge pull request #95 from jaxxstorm/docker_remove
Remove docker build
2018-01-30 19:33:37 +00:00
Lee Briggs
fe23f8140a Remove docker build 2018-01-30 11:16:53 -08:00
Lee Briggs
d464ab5639 Wrong configuration file 2018-01-30 09:49:41 -08:00
Lee Briggs
165444df60 Test fixes for 1.8 2018-01-30 09:28:20 -08:00
Liz Rice
18032b22eb Merge pull request #91 from aquasecurity/lizrice-patch-1
Fix build
2018-01-30 17:13:42 +00:00
Liz Rice
c389d6ecf2 Fix build
Copy the cfg files and entrypoint.sh from the first stage of the multistage build
2018-01-30 16:56:23 +00:00
Liz Rice
4f07b01ead Merge pull request #83 from jaxxstorm/u/jaxxstorm/goreleaser
Add goreleaser configuration
2018-01-30 09:24:07 +00:00
Lee Briggs
e0a032dfbb Merge remote-tracking branch 'upstream/master' into u/jaxxstorm/goreleaser 2018-01-26 11:43:20 -08:00
Liz Rice
0c309bc1d4 Merge pull request #90 from jhvhs/master
Improve etcd data directory extraction
2018-01-25 13:16:32 +00:00
Liz Rice
4b1b2b8762 Merge branch 'master' into master 2018-01-25 13:13:57 +00:00
Liz Rice
4f90a1361c Merge pull request #68 from aquasecurity/unnecessary-warning
Improves the way we get config & binary file names for different installation methods.
2018-01-25 13:12:30 +00:00
Liz Rice
fc4fe38bc2 Merge branch 'master' into unnecessary-warning 2018-01-25 13:01:48 +00:00
Konstantin Semenov
961dbeb2b5 Correct sed regex 2018-01-25 00:34:52 +00:00
Konstantinos Karampogias
8fc6904093 Improve etcd data directory extraction
- If data-dir is not the last argument, the remaining arguments
  are captured preventing the correct checking.

Signed-off-by: Konstantin Semenov <ksemenov@pivotal.io>
2018-01-24 14:17:45 +00:00
Liz Rice
be0134de95 Merge pull request #89 from aquasecurity/issue-88
Fix etcd tests fail because kube-bench expects flags to be set with equal sign
2018-01-19 11:44:17 +00:00
Abubakr-Sadik Nii Nai Davis
7fcfb0cf30 Fix issue with etcd checks failing because of using " " instead of "=" to specify value.
This issue affects master checks 1.4.11 and 1.4.12.
2018-01-18 14:41:46 +00:00
Liz Rice
c9227c0eea Merge branch 'master' into unnecessary-warning 2018-01-15 11:30:25 +00:00
jerbia
850cde23e9 Added travis token (#87) 2018-01-15 01:24:42 +02:00
jerbia
cbe02e1d5e Fixed typo in entrypoint.sh (#86)
The entrypoint.sh had a typo where it tried coping files from "/kube-bench" instead of just "/".
2018-01-15 00:59:27 +02:00
Lee Briggs
f63cd11807 Fix docker repo path 2018-01-12 08:54:39 -08:00
Lee Briggs
94a1f3c41f Lint all code for golint tests 2018-01-11 10:01:58 -08:00
Lee Briggs
3dd5db693d Add goreleaser configuration 2018-01-11 09:48:57 -08:00
Liz Rice
e7152265eb Merge pull request #82 from aquasecurity/lizrice-patch-1
Minor format update to readme
2018-01-11 19:20:49 +02:00
Liz Rice
1e25e089d0 Minor format update to readme 2018-01-11 16:54:40 +00:00
Liz Rice
b42f2ba39e Merge branch 'master' into unnecessary-warning 2018-01-11 18:48:15 +02:00
Abubakr-Sadik Nii Nai Davis
64aaef7997 Fixed expected return for getKubeVersion. 2017-11-28 17:47:57 +00:00
Abubakr-Sadik Nii Nai Davis
53eb720952 Merge branch 'master' into unnecessary-warning 2017-11-28 17:44:53 +00:00
Abubakr-Sadik Nii Nai Davis
04f044e3b9 Add support for merging general and kubernetes version specific config files.
This change unifies all config files, podspecs and unitfiles under
a single component configuration key; `config`.
2017-11-28 17:38:34 +00:00
Abubakr-Sadik Nii Nai Davis
31b5910a7f Remove unnecessary warnings about missing config files. 2017-11-03 10:41:01 +00:00
19 changed files with 551 additions and 239 deletions

19
.goreleaser.yml Normal file
View File

@@ -0,0 +1,19 @@
builds:
- main: main.go
binary: kube-bench
goos:
- darwin
- linux
goarch:
- amd64
# Archive customization
archive:
format: tar.gz
nfpm:
vendor: Aqua Security
description: "The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed according to security best practices"
license: Apache-2.0
homepage: https://github.com/aquasecurity/kube-bench
formats:
- deb
- rpm

View File

@@ -1,6 +1,34 @@
---
language: go
install:
- go get github.com/aquasecurity/kube-bench
sudo: required
services:
- docker
notifications:
email: false
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y rpm
- gem install --no-ri --no-rdoc fpm
install:
- go get -v github.com/Masterminds/glide
- cd $GOPATH/src/github.com/Masterminds/glide && git checkout tags/v0.12.3 && go install && cd - # use a known good glide version
- glide install
script:
- go test ./...
- go build -o kube-bench .
- docker build --tag kube-bench .
- docker run -v `pwd`:/host kube-bench install
- test -d cfg
- test -f kube-bench
after_success:
- test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash
env:
global:
secure: mb8AYZKDo6hkKN+2F9ldXcw27Yn2AfxpXvKlD8GD7NdGOI+TaiSFbE0I+qqTa/1DqcRekCQwqN7OG/17s9JDkgzUXYuYUGlVUOM4WbeJoSlzJFIOh9r9R/JddluYJohypgkE20IBHIrEHq5sY0Nn1Pl9WgSQFaVcQjxkX009AOuVjN0o5HcoXsb5hAzvHrpoSPkcSSqq7VWab60TgUttVaRlZSGwGdSYQEqk5TdO0hWHuXyxaaEPybgFIyZLLbxPS4JmMz8n3Sngetpw9Jgc+V9Fc7wKXpjvZZ33SpArG5p5ZFFu2YQOXFLZth9qtQOjduQ2gU1kHN6WjWnJ8QX2s8vmU38Tk19kd5i+mz9dvc87IdBvmTIqVYSpM6AAYa2osBGP3f97Rj2S68lTad4ecSVyHdsjz56vdE3ZH4wskswmogbKkVdvO4biPHxT6odszBxYLEJuRJyZ7ckXd52MCzqAUPrw7YUuH8N1mLIlf7V5bW5R+q4DlKw774zxnHiWrymXGvlINSrB0qxBn8Fii6ib+Pacl3PuqSumCcgIHlVjqrzIXaqcTMn2/ABZYC99mralGvwA/EgNa8CBKB5evMCEwWa5Ntvcs2I2DFcO5Q2WzN4H0YScyAzzCzK7/3hWJE/rUIJntwiSXkV3MSa1yxWSGGH8F1lcz+lzgTBm/MU=

View File

@@ -1,13 +1,22 @@
FROM golang:1.9
WORKDIR /kube-bench
RUN go get github.com/aquasecurity/kube-bench
FROM golang:1.9 AS build
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
ADD glide.lock glide.yaml ./
RUN go get github.com/Masterminds/glide && glide install
ADD main.go .
ADD check/ check/
ADD cmd/ cmd/
RUN CGO_ENABLED=0 go install -a -ldflags '-w'
FROM alpine:latest
WORKDIR /
COPY --from=0 /go/bin/kube-bench /kube-bench
COPY cfg cfg
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
FROM alpine:3.7 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
RUN apk --no-cache add procps
COPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench
ADD entrypoint.sh .
ADD cfg/ cfg/
ENTRYPOINT ["./entrypoint.sh"]
CMD ["install"]
# Build-time metadata as defined at http://label-schema.org
ARG BUILD_DATE

View File

@@ -3,9 +3,9 @@
[![Docker image](https://images.microbadger.com/badges/image/aquasec/kube-bench.svg)](https://microbadger.com/images/aquasec/kube-bench "Get your own image badge on microbadger.com")
[![Source commit](https://images.microbadger.com/badges/commit/aquasec/kube-bench.svg)](https://microbadger.com/images/aquasec/kube-bench)
# kube-bench
<img src="images/kube-bench.png" width="200" alt="kube-bench logo">
The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark.
kube-bench is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark.
Tests are configured with YAML files, making this tool easy to update as test specifications evolve.
@@ -17,19 +17,46 @@ kube-bench supports the tests for multiple versions of Kubernetes (1.6, 1.7 and
## Installation
You can either install kube-bench through a dedicated container, or compile it from source:
You can choose to
* run kube-bench from inside a container (sharing PID namespace with the host)
* run a container that installs kube-bench on the host, and then run kube-bench directly on the host
* install the latest binaries from the [Releases page](https://github.com/aquasecurity/kube-bench/releases),
* compile it from source.
1. Container installation:
Run ```docker run --rm -v `pwd`:/host aquasec/kube-bench:latest```. This will copy the kube-bench binary and configuration to you host. You can then run ```./kube-bench <master|node>```.
### Running inside a container
You can avoid installing kube-bench on the host by running it inside a container using the host PID namespace.
```
docker run --pid=host aquasec/kube-bench:latest <master|node>
```
You can even use your own configs by mounting them over the default ones in `/opt/kube-bench/cfg/`
```
docker run --pid=host -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yaml aquasec/kube-bench:latest <master|node>
```
### Installing from a container
This command copies the kube-bench binary and configuration files to your host from the Docker container:
```
docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
```
You can then run `./kube-bench <master|node>`.
### Installing from sources
2. Install from sources:
If Go is installed on the target machines, you can simply clone this repository and run as follows (assuming your [$GOPATH is set](https://github.com/golang/go/wiki/GOPATH)):
```go get github.com/aquasecurity/kube-bench```
```go get github.com/Masterminds/glide```
```cd $GOPATH/src/github.com/aquasecurity/kube-bench```
```$GOPATH/bin/glide install```
```go build -o kube-bench . ```
```./kube-bench <master|node>```
```go get github.com/aquasecurity/kube-bench
go get github.com/Masterminds/glide
cd $GOPATH/src/github.com/aquasecurity/kube-bench
$GOPATH/bin/glide install
go build -o kube-bench .
./kube-bench <master|node>
```
## Usage
```./kube-bench [command]```
@@ -45,7 +72,6 @@ Flags:
-c, --check string A comma-delimited list of checks to run as specified in CIS document. Example --check="1.1.1,1.1.2"
--config string config file (default is ./cfg/config.yaml)
-g, --group string Run all the checks under this comma-delimited list of groups. Example --group="1.1"
--installation string Specify how kubernetes cluster was installed. Possible values are default,hyperkube,kops,kubeadm (default "default")
--json Prints the results as JSON
-v, --verbose verbose output (default false)
```

View File

@@ -731,7 +731,7 @@ groups:
- id: 1.4.11
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %a"
audit: ps -ef | grep $etcdbin | grep -v grep | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %a
tests:
test_items:
- flag: "700"
@@ -748,7 +748,7 @@ groups:
- id: 1.4.12
text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %U:%G"
audit: ps -ef | grep $etcdbin | grep -v grep | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %U:%G
tests:
test_items:
- flag: "etcd:etcd"

View File

@@ -793,7 +793,7 @@ groups:
- id: 1.4.11
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %a"
audit: ps -ef | grep $etcdbin | grep -v grep | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %a
tests:
test_items:
- flag: "700"
@@ -810,7 +810,7 @@ groups:
- id: 1.4.12
text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %U:%G"
audit: ps -ef | grep $etcdbin | grep -v grep | ed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %U:%G
tests:
test_items:
- flag: "etcd:etcd"

38
cfg/1.8/config.yaml Normal file
View File

@@ -0,0 +1,38 @@
---
## Controls Files.
# These are YAML files that hold all the details for running checks.
#
## Uncomment to use different control file paths.
# masterControls: ./cfg/master.yaml
# nodeControls: ./cfg/node.yaml
# federatedControls: ./cfg/federated.yaml
master:
apiserver:
defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
confs:
- /etc/kubernetes/manifests/kube-scheduler.yaml
defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml
controllermanager:
confs:
- /etc/kubernetes/manifests/kube-controller-manager.yaml
defaultconf: /etc/kubernetes/manifests/kube-controller-manager.yaml
etcd:
confs:
- /etc/kubernetes/manifests/etcd.yaml
defaultconf: /etc/kubernetes/manifests/etcd.yaml
node:
kubelet:
confs:
- /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
defaultconf: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
proxy:
confs:
- /etc/kubernetes/addons/kube-proxy-daemonset.yaml
defaultconf: /etc/kubernetes/addons/kube-proxy-daemonset.yaml

View File

@@ -19,7 +19,7 @@ groups:
value: false
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the below parameter.
--anonymous-auth=false
@@ -34,7 +34,7 @@ groups:
set: false
remediation: |
Follow the documentation and configure alternate mechanisms for authentication. Then,
edit the API server pod specification file $apiserverpodspec
edit the API server pod specification file $apiserverconf
on the master node and remove the --basic-auth-file=<filename>
parameter.
scored: true
@@ -47,7 +47,7 @@ groups:
- flag: "--insecure-allow-any-token"
set: false
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and remove the --insecure-allow-any-token
parameter.
scored: true
@@ -66,7 +66,7 @@ groups:
- flag: "--kubelet-https"
set: false
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and remove the --kubelet-https parameter.
scored: true
@@ -78,7 +78,7 @@ groups:
- flag: "--insecure-bind-address"
set: false
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and remove the --insecure-bind-address
parameter.
scored: true
@@ -94,7 +94,7 @@ groups:
value: 0
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
apiserver.yaml on the master node and set the below parameter.
--insecure-port=0
scored: true
@@ -113,7 +113,7 @@ groups:
- flag: "--secure-port"
set: false
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and either remove the --secure-port parameter or
set it to a different (non-zero) desired port.
scored: true
@@ -129,7 +129,7 @@ groups:
value: false
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the below parameter.
--profiling=false
scored: true
@@ -145,7 +145,7 @@ groups:
value: false
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the below parameter.
--repair-malformed-updates=false
scored: true
@@ -161,7 +161,7 @@ groups:
value: AlwaysAdmit
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to a
value that does not include AlwaysAdmit.
scored: true
@@ -177,7 +177,7 @@ groups:
value: "AlwaysPullImages"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to
include AlwaysPullImages.
--admission-control=...,AlwaysPullImages,...
@@ -194,7 +194,7 @@ groups:
value: "DenyEscalatingExec"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to a
value that includes DenyEscalatingExec.
--admission-control=...,DenyEscalatingExec,...
@@ -211,7 +211,7 @@ groups:
value: "SecurityContextDeny"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to
include SecurityContextDeny.
--admission-control=...,SecurityContextDeny,...
@@ -228,7 +228,7 @@ groups:
value: "NamespaceLifecycle"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to
include NamespaceLifecycle.
--admission-control=...,NamespaceLifecycle,...
@@ -242,7 +242,7 @@ groups:
- flag: "--audit-log-path"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master 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
@@ -259,7 +259,7 @@ groups:
value: 30
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --audit-log-maxage parameter to 30 or
as an appropriate number of days:
--audit-log-maxage=30
@@ -276,7 +276,7 @@ groups:
value: 10
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --audit-log-maxbackup parameter to 10
or to an appropriate value.
--audit-log-maxbackup=10
@@ -293,7 +293,7 @@ groups:
value: 100
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master 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
@@ -310,7 +310,7 @@ groups:
value: "AlwaysAllow"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --authorization-mode parameter to
values other than AlwaysAllow. One such example could be as below.
--authorization-mode=RBAC
@@ -325,7 +325,7 @@ groups:
set: false
remediation: |
Follow the documentation and configure alternate mechanisms for authentication. Then,
edit the API server pod specification file $apiserverpodspec
edit the API server pod specification file $apiserverconf
on the master node and remove the --token-auth-file=<filename>
parameter.
scored: true
@@ -340,7 +340,7 @@ groups:
remediation: |
Follow the Kubernetes documentation and setup the TLS connection between the apiserver
and kubelets. Then, edit the API server pod specification file
$apiserverpodspec on the master node and set the --
$apiserverconf on the master node and set the --
kubelet-certificate-authority parameter to the path to the cert file for the certificate
authority.
--kubelet-certificate-authority=<ca-string>
@@ -360,7 +360,7 @@ groups:
remediation: |
Follow the Kubernetes documentation and set up the TLS connection between the
apiserver and kubelets. Then, edit API server pod specification file
$apiserverpodspec on the master node and set the
$apiserverconf on the master 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>
@@ -377,7 +377,7 @@ groups:
value: true
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the below parameter.
--service-account-lookup=true
scored: true
@@ -394,7 +394,7 @@ groups:
set: true
remediation: |
Follow the documentation and create Pod Security Policy objects as per your environment.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to a
value that includes PodSecurityPolicy :
--admission-control=...,PodSecurityPolicy,...
@@ -410,7 +410,7 @@ groups:
- flag: "--service-account-key-file"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --service-account-key-file parameter
to the public key file for service accounts:
--service-account-key-file=<filename>
@@ -430,7 +430,7 @@ groups:
remediation: |
Follow the Kubernetes documentation and set up the TLS connection between the
apiserver and etcd. Then, edit the API server pod specification file
$apiserverpodspec on the master node and set the etcd
$apiserverconf on the master node and set the etcd
certificate and key file parameters.
--etcd-certfile=<path/to/client-certificate-file>
--etcd-keyfile=<path/to/client-key-file>
@@ -448,7 +448,7 @@ groups:
set: true
remediation: |
Follow the documentation and create ServiceAccount objects as per your environment.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to a
value that includes ServiceAccount.
--admission-control=...,ServiceAccount,...
@@ -467,7 +467,7 @@ groups:
set: true
remediation: |
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
on the master node and set the TLS certificate and private key file
parameters.
--tls-cert-file=<path/to/tls-certificate-file>
@@ -483,7 +483,7 @@ groups:
set: true
remediation: |
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
on the master node and set the client certificate authority file.
--client-ca-file=<path/to/client-ca-file>
scored: true
@@ -498,7 +498,7 @@ groups:
remediation: |
Follow the Kubernetes documentation and set up the TLS connection between the
apiserver and etcd. Then, edit the API server pod specification file
$apiserverpodspec on the master node and set the etcd
$apiserverconf on the master node and set the etcd
certificate authority file parameter.
--etcd-cafile=<path/to/ca-file>
scored: true
@@ -514,7 +514,7 @@ groups:
value: "Node"
set: true
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
on the master node and set the --authorization-mode parameter to a
value that includes Node.
--authorization-mode=Node,RBAC
@@ -532,7 +532,7 @@ groups:
set: true
remediation: |
Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
on the master node and set the --admission-control parameter to a
value that includes NodeRestriction.
--admission-control=...,NodeRestriction,...
@@ -548,7 +548,7 @@ groups:
set: true
remediation: |
Follow the Kubernetes documentation and configure a EncryptionConfig file. Then, edit
the API server pod specification file $apiserverpodspec
the API server pod specification file $apiserverconf
on the master node and set the --experimental-encryption-provider-config parameter
to the path of that file:
--experimental-encryption-provider-config=</path/to/EncryptionConfig/File>
@@ -586,7 +586,7 @@ groups:
set: true
remediation: |
Follow the Kubernetes documentation and set the desired limits in a configuration file.
Then, edit the API server pod specification file $apiserverpodspec
Then, edit the API server pod specification file $apiserverconf
and set the below parameters.
--admission-control=EventRateLimit
--admission-control-config-file=<path/to/configuration/file>
@@ -598,7 +598,7 @@ groups:
type: "manual"
remediation: |
Follow the Kubernetes documentation and set the desired audit policy in the
/etc/kubernetes/audit-policy.yaml file. Then, edit the API server pod specification file $apiserverpodspec
/etc/kubernetes/audit-policy.yaml file. Then, edit the API server pod specification file $apiserverconf
and set the below parameters.
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
scored: true
@@ -608,9 +608,9 @@ groups:
audit: "ps -ef | grep $apiserverbin | grep -v grep"
type: "manual"
remediation: |
Edit the API server pod specification file $apiserverpodspec
Edit the API server pod specification file $apiserverconf
and set the below parameter as appropriate and if needed. For example,
--request-timeout=300
--request-timeout=300s
scored: true
- id: 1.2
@@ -628,7 +628,7 @@ groups:
set: true
remediation: |
Remediation:
Edit the Scheduler pod specification file $apiserverpodspec
Edit the Scheduler pod specification file $schedulerconf
file on the master node and set the below parameter.
--profiling=false
scored: true
@@ -644,7 +644,7 @@ groups:
- flag: "--terminated-pod-gc-threshold"
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $controllermanagerconf
on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold, for example:
--terminated-pod-gc-threshold=10
scored: true
@@ -660,7 +660,7 @@ groups:
value: false
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $apiserverconf
on the master node and set the below parameter.
--profiling=false
scored: true
@@ -676,7 +676,7 @@ groups:
value: true
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $apiserverconf
on the master node to set the below parameter.
--use-service-account-credentials=true
scored: true
@@ -689,7 +689,7 @@ groups:
- flag: "--service-account-private-key-file"
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $apiserverconf
on the master node and set the --service-account-private-
key-file parameter to the private key file for service accounts.
--service-account-private-key-file=<filename>
@@ -703,7 +703,7 @@ groups:
- flag: "--root-ca-file"
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $apiserverconf
on the master node and set the --root-ca-file parameter to
the certificate bundle file.
--root-ca-file=<path/to/file>
@@ -729,7 +729,7 @@ groups:
value: true
set: true
remediation: |
Edit the Controller Manager pod specification file $apiserverpodspec
Edit the Controller Manager pod specification file $apiserverconf
controller-manager.yaml on the master node and set the --feature-gates parameter to
include RotateKubeletServerCertificate=true.
--feature-gates=RotateKubeletServerCertificate=true
@@ -741,7 +741,7 @@ groups:
- id: 1.4.1
text: "Ensure that the API server pod specification file permissions are
set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $apiserverpodspec; then stat -c %a $apiserverpodspec; fi'"
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %a $apiserverconf; fi'"
tests:
bin_op: or
test_items:
@@ -763,13 +763,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chmod 644 $apiserverpodspec
chmod 644 $apiserverconf
scored: true
- id: 1.4.2
text: "Ensure that the API server pod specification file ownership is set to
root:root (Scored)"
audit: "/bin/sh -c 'if test -e $apiserverpodspec; then stat -c %U:%G $apiserverpodspec; fi'"
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -780,13 +780,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chown root:root $apiserverpodspec
chown root:root $apiserverconf
scored: true
- id: 1.4.3
text: "Ensure that the controller manager pod specification file
permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $controllermanagerpodspec; then stat -c %a $controllermanagerpodspec; fi'"
audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %a $controllermanagerconf; fi'"
tests:
bin_op: or
test_items:
@@ -808,13 +808,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chmod 644 $controllermanagerpodspec
chmod 644 $controllermanagerconf
scored: true
- id: 1.4.4
text: "Ensure that the controller manager pod specification file
ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $controllermanagerpodspec; then stat -c %U:%G $controllermanagerpodspec; fi'"
audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -825,13 +825,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chown root:root $controllermanagerpodspec
chown root:root $controllermanagerconf
scored: true
- id: 1.4.5
text: "Ensure that the scheduler pod specification file permissions are set
to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $schedulerpodspec; then stat -c %a $schedulerpodspec; fi'"
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %a $schedulerconf; fi'"
tests:
bin_op: or
test_items:
@@ -853,13 +853,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chmod 644 $schedulerpodspec
chmod 644 $schedulerconf
scored: true
- id: 1.4.6
text: "Ensure that the scheduler pod specification file ownership is set to
root:root (Scored)"
audit: "/bin/sh -c 'if test -e $schedulerpodspec; then stat -c %U:%G $schedulerpodspec; fi'"
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -870,13 +870,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chown root:root $schedulerpodspec
chown root:root $schedulerconf
scored: true
- id: 1.4.7
text: "Ensure that the etcd pod specification file permissions are set to
644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $etcdpodspec; then stat -c %a $etcdpodspec; fi'"
audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %a $etcdconf; fi'"
tests:
bin_op: or
test_items:
@@ -898,13 +898,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chmod 644 $etcdpodspec
chmod 644 $etcdconf
scored: true
- id: 1.4.8
text: "Ensure that the etcd pod specification file ownership is set to
root:root (Scored)"
audit: "/bin/sh -c 'if test -e $etcdpodspec; then stat -c %U:%G $etcdpodspec; fi'"
audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -915,7 +915,7 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
chown root:root $etcdpodspec
chown root:root $etcdconf
scored: true
- id: 1.4.9
@@ -942,7 +942,7 @@ groups:
- id: 1.4.11
text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %a"
audit: ps -ef | grep $etcdbin | grep -v grep | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %a
tests:
test_items:
- flag: "700"
@@ -960,7 +960,7 @@ groups:
- id: 1.4.12
text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep | grep -o data-dir=.* | cut -d= -f2 | xargs stat -c %U:%G"
audit: ps -ef | grep $etcdbin | grep -v grep | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %U:%G
tests:
test_items:
- flag: "etcd:etcd"
@@ -978,12 +978,23 @@ groups:
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %a /etc/kubernetes/admin.conf; fi'"
tests:
bin_op: or
test_items:
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "640"
compare:
op: eq
value: "640"
set: true
- flag: "600"
compare:
op: eq
value: "600"
set: true
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
@@ -1009,14 +1020,25 @@ groups:
- id: 1.4.15
text: "Ensure that the scheduler.conf file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $schedulerconf then stat -c %a $schedulerconf; fi'"
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %a $schedulerconf; fi'"
tests:
bin_op: or
test_items:
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "640"
compare:
op: eq
value: "640"
set: true
- flag: "600"
compare:
op: eq
value: "600"
set: true
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
@@ -1042,14 +1064,25 @@ groups:
- id: 1.4.17
text: "Ensure that the controller-manager.conf file permissions are set
to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $controllermanagerconf then stat -c %a $controllermanagerconf; fi'"
audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %a $controllermanagerconf; fi'"
tests:
bin_op: or
test_items:
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "644"
compare:
op: eq
value: "644"
set: true
- flag: "640"
compare:
op: eq
value: "640"
set: true
- flag: "600"
compare:
op: eq
value: "600"
set: true
remediation: |
Run the below command (based on the file location on your system) on the master node.
For example,
@@ -1086,7 +1119,7 @@ groups:
set: true
remediation: |
Follow the etcd service documentation and configure TLS encryption.
Then, edit the etcd pod specification file $etcdpodspec on the
Then, edit the etcd pod specification file $etcdconf on the
master node and set the below parameters.
--ca-file=</path/to/ca-file>
--key-file=</path/to/key-file>
@@ -1103,7 +1136,7 @@ groups:
value: true
set: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
Edit the etcd pod specification file $etcdconf on the master
node and set the below parameter.
--client-cert-auth="true"
scored: true
@@ -1121,7 +1154,7 @@ groups:
op: neq
value: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
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
@@ -1138,7 +1171,7 @@ groups:
set: true
remediation: |
Follow the etcd service documentation and configure peer TLS encryption as appropriate
for your etcd cluster. Then, edit the etcd pod specification file $etcdpodspec on the
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>
@@ -1155,7 +1188,7 @@ groups:
value: true
set: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
Edit the etcd pod specification file $etcdconf on the master
node and set the below parameter.
--peer-client-cert-auth=true
scored: true
@@ -1174,7 +1207,7 @@ groups:
value: false
set: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
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
@@ -1187,7 +1220,7 @@ groups:
- flag: "--wal-dir"
set: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
Edit the etcd pod specification file $etcdconf on the master
node and set the below parameter.
--wal-dir=</path/to/log/dir>
scored: true
@@ -1203,7 +1236,7 @@ groups:
value: 0
set: true
remediation: |
Edit the etcd pod specification file $etcdpodspec on the master
Edit the etcd pod specification file $etcdconf on the master
node and set the below parameter.
--max-wals=0
scored: true
@@ -1218,7 +1251,7 @@ groups:
remediation: |
Follow the etcd documentation and create a dedicated certificate authority setup for the
etcd service.
Then, edit the etcd pod specification file $etcdpodspec on the
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

View File

@@ -19,7 +19,7 @@ groups:
value: false
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
--allow-privileged=false
Based on your system, restart the kubelet service. For example:
@@ -38,7 +38,7 @@ groups:
value: false
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -57,7 +57,7 @@ groups:
value: "AlwaysAllow"
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -73,7 +73,7 @@ groups:
- flag: "--client-ca-file"
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -92,7 +92,7 @@ groups:
value: 0
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -111,7 +111,7 @@ groups:
value: 0
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -130,7 +130,7 @@ groups:
value: true
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
--protect-kernel-defaults=true
Based on your system, restart the kubelet service. For example:
@@ -150,7 +150,7 @@ groups:
value: true
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -169,7 +169,7 @@ groups:
value: false
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
--keep-terminated-pod-volumes=false
Based on your system, restart the kubelet service. For example:
@@ -185,7 +185,7 @@ groups:
- flag: "--hostname-override"
set: false
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -204,7 +204,7 @@ groups:
value: 0
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
--event-qps=0
Based on your system, restart the kubelet service. For example:
@@ -245,7 +245,7 @@ groups:
value: 0
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and set the below parameter in KUBELET_CADVISOR_ARGS variable.
--cadvisor-port=0
Based on your system, restart the kubelet service. For example:
@@ -264,7 +264,7 @@ groups:
value: true
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
on each worker node and remove the --feature-
gates=RotateKubeletClientCertificate=false argument from the
KUBELET_CERTIFICATE_ARGS variable.
@@ -284,7 +284,7 @@ groups:
value: true
set: true
remediation: |
Edit the kubelet service file $kubeletunitfile
Edit the kubelet service file $kubeletconf
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:
@@ -342,7 +342,7 @@ groups:
- id: 2.2.3
text: "Ensure that the kubelet service file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletunitfile; then stat -c %a $kubeletunitfile; fi'"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
@@ -364,13 +364,13 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chmod 755 $kubeletunitfile
chmod 755 $kubeletconf
scored: true
- id: 2.2.4
text: "Ensure that the kubelet service file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletunitfile; then stat -c %U:%G $kubeletunitfile; fi'"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -378,7 +378,7 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $kubeletunitfile
chown root:root $kubeletconf
scored: true
- id: 2.2.5

View File

@@ -30,10 +30,6 @@ master:
- /etc/kubernetes/apiserver
defaultconf: /etc/kubernetes/apiserver
podspecs:
- /etc/kubernetes/manifests/kube-apiserver.yaml
defaultpodspec: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
bins:
- "kube-scheduler"
@@ -44,10 +40,6 @@ master:
- /etc/kubernetes/scheduler
defaultconf: /etc/kubernetes/scheduler
podspecs:
- /etc/kubernetes/manifests/kube-scheduler.yaml
defaultpodspec: /etc/kubernetes/manifests/kube-scheduler.yaml
controllermanager:
bins:
- "kube-controller-manager"
@@ -58,10 +50,6 @@ master:
- /etc/kubernetes/controller-manager
defaultconf: /etc/kubernetes/controller-manager
podspecs:
- /etc/kubernetes/manifests/kube-controller-manager.yaml
defaultpodspec: /etc/kubernetes/manifests/kube-controller-manager.yaml
etcd:
optional: true
bins:
@@ -70,17 +58,12 @@ master:
- /etc/etcd/etcd.conf
defaultconf: /etc/etcd/etcd.conf
podspecs:
- /etc/kubernetes/manifests/etcd.yaml
defaultpodspec: /etc/kubernetes/manifests/etcd.yaml
flanneld:
optional: true
bins:
- flanneld
defaultconf: /etc/sysconfig/flanneld
node:
components:
- kubelet
@@ -100,10 +83,6 @@ node:
- /etc/kubernetes/kubelet
defaultconf: "/etc/kubernetes/kubelet.conf"
unitfiles:
- /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
defaultunitfile: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
proxy:
bins:
- "kube-proxy"
@@ -130,5 +109,3 @@ federated:
- "hyperkube federation-controller-manager"
- "kube-federation-controller-manager"
- "federation-controller-manager"

View File

@@ -17,6 +17,7 @@ package cmd
import (
"fmt"
"io/ioutil"
"path/filepath"
"github.com/aquasecurity/kube-bench/check"
"github.com/golang/glog"
@@ -29,6 +30,7 @@ var (
func runChecks(t check.NodeType) {
var summary check.Summary
var nodetype string
var file string
var err error
var typeConf *viper.Viper
@@ -36,49 +38,56 @@ func runChecks(t check.NodeType) {
switch t {
case check.MASTER:
file = masterFile
typeConf = viper.Sub("master")
nodetype = "master"
case check.NODE:
file = nodeFile
typeConf = viper.Sub("node")
nodetype = "node"
case check.FEDERATED:
file = federatedFile
typeConf = viper.Sub("federated")
nodetype = "federated"
}
var ver string
if kubeVersion != "" {
ver = kubeVersion
} else {
ver = getKubeVersion()
}
switch ver {
case "1.9", "1.10":
continueWithError(nil, fmt.Sprintf("No CIS spec for %s - using tests from CIS 1.2.0 spec for Kubernetes 1.8\n", ver))
ver = "1.8"
}
path := filepath.Join(cfgDir, ver)
def := filepath.Join(path, file)
in, err := ioutil.ReadFile(def)
if err != nil {
exitWithError(fmt.Errorf("error opening %s controls file: %v", t, err))
}
// Merge kubernetes version specific config if any.
viper.SetConfigFile(path + "/config.yaml")
err = viper.MergeInConfig()
if err != nil {
continueWithError(err, fmt.Sprintf("Reading %s specific configuration file", ver))
}
typeConf = viper.Sub(nodetype)
// Get the set of exectuables and config files we care about on this type of node. This also
// checks that the executables we need for the node type are running.
binmap := getBinaries(typeConf)
confmap := getConfigFiles(typeConf, "conf")
podspecmap := getConfigFiles(typeConf, "podspec")
unitfilemap := getConfigFiles(typeConf, "unitfile")
switch t {
case check.MASTER:
file = masterFile
case check.NODE:
file = nodeFile
case check.FEDERATED:
file = federatedFile
}
ver := getKubeVersion()
glog.V(1).Info(fmt.Sprintf("Running tests for Kubernetes version: %s", ver))
path := fmt.Sprintf("%s/%s/%s", cfgDir, ver, file)
in, err := ioutil.ReadFile(path)
if err != nil {
exitWithError(fmt.Errorf("error opening %s controls file: %v", t, err))
}
confmap := getConfigFiles(typeConf)
// Variable substitutions. Replace all occurrences of variables in controls files.
s := string(in)
s = makeSubstitutions(s, "bin", binmap)
s = makeSubstitutions(s, "conf", confmap)
s = makeSubstitutions(s, "podspec", podspecmap)
s = makeSubstitutions(s, "unitfile", unitfilemap)
glog.V(1).Info(fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed()))
glog.V(1).Info(fmt.Sprintf("Using benchmark file: %s\n", path))
glog.V(1).Info(fmt.Sprintf("Using benchmark file: %s\n", def))
controls, err := check.NewControls(t, []byte(s))
if err != nil {
@@ -107,7 +116,7 @@ func runChecks(t check.NodeType) {
fmt.Println(string(out))
} else {
// if we want to store in PostgreSQL, convert to JSON and save it
if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0) && pgSql {
if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0) && pgSQL {
out, err := controls.JSON()
if err != nil {
exitWithError(fmt.Errorf("failed to output in JSON format: %v", err))
@@ -128,41 +137,48 @@ func colorPrint(state check.State, s string) {
// prettyPrint outputs the results to stdout in human-readable format
func prettyPrint(r *check.Controls, summary check.Summary) {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", r.ID, r.Text))
for _, g := range r.Groups {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text))
for _, c := range g.Checks {
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
}
}
fmt.Println()
// Print remediations.
if summary.Fail > 0 || summary.Warn > 0 {
colors[check.WARN].Printf("== Remediations ==\n")
// Print check results.
if !noResults {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", r.ID, r.Text))
for _, g := range r.Groups {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text))
for _, c := range g.Checks {
if c.State != check.PASS {
fmt.Printf("%s %s\n", c.ID, c.Remediation)
}
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
}
}
fmt.Println()
}
// Print summary setting output color to highest severity.
var res check.State
if summary.Fail > 0 {
res = check.FAIL
} else if summary.Warn > 0 {
res = check.WARN
} else {
res = check.PASS
// Print remediations.
if !noRemediations {
if summary.Fail > 0 || summary.Warn > 0 {
colors[check.WARN].Printf("== Remediations ==\n")
for _, g := range r.Groups {
for _, c := range g.Checks {
if c.State != check.PASS {
fmt.Printf("%s %s\n", c.ID, c.Remediation)
}
}
}
fmt.Println()
}
}
colors[res].Printf("== Summary ==\n")
fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n",
summary.Pass, summary.Fail, summary.Warn,
)
// Print summary setting output color to highest severity.
if !noSummary {
var res check.State
if summary.Fail > 0 {
res = check.FAIL
} else if summary.Warn > 0 {
res = check.WARN
} else {
res = check.PASS
}
colors[res].Printf("== Summary ==\n")
fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n",
summary.Pass, summary.Fail, summary.Warn,
)
}
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/golang/glog"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
_ "github.com/jinzhu/gorm/dialects/postgres" // database packages get blank imports
"github.com/spf13/viper"
)

View File

@@ -26,16 +26,20 @@ import (
var (
envVarsPrefix = "KUBE_BENCH"
cfgDir = "./cfg"
defaultKubeVersion = "1.6"
kubeVersion string
cfgFile string
cfgDir string
jsonFmt bool
pgSql bool
pgSQL bool
checkList string
groupList string
masterFile string
nodeFile string
federatedFile string
noResults bool
noSummary bool
noRemediations bool
)
// RootCmd represents the base command when called without any subcommands
@@ -60,8 +64,13 @@ func Execute() {
func init() {
cobra.OnInitialize(initConfig)
// Output control
RootCmd.PersistentFlags().BoolVar(&noResults, "noresults", false, "Disable prints of results section")
RootCmd.PersistentFlags().BoolVar(&noSummary, "nosummary", false, "Disable printing of summary section")
RootCmd.PersistentFlags().BoolVar(&noRemediations, "noremediations", false, "Disable printing of remediations section")
RootCmd.PersistentFlags().BoolVar(&jsonFmt, "json", false, "Prints the results as JSON")
RootCmd.PersistentFlags().BoolVar(&pgSql, "pgsql", false, "Save the results to PostgreSQL")
RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL")
RootCmd.PersistentFlags().StringVarP(
&checkList,
"check",
@@ -77,6 +86,8 @@ func init() {
`Run all the checks under this comma-delimited list of groups. Example --group="1.1"`,
)
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./cfg/config.yaml)")
RootCmd.PersistentFlags().StringVarP(&cfgDir, "config-dir", "D", "./cfg/", "config directory")
RootCmd.PersistentFlags().StringVar(&kubeVersion, "version", "", "Manually specify Kubernetes version, automatically detected if unset")
goflag.CommandLine.VisitAll(func(goflag *goflag.Flag) {
RootCmd.PersistentFlags().AddGoFlag(goflag)

View File

@@ -119,7 +119,7 @@ func getBinaries(v *viper.Viper) map[string]string {
// getConfigFiles finds which of the set of candidate config files exist
// accepts a string 't' which indicates the type of config file, conf,
// podspec or untifile.
func getConfigFiles(v *viper.Viper, t string) map[string]string {
func getConfigFiles(v *viper.Viper) map[string]string {
confmap := make(map[string]string)
for _, component := range v.GetStringSlice("components") {
@@ -129,14 +129,14 @@ func getConfigFiles(v *viper.Viper, t string) map[string]string {
}
// See if any of the candidate config files exist
conf := findConfigFile(s.GetStringSlice(t + "s"))
conf := findConfigFile(s.GetStringSlice("confs"))
if conf == "" {
if s.IsSet("default" + t) {
conf = s.GetString("default" + t)
if s.IsSet("defaultconf") {
conf = s.GetString("defaultconf")
glog.V(2).Info(fmt.Sprintf("Using default config file name '%s' for component %s", conf, component))
} else {
// Default the config file name that we'll substitute to the name of the component
printlnWarn(fmt.Sprintf("Missing config file for %s", component))
glog.V(2).Info(fmt.Sprintf("Missing config file for %s", component))
conf = component
}
} else {
@@ -196,9 +196,8 @@ func findExecutable(candidates []string) (string, error) {
for _, c := range candidates {
if verifyBin(c) {
return c, nil
} else {
glog.V(1).Info(fmt.Sprintf("executable '%s' not running", c))
}
glog.V(1).Info(fmt.Sprintf("executable '%s' not running", c))
}
return "", fmt.Errorf("no candidates running")
@@ -216,10 +215,19 @@ func multiWordReplace(s string, subname string, sub string) string {
func getKubeVersion() string {
// These executables might not be on the user's path.
_, err := exec.LookPath("kubectl")
if err != nil {
exitWithError(fmt.Errorf("kubernetes version check failed: %v", err))
_, err = exec.LookPath("kubelet")
if err != nil {
exitWithError(fmt.Errorf("Version check failed: need kubectl or kubelet binaries to get kubernetes version.\nAlternately, you can specify the version with --version"))
}
return getKubeVersionFromKubelet()
}
return getKubeVersionFromKubectl()
}
func getKubeVersionFromKubectl() string {
cmd := exec.Command("kubectl", "version", "--short")
out, err := cmd.CombinedOutput()
if err != nil {
@@ -229,6 +237,17 @@ func getKubeVersion() string {
return getVersionFromKubectlOutput(string(out))
}
func getKubeVersionFromKubelet() string {
cmd := exec.Command("kubelet", "--version")
out, err := cmd.CombinedOutput()
if err != nil {
continueWithError(fmt.Errorf("%s", out), "")
}
return getVersionFromKubeletOutput(string(out))
}
func getVersionFromKubectlOutput(s string) string {
serverVersionRe := regexp.MustCompile(`Server Version: v(\d+.\d+)`)
subs := serverVersionRe.FindStringSubmatch(s)
@@ -239,6 +258,16 @@ func getVersionFromKubectlOutput(s string) string {
return subs[1]
}
func getVersionFromKubeletOutput(s string) string {
serverVersionRe := regexp.MustCompile(`Kubernetes v(\d+.\d+)`)
subs := serverVersionRe.FindStringSubmatch(s)
if len(subs) < 2 {
printlnWarn(fmt.Sprintf("Unable to get kubelet version, using default version: %s", defaultKubeVersion))
return defaultKubeVersion
}
return subs[1]
}
func makeSubstitutions(s string, ext string, m map[string]string) string {
for k, v := range m {
subst := "$" + k + ext

View File

@@ -279,7 +279,7 @@ func TestGetConfigFiles(t *testing.T) {
e = c.statResults
eIndex = 0
m := getConfigFiles(v, "conf")
m := getConfigFiles(v)
if !reflect.DeepEqual(m, c.exp) {
t.Fatalf("Got %v\nExpected %v", m, c.exp)
}

View File

@@ -1,14 +1,19 @@
#!/bin/sh
if [ -d /host ]; then
mkdir -p /host/cfg/
yes | cp -rf ./kube-bench/cfg/* /host/cfg/
yes | cp -rf ./kube-bench/kube-bench /host/
echo "==============================================="
echo "kube-bench is now installed on your host "
echo "Run ./kube-bench to perform a security check "
echo "==============================================="
#!/bin/sh -e
if [ "$1" == "install" ]; then
if [ -d /host ]; then
mkdir -p /host/cfg/
yes | cp -rf cfg/* /host/cfg/
yes | cp -rf /usr/local/bin/kube-bench /host/
echo "==============================================="
echo "kube-bench is now installed on your host "
echo "Run ./kube-bench to perform a security check "
echo "==============================================="
else
echo "Usage:"
echo " install: docker run --rm -v \`pwd\`:/host aquasec/kube-bench install"
echo " run: docker run --rm --pid=host aquasec/kube-bench [command]"
exit
fi
else
echo "Usage:"
echo " docker run --rm -v \`pwd\`:/host aquasec/kube-bench"
exit
exec kube-bench "$@"
fi

0
hooks/build Normal file → Executable file
View File

BIN
images/kube-bench.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

121
images/kube-bench.svg Normal file
View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 831.49597 755.90533"
height="755.90533"
width="831.49597"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath22"
clipPathUnits="userSpaceOnUse"><path
id="path20"
d="M 0,566.929 H 623.622 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,755.90533)"
id="g10"><g
transform="translate(314.8111,521.959)"
id="g12"><path
id="path14"
style="fill:#0ab1d5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 -106.784,-145.31 0,-280.384 105.477,-147.025 Z" /></g><g
id="g16"><g
clip-path="url(#clipPath22)"
id="g18"><g
transform="translate(51.8912,72.061)"
id="g24"><path
id="path26"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 71.061 c 0,3.629 2.86,6.6 6.6,6.6 3.74,0 6.6,-2.971 6.6,-6.6 V 32.45 h 2.97 c 1.32,0 2.42,0.551 3.52,1.981 L 33.44,52.69 c 1.43,1.981 3.081,3.3 5.72,3.3 3.63,0 6.271,-2.969 6.271,-6.599 0,-1.87 -0.881,-3.411 -1.981,-4.731 L 29.59,27.5 44.44,3.96 C 45.32,2.641 45.76,1.21 45.76,0 c 0,-3.63 -2.97,-6.6 -6.6,-6.6 -2.309,0 -4.4,1.54 -5.5,3.411 L 19.8,19.25 c -0.88,1.431 -1.98,2.091 -3.52,2.091 H 13.2 L 13.2,0 C 13.2,-3.63 10.34,-6.6 6.6,-6.6 2.86,-6.6 0,-3.63 0,0" /></g><g
transform="translate(104.9547,86.8013)"
id="g28"><path
id="path30"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 34.65 c 0,3.63 2.97,6.6 6.6,6.6 3.629,0 6.6,-2.97 6.6,-6.6 V 2.86 c 0,-8.47 3.409,-11.44 9.57,-11.44 4.73,0 9.24,2.86 11.33,4.95 v 38.28 c 0,3.63 2.97,6.6 6.6,6.6 3.63,0 6.6,-2.97 6.6,-6.6 v -50.16 c 0,-3.3 -2.53,-5.83 -5.72,-5.83 -2.97,0 -5.06,2.09 -5.72,4.95 l -0.55,2.42 C 32.12,-17.16 26.18,-21.34 18.149,-21.34 5.06,-21.34 0,-11.99 0,0" /></g><g
transform="translate(197.5084,90.4312)"
id="g32"><path
id="path34"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 12.65 c 0,8.47 -2.971,12.54 -10.341,12.54 -4.069,0 -8.029,-2.2 -10.559,-4.839 V -7.59 c 2.53,-2.639 6.49,-4.95 10.559,-4.95 C -2.971,-12.54 0,-8.47 0,0 m -34.101,-19.14 v 71.83 c 0,3.63 2.861,6.601 6.6,6.601 3.74,0 6.601,-2.971 6.601,-6.601 V 31.57 c 3.08,3.191 8.359,6.05 14.299,6.05 13.09,0 19.8,-8.8 19.8,-23.54 V -1.319 c 0,-14.741 -6.819,-23.651 -20.13,-23.651 -6.16,0 -11.88,2.97 -14.96,6.491 l -0.66,-2.201 c -0.769,-2.53 -3.08,-4.29 -5.72,-4.29 -3.299,0 -5.83,2.75 -5.83,5.83" /></g><g
transform="translate(251.7047,102.311)"
id="g36"><path
id="path38"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,9.57 -1.87,14.301 -9.9,14.301 -7.92,0 -9.9,-4.181 -9.9,-14.301 z M -33,-15.069 V 2.2 c 0,14.521 7.479,23.54 23.1,23.54 15.95,0 22.77,-8.689 22.77,-23.54 v -7.37 c 0,-2.859 -2.309,-5.17 -5.17,-5.17 h -27.5 v -5.939 c 0,-4.62 2.86,-9.13 10.89,-9.13 5.72,0 8.8,0.88 13.09,2.97 0.66,0.33 1.54,0.66 2.42,0.66 2.97,0 5.39,-2.42 5.39,-5.391 0,-2.309 -1.429,-3.96 -3.52,-5.17 -5.17,-2.97 -10.23,-4.51 -17.93,-4.51 -15.73,0 -23.54,8.25 -23.54,21.781" /></g><g
transform="translate(271.7564,99.4517)"
id="g40"><path
id="path42"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,3.3 2.53,5.83 5.721,5.83 h 19.91 c 3.3,0 5.83,-2.53 5.83,-5.83 0,-3.19 -2.53,-5.72 -5.83,-5.72 H 5.721 C 2.53,-5.72 0,-3.19 0,0" /></g><g
transform="translate(345.776,90.4312)"
id="g44"><path
id="path46"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 12.65 c 0,8.47 -2.971,12.54 -10.341,12.54 -4.069,0 -8.029,-2.2 -10.559,-4.839 V -7.59 c 2.53,-2.639 6.49,-4.95 10.559,-4.95 C -2.971,-12.54 0,-8.47 0,0 m -34.101,-19.14 v 71.83 c 0,3.63 2.861,6.601 6.6,6.601 3.74,0 6.601,-2.971 6.601,-6.601 V 31.57 c 3.08,3.191 8.359,6.05 14.299,6.05 13.09,0 19.8,-8.8 19.8,-23.54 V -1.319 c 0,-14.741 -6.819,-23.651 -20.13,-23.651 -6.16,0 -11.88,2.97 -14.96,6.491 l -0.66,-2.201 c -0.769,-2.53 -3.08,-4.29 -5.72,-4.29 -3.299,0 -5.83,2.75 -5.83,5.83" /></g><g
transform="translate(399.9723,102.311)"
id="g48"><path
id="path50"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,9.57 -1.87,14.301 -9.9,14.301 -7.92,0 -9.9,-4.181 -9.9,-14.301 z M -33,-15.069 V 2.2 c 0,14.521 7.479,23.54 23.1,23.54 15.95,0 22.77,-8.689 22.77,-23.54 v -7.37 c 0,-2.859 -2.309,-5.17 -5.17,-5.17 h -27.5 v -5.939 c 0,-4.62 2.86,-9.13 10.89,-9.13 5.72,0 8.8,0.88 13.09,2.97 0.66,0.33 1.54,0.66 2.42,0.66 2.97,0 5.39,-2.42 5.39,-5.391 0,-2.309 -1.429,-3.96 -3.52,-5.17 -5.17,-2.97 -10.23,-4.51 -17.93,-4.51 -15.73,0 -23.54,8.25 -23.54,21.781" /></g><g
transform="translate(421.8512,72.061)"
id="g52"><path
id="path54"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 50.16 c 0,3.301 2.53,5.83 5.72,5.83 2.97,0 5.06,-2.09 5.72,-4.949 l 0.55,-2.421 c 3.19,3.191 9.13,7.37 17.16,7.37 13.09,0 18.15,-9.349 18.15,-21.34 V 0 c 0,-3.63 -2.97,-6.6 -6.6,-6.6 -3.63,0 -6.599,2.97 -6.599,6.6 v 31.79 c 0,8.471 -3.411,11.44 -9.571,11.44 -4.73,0 -9.24,-2.86 -11.33,-4.95 L 13.2,0 C 13.2,-3.63 10.23,-6.6 6.6,-6.6 2.97,-6.6 0,-3.63 0,0" /></g><g
transform="translate(478.358,89.1118)"
id="g56"><path
id="path58"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 15.29 c 0,14.52 8.36,23.649 24.31,23.649 8.36,0 14.08,-3.08 18.15,-8.029 1.21,-1.54 1.87,-2.75 1.87,-4.511 0,-3.299 -2.53,-5.83 -5.83,-5.83 -1.76,0 -3.08,0.66 -4.4,1.981 -2.75,2.75 -5.39,4.62 -9.79,4.62 -8.69,0 -11.11,-5.83 -11.11,-12.981 L 13.2,1.1 c 0,-7.151 2.75,-12.981 11.44,-12.981 4.4,0 7.04,1.87 9.79,4.62 1.32,1.321 2.31,1.981 4.29,1.981 3.3,0 5.94,-2.531 5.94,-5.83 0,-1.76 -0.66,-2.97 -1.87,-4.51 C 38.72,-20.57 33,-23.65 24.64,-23.65 8.689,-23.65 0,-14.521 0,0" /></g><g
transform="translate(530.5396,72.061)"
id="g60"><path
id="path62"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 71.061 c 0,3.629 2.86,6.6 6.6,6.6 3.74,0 6.6,-2.971 6.6,-6.6 v -21.34 c 3.41,2.969 9.02,6.269 16.17,6.269 13.09,0 18.26,-9.349 18.26,-21.34 V 0 c 0,-3.63 -2.859,-6.6 -6.6,-6.6 -3.74,0 -6.6,2.97 -6.6,6.6 v 31.79 c 0,8.471 -3.52,11.44 -9.68,11.44 -4.729,0 -9.46,-2.86 -11.55,-4.95 V 0 C 13.2,-3.63 10.34,-6.6 6.6,-6.6 2.86,-6.6 0,-3.63 0,0" /></g><g
transform="translate(249.2096,192.0259)"
id="g64"><path
id="path66"
style="fill:#f1df36;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h 0.008 l 131.211,0.031 h 0.013 c 3.063,0 6.107,0.66 8.916,1.863 L 65.602,49.549 -8.531,1.7 C -5.83,0.6 -2.923,0 0,0" /></g><g
transform="translate(420.2877,374.9341)"
id="g68"><path
id="path70"
style="fill:#faaf42;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 -105.477,-133.359 74.547,-47.655 c 3.392,1.452 6.439,3.697 8.747,6.559 l 75.104,93.431 6.686,8.317 c 1.38,1.714 2.479,3.637 3.289,5.675 0.384,0.965 0.701,1.954 0.95,2.962 z" /></g><g
transform="translate(145.3785,311.2251)"
id="g72"><path
id="path74"
style="fill:#faaf42;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0.583,-2.568 1.609,-5.036 3.054,-7.245 0.401,-0.614 0.83,-1.209 1.285,-1.783 l 81.823,-101.735 c 2.396,-2.975 5.588,-5.289 9.138,-6.736 L 169.433,-69.65 62.648,65.424 Z" /></g><g
transform="translate(179.4977,457.7324)"
id="g76"><path
id="path78"
style="fill:#9ad7ec;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -2.408,-2.762 -4.144,-6.1 -4.985,-9.762 l -29.149,-126.8 c -0.65,-2.826 -0.715,-5.774 -0.239,-8.633 0.073,-0.44 0.155,-0.878 0.254,-1.312 l 62.648,65.424 z" /></g><g
transform="translate(484.1334,310.8643)"
id="g80"><path
id="path82"
style="fill:#9ad7ec;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 0.837,3.378 0.913,6.943 0.131,10.337 L -29.076,137.21 c -0.791,3.437 -2.374,6.586 -4.566,9.236 L -63.846,64.07 Z" /></g><g
transform="translate(317.7506,366.4487)"
id="g84"><path
id="path86"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 40.622,41.329 H 14.038 L -18.791,6.272 V 77.598 H -39.47 V -56.101 h 20.679 v 40.069 l 3.269,3.181 33.46,-43.25 h 27.03 z" /></g><g
transform="translate(275.7818,468.8486)"
id="g88"><path
id="path90"
style="fill:#1280c4;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 39.028,53.109 c -0.01,0 -0.022,10e-4 -0.033,10e-4 -0.047,0 -0.094,-0.003 -0.141,-0.003 C 38.521,53.105 38.187,53.099 37.853,53.082 37.814,53.08 37.776,53.072 37.738,53.07 34.783,52.909 31.86,52.166 29.192,50.889 L -89.022,-5.593 c -2.809,-1.342 -5.266,-3.235 -7.262,-5.523 L -67.755,-92.199 0,0.03 Z" /></g><g
transform="translate(442.8853,463.2578)"
id="g92"><path
id="path94"
style="fill:#1280c4;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 -118.288,56.48 c -3.039,1.455 -6.412,2.215 -9.785,2.22 L -22.598,-88.324 7.606,-5.947 C 5.558,-3.467 2.978,-1.422 0,0" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 10 KiB