Compare commits

...

201 Commits

Author SHA1 Message Date
Liz Rice
277ec9c823 Merge pull request #163 from noqcks/master
Update tests for Kubernetes 1.11 - thank you @noqcks!
2018-10-13 22:09:24 +01:00
Abubakr-Sadik Nii Nai Davis
b1369832bc A few corrections to node tests. (#2)
* Add a few corrections.

* Add a few corrections to node test file.
2018-10-13 15:48:50 -04:00
Abubakr-Sadik Nii Nai Davis
934b4aef96 Add a few corrections. (#1) 2018-10-12 10:22:08 -04:00
noqcks
e85de9e8af fix simple errors 2018-10-09 19:16:08 -04:00
noqcks
ded5aff482 update README 2018-10-09 18:58:30 -04:00
noqcks
b3a115963b adding 1.11 config and node checks 2018-10-09 18:57:37 -04:00
noqcks
e5c05a97f7 updating README with 1.11 updates 2018-10-09 18:56:48 -04:00
noqcks
ba5ec8d4be adding 1.11 master configuration 2018-10-09 18:34:52 -04:00
Liz Rice
d56afd4104 Merge pull request #159 from lukebond/master
Update README.md
2018-09-04 08:37:04 +01:00
Luke Bond
8894b1dc4f Update README.md
Specify `-t` to get colour in the Docker output.
Added a note about mounting kubectl or kubelet to get the version.
2018-09-03 23:05:48 +01:00
Liz Rice
ff59938f94 Merge pull request #155 from bvwells/cis-benchmark-link
Add link to CIS kubernetes benchmark
2018-08-20 09:14:37 +01:00
bvwells
cc43fcbb7e Add link to CIS kubernetes benchmark 2018-08-10 20:55:02 +01:00
Liz Rice
2f4f55a363 Merge pull request #149 from aquasecurity/itai_cis_results
Support actual result in json output.
2018-07-31 18:18:51 +01:00
Itai Ben-Natan
e9076233dd Support actual result in json output.
This commit adds the actual value of the result
of the value which was returned by the test.
2018-07-30 14:19:18 +00:00
Liz Rice
b1e41d345f Merge pull request #147 from aquasecurity/version-fix
Shouldn't need kubelet or kubectl if version specified
2018-07-28 14:53:56 +01:00
Liz Rice
ccc2b6c9ae Shouldn't need kubelet or kubectl if version specified 2018-07-26 12:03:09 +01:00
Liz Rice
668a9e10ce Merge pull request #141 from aquasecurity/version-default
Default version
2018-07-02 15:36:31 +01:00
Liz Rice
8c3bb62dd4 Merge pull request #140 from aquasecurity/manifest-extension
Inlcude .manifest extension config files for kops & kubespray
2018-07-02 15:34:49 +01:00
Liz Rice
9d0141871a Use new utility function for finding correct config files.
Improve order of message output
Remove unnecessary local variable
2018-06-29 12:20:29 +01:00
Liz Rice
344d2bfd24 Utility for getting the right config file for the Kubernetes version 2018-06-29 12:19:34 +01:00
Liz Rice
ecd14ed682 File substitutions should be a detailed log 2018-06-29 12:19:00 +01:00
Liz Rice
223ac14642 Don't override version specified on command line 2018-06-29 10:35:44 +01:00
Liz Rice
c44e0db97b Inlcude .manifest extension config files for kops & kubespray 2018-06-29 10:24:09 +01:00
Liz Rice
0bc004468b Include .manifest extensions as an option for config files (as used by kops and kubespreay) 2018-06-29 10:23:06 +01:00
Liz Rice
83704a7d89 Merge pull request #134 from hutr/master
fix grep string for check 1.4.11 and 1.4.12
2018-06-18 08:44:13 -07:00
Liz Rice
024b7ed396 Merge branch 'master' into master 2018-06-18 08:30:24 -07:00
Liz Rice
c5e04677cf Merge pull request #138 from jgsqware/patch-1
Rule node 2.2.4 is not correct
2018-06-18 08:28:38 -07:00
Julien Garcia Gonzalez
2073e08363 update 2.2.4 rules 2018-06-18 13:44:25 +02:00
Julien Garcia Gonzalez
db096c9f51 Rule node 2.2.4 is not correct 2018-06-15 15:49:55 +02:00
hutr
d736d10f90 fix sed string for 1.4.12 2018-06-07 16:34:03 +02:00
hutr
50a3725ff2 Merge branch 'master' into master 2018-06-07 16:12:04 +02:00
hutr
468f5fac6e changes for 1.4.11 and 1.4.2
added tests: for 1.4.11 and removed grep -v grep for both
2018-06-07 16:08:43 +02:00
Liz Rice
3408e0f865 Merge pull request #135 from mirwan/node_2.2.6_audit_field
Addition of missing audit field in 2.2.6 node item
2018-06-07 13:33:50 +01:00
Erwan Miran
182e9b5e01 Addition of missing audit field in 2.2.6 node item 2018-06-05 15:27:20 +02:00
hutr
e4100a4435 fixed grep string for 1.4.11 and 1.4.22
check 1.4.11 and 1.4.22 FAIL even when permissions is correct.
2018-05-28 15:39:07 +02:00
Liz Rice
b502d09f8b Merge pull request #132 from wmedlar/issue-116
Migrate dependency management to dep
2018-05-18 10:03:47 +01:00
Will Medlar
6c7422a938 Migrate dependency management to dep 2018-05-16 18:16:41 -05:00
Liz Rice
82b1e05a32 Merge pull request #131 from philalex/fixBooleansComparaison-issue125
Fix booleans comparaison issue125
2018-05-15 11:57:44 +01:00
Liz Rice
97e5bc9b97 Merge branch 'master' into fixBooleansComparaison-issue125 2018-05-15 11:42:21 +01:00
Liz Rice
c0d80b4669 Merge pull request #130 from aquasecurity/fix-typo
A bunch of text edits
2018-05-15 11:41:51 +01:00
Philippe ALEXANDRE
7b61cf60fe Add strings.ToLower ... 2018-05-15 11:52:49 +02:00
Philippe ALEXANDRE
c4e7487ba7 Do case insensitive comparaison for booleans - Fix #125 2018-05-15 11:48:49 +02:00
Abubakr-Sadik Nii Nai Davis
6d237607fb Fix typo in help text. 2018-05-15 04:50:39 +00:00
Abubakr-Sadik Nii Nai Davis
b4b3ebe99c Add instruction for running kube-bench against a kubernetes cluster.
#218
2018-05-15 04:40:41 +00:00
Abubakr-Sadik Nii Nai Davis
609335510a Remove kube-bench --help output.
It has grown stale and no longer reflects the supported options, and can be misleading (see #127).
2018-05-15 04:24:33 +00:00
Abubakr-Sadik Nii Nai Davis
5da707b8d6 Remove CIS benchmark version in tool title.
it has grown stale and is dependent on k8s version we are checking.
2018-05-15 04:23:39 +00:00
Abubakr-Sadik Nii Nai Davis
b10b2bd22e Merge branch 'master' into fix-typo 2018-05-15 04:09:27 +00:00
Abubakr-Sadik Nii Nai Davis
aa9da13226 Fix a bunch of typos. 2018-05-15 04:08:44 +00:00
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
Liz Rice
22e46990db Merge pull request #81 from jaxxstorm/u/jaxxstorm/deps
Add glide dependencies
2018-01-11 18:47:52 +02:00
Lee Briggs
216b1d497a Fix glide install instructions 2018-01-11 08:23:46 -08:00
Lee Briggs
033ab5638c Add glide dependencies
Also update build from source instructions
2018-01-09 12:54:18 -08:00
Liz Rice
94b960cfad Merge pull request #75 from nuwaida/master
Result structure changes
2017-11-29 18:40:37 +00:00
nazemu
017a9836ce Result structure changes
Changes to the json structure and field names
2017-11-29 19:04:05 +02:00
Liz Rice
a863cf87ca Merge pull request #74 from aquasecurity/multistage
Multistage build
2017-11-29 11:30:22 +00: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
Liz Rice
7b538ed6e4 Multistage build 2017-11-27 11:51:20 +00:00
Liz Rice
778c662055 Merge pull request #69 from aquasecurity/fix-kubeversion-fail
Exit kube-bench if we can't get valid kubernetes server version
2017-11-21 13:25:11 +00:00
Liz Rice
97485419e2 Can't run kubectl on Travis so I don't know how this test ever worked 2017-11-21 13:21:47 +00:00
Liz Rice
730871f330 Fix kubeVersion regex tests 2017-11-21 13:19:09 +00:00
Abubakr-Sadik Nii Nai Davis
471c02f4d7 Merge branch 'fix-kubeversion-fail' of github.com:aquasecurity/kube-bench into fix-kubeversion-fail 2017-11-21 12:20:22 +00:00
Abubakr-Sadik Nii Nai Davis
c93c94b3f6 Fix version check regexp. 2017-11-21 12:20:02 +00:00
Liz Rice
1d7df75f57 Merge branch 'master' into fix-kubeversion-fail 2017-11-16 10:00:46 +02:00
Abubakr-Sadik Nii Nai Davis
c60c459bc4 Fix bug causing kubectl version to always return default version. 2017-11-14 22:27:55 +00:00
Liz Rice
4907843b7b Merge pull request #71 from aquasecurity/lizrice-patch-2
Correct test config file typo
2017-11-14 18:12:25 +02:00
Liz Rice
d52e326147 Correct test config file typo 2017-11-14 18:05:40 +02:00
Abubakr-Sadik Nii Nai Davis
42a1068964 Add default version if version check fails. 2017-11-13 15:25:34 +00:00
Abubakr-Sadik Nii Nai Davis
f90dd925b8 Exit kube-bench if we can't get valid kubernetes server version and
improve error messages.
2017-11-03 13:11:10 +00:00
Abubakr-Sadik Nii Nai Davis
31b5910a7f Remove unnecessary warnings about missing config files. 2017-11-03 10:41:01 +00:00
Liz Rice
85fb818e41 Merge pull request #67 from aquasecurity/config-spacing
Remove odd spacing and line breaks from test config files
2017-11-02 11:14:03 +00:00
Liz Rice
2eb261b94f Remove odd spacing and line breaks from test config files 2017-11-02 09:51:03 +00:00
Liz Rice
732b987d6d Merge pull request #61 from bitvector2/master
added saving results to PostgreSQL DB as a JSONB document
2017-11-02 08:34:13 +00:00
Steven Logue
909e6cc874 created database.go file and moved DB function into it 2017-11-01 10:15:31 -07:00
Liz Rice
1b13375ff7 Merge branch 'master' into master 2017-11-01 15:06:40 +00:00
Liz Rice
bdb5ccf982 Merge pull request #64 from aquasecurity/lizrice-patch-1
Update README for Kubernetes 1.8 support
2017-11-01 15:06:20 +00:00
Liz Rice
83e58b86db Update README for Kubernetes 1.8 support 2017-11-01 15:04:25 +00:00
Liz Rice
1faeb55b67 Merge branch 'master' into master 2017-11-01 14:46:48 +00:00
Steven Logue
f7d4f03f48 fixed typo in makefile 2017-10-31 13:12:20 -07:00
Steven Logue
d79a2a5478 added support for saving scan results to pgsql 2017-10-31 13:08:46 -07:00
Liz Rice
7f5504413e Merge pull request #60 from aquasecurity/lizrice-patch-1
Remove reference to specific benchmark version
2017-10-26 16:14:56 -04:00
Liz Rice
478e378752 Remove reference to specific benchmark version
We support multiple versions of the CIS benchmark
2017-10-26 16:12:36 -04:00
Liz Rice
2a269fb974 Merge pull request #59 from aquasecurity/k8s-1.8-support
Add kubernetes 1.8 support
2017-10-24 22:19:13 +01:00
Abubakr-Sadik Nii Nai Davis
3dcc38d5c8 Fix issue with util test. 2017-10-24 12:45:38 +00:00
Abubakr-Sadik Nii Nai Davis
592dc81974 Remove unused variables. 2017-10-24 12:02:22 +00:00
Abubakr-Sadik Nii Nai Davis
cec1d9d6b3 Combine config reading functions into single function. 2017-10-24 12:01:02 +00:00
Abubakr-Sadik Nii Nai Davis
e227934c88 Add function to get unit files for kubernetes components. 2017-10-15 13:20:01 +00:00
Abubakr-Sadik Nii Nai Davis
6ce0c5bf60 Add function to get pod specs for kubernetes components. 2017-10-15 13:19:57 +00:00
Abubakr-Sadik Nii Nai Davis
8e758bb5e0 Update federated definitions. 2017-10-15 13:19:13 +00:00
Abubakr-Sadik Nii Nai Davis
82e325f96e Update 1.8 node definition. 2017-10-15 13:19:07 +00:00
Abubakr-Sadik Nii Nai Davis
04f21d1887 Update 1.8 master definition. 2017-10-15 13:17:45 +00:00
Abubakr-Sadik Nii Nai Davis
7663dc87ee Copy 1.7 benchmark as 1.8. 2017-10-05 17:29:38 +00:00
Liz Rice
7435a8db38 Merge pull request #57 from aquasecurity/dockerfile
Dockerfile fix to copy all the cfg files
2017-10-02 12:00:28 +01:00
Liz Rice
b98dfbc718 Dockerfile fix to copy all the cfg files 2017-10-02 06:38:45 -04:00
Liz Rice
9b121de50a Merge pull request #55 from aquasecurity/client-server-error-message-on-1.6
Client server error message on 1.6
2017-09-27 15:06:48 +01:00
Abubakr-Sadik Nii Nai Davis
018ad12a64 Log benchmark definition file at verbosity level 1. 2017-09-26 23:33:47 +00:00
Abubakr-Sadik Nii Nai Davis
73a37a0c16 Delete tests for verifyKubeVersion and support functions. 2017-09-26 23:24:44 +00:00
Abubakr-Sadik Nii Nai Davis
88a003090f Delete verifyKubeVersion support functions. 2017-09-26 23:23:34 +00:00
Abubakr-Sadik Nii Nai Davis
a95d083049 Remove call to verifyKubeVersion.
This functionality is fulfilled by getKubeVersion.
2017-09-26 23:20:28 +00:00
Liz Rice
d01faef457 Merge pull request #52 from ttousai/new-auto-detect
Support multiple kubernetes version
2017-09-21 09:30:34 -05:00
Abubakr-Sadik Nii Nai Davis
d9e1eee2cd Merge remote-tracking branch 'origin/master' into support for multiple
Kubernetes versions.
2017-09-20 00:39:30 +00:00
Abubakr-Sadik Nii Nai Davis
56fa20103a Add function to retrieve Kubernetes server version.
The server version is used to load the correct benchmark check
to run against the Kubernetes cluster.
2017-09-17 19:49:13 +00:00
Abubakr-Sadik Nii Nai Davis
8ea0892437 Update controls to support multiple Kubernetes versions. 2017-09-17 00:09:02 +00:00
Abubakr-Sadik Nii Nai Davis
f2e744bdcb Reorganize benchmark checks into Kubernetes 1.7 and restore Kubernetes 1.6 benchmarks. 2017-09-15 19:38:09 +00:00
Liz Rice
95bb80b7db Merge pull request #51 from aquasecurity/add-test
Add tests for #50
2017-09-15 15:11:10 +01:00
Liz Rice
e8579ade6c Add tests for #50 2017-09-13 15:32:33 +01:00
Liz Rice
a6d4f2fb59 Merge pull request #50 from junaid18183/master
Fixed issue admission control showing wrong status
2017-09-13 15:29:16 +01:00
Juned Memon
44994ced33 Fixed issue of The controls for master - admission control showing wrong status #49 2017-09-13 04:31:43 +05:30
Liz Rice
883b963e21 Merge pull request #48 from aquasecurity/auto-detect
Update README for auto-detection of executables and config files
2017-09-04 10:25:53 +01:00
Liz Rice
9a500229a4 Update README for auto-detection of executables and config files 2017-09-04 10:11:34 +01:00
Liz Rice
516343eb06 Merge pull request #47 from aquasecurity/auto-detect
Auto-detect executables and config files
2017-09-04 10:00:24 +01:00
Liz Rice
c4be4a1240 Remove installation flag and some other unused variables 2017-08-31 17:52:21 +01:00
Liz Rice
de12829923 Correct test to cope with multi-line ps output 2017-08-31 17:43:07 +01:00
Liz Rice
a6036bcfcf Corrections to config file substitutions. Use “kubernetes” as a fake component name so we can more easily substitute “kubernetesconf” 2017-08-31 17:39:48 +01:00
Liz Rice
e4a89123e0 Move message about which config file we’re using into a log at the start 2017-08-31 17:38:11 +01:00
Liz Rice
8380ad1ef3 Better detection of running executables 2017-08-31 16:01:31 +01:00
Liz Rice
d637d8714a Fix and add tests 2017-08-31 15:22:30 +01:00
Liz Rice
a3197f8efe Reorder YAML to make a bit more sense. Allow for optional components, and a config file that we don’t think exists. 2017-08-31 14:45:16 +01:00
Liz Rice
e4b905e360 Log when there’s no substitution 2017-08-31 14:43:59 +01:00
Liz Rice
f5550fd8bd Node type is now verified by looking for running binaries from a set of options 2017-08-31 14:43:35 +01:00
Liz Rice
0e9c11ebd5 Remove empty error messages that manifested as "%s" 2017-08-31 14:41:52 +01:00
Liz Rice
6a5a62b278 Autodetect the binaries and config files from a set of options 2017-08-30 18:37:01 +01:00
Liz Rice
e4e41683c4 Update the config file 2017-08-30 18:36:00 +01:00
Liz Rice
f5cef922cc Functions and tests for finding binaries and config files 2017-08-30 18:01:53 +01:00
Liz Rice
7600dd9dd6 Make the ps / fakeps function global so we don’t have to pass it around so much 2017-08-30 17:51:28 +01:00
Liz Rice
0bc00e0036 Slightly more robust looking for running executables 2017-08-30 17:48:12 +01:00
Liz Rice
9114e139cf Function to find which of a set of executables is running 2017-08-30 12:07:46 +01:00
Liz Rice
89e9d37cde Merge pull request #43 from aquasecurity/issue-42
Change node check 2.1.6 to use operation `noteq` instead of `gt`.
2017-08-25 11:13:11 +01:00
Abubakr-Sadik Nii Nai Davis
3e3aa0ed82 Change node check 2.1.6 to use operation noteq instead of gt.
Kubelet option --streaming-connection-idle-timeout expects a string
value which fails parsing to integer for greater than comparison.

The string "0" indicates no timeout and this is what we are checking
for.
2017-08-24 18:33:32 +00:00
39 changed files with 7137 additions and 511 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
kube-bench
*.swp
vendor
dist

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,33 @@
---
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/golang/dep/cmd/dep
- dep ensure -v -vendor-only
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,16 +1,22 @@
FROM golang:1.8
WORKDIR /kube-bench
RUN go get github.com/aquasecurity/kube-bench
RUN cp /go/bin/kube-bench /kube-bench/ && chmod +x /kube-bench/kube-bench
WORKDIR /kube-bench/cfg
RUN wget https://raw.githubusercontent.com/aquasecurity/kube-bench/master/cfg/config.yaml && \
wget https://raw.githubusercontent.com/aquasecurity/kube-bench/master/cfg/federated.yaml && \
wget https://raw.githubusercontent.com/aquasecurity/kube-bench/master/cfg/master.yaml && \
wget https://raw.githubusercontent.com/aquasecurity/kube-bench/master/cfg/node.yaml
# When Docker Hub supports it, we would split this into a multi-stage build with the second part based on, say, alpine for size
WORKDIR /
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
FROM golang:1.9 AS build
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
ADD Gopkg.toml Gopkg.lock ./
RUN go get -v github.com/golang/dep/cmd/dep && dep ensure -v -vendor-only
ADD main.go .
ADD check/ check/
ADD cmd/ cmd/
RUN CGO_ENABLED=0 go install -a -ldflags '-w'
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

153
Gopkg.lock generated Normal file
View File

@@ -0,0 +1,153 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/fatih/color"
packages = ["."]
revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260"
version = "v1.5.0"
[[projects]]
name = "github.com/fsnotify/fsnotify"
packages = ["."]
revision = "4da3e2cfbabc9f751898f250b49f2439785783a1"
[[projects]]
branch = "master"
name = "github.com/golang/glog"
packages = ["."]
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
[[projects]]
name = "github.com/hashicorp/hcl"
packages = [
".",
"hcl/ast",
"hcl/parser",
"hcl/scanner",
"hcl/strconv",
"hcl/token",
"json/parser",
"json/scanner",
"json/token"
]
revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8"
[[projects]]
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
name = "github.com/jinzhu/gorm"
packages = [
".",
"dialects/postgres"
]
revision = "5174cc5c242a728b435ea2be8a2f7f998e15429b"
version = "v1.0"
[[projects]]
name = "github.com/jinzhu/inflection"
packages = ["."]
revision = "1c35d901db3da928c72a72d8458480cc9ade058f"
[[projects]]
name = "github.com/lib/pq"
packages = [
".",
"hstore",
"oid"
]
revision = "83612a56d3dd153a94a629cd64925371c9adad78"
[[projects]]
name = "github.com/magiconair/properties"
packages = ["."]
revision = "49d762b9817ba1c2e9d0c69183c2b4a8b8f1d934"
[[projects]]
name = "github.com/mattn/go-colorable"
packages = ["."]
revision = "5411d3eea5978e6cdc258b30de592b60df6aba96"
[[projects]]
name = "github.com/mattn/go-isatty"
packages = ["."]
revision = "57fdcb988a5c543893cc61bce354a6e24ab70022"
[[projects]]
name = "github.com/mitchellh/mapstructure"
packages = ["."]
revision = "06020f85339e21b2478f756a78e295255ffa4d6a"
[[projects]]
name = "github.com/pelletier/go-toml"
packages = ["."]
revision = "0131db6d737cfbbfb678f8b7d92e55e27ce46224"
[[projects]]
name = "github.com/spf13/afero"
packages = [
".",
"mem"
]
revision = "57afd63c68602b63ed976de00dd066ccb3c319db"
[[projects]]
name = "github.com/spf13/cast"
packages = ["."]
revision = "acbeb36b902d72a7a4c18e8f3241075e7ab763e4"
version = "v1.1.0"
[[projects]]
name = "github.com/spf13/cobra"
packages = ["."]
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
version = "v0.0.1"
[[projects]]
name = "github.com/spf13/jwalterweatherman"
packages = ["."]
revision = "12bd96e66386c1960ab0f74ced1362f66f552f7b"
[[projects]]
name = "github.com/spf13/pflag"
packages = ["."]
revision = "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
[[projects]]
name = "github.com/spf13/viper"
packages = ["."]
revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7"
version = "v1.0.0"
[[projects]]
name = "golang.org/x/sys"
packages = ["unix"]
revision = "e24f485414aeafb646f6fca458b0bf869c0880a1"
[[projects]]
name = "golang.org/x/text"
packages = [
"internal/gen",
"internal/triegen",
"internal/ucd",
"transform",
"unicode/cldr",
"unicode/norm"
]
revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3"
[[projects]]
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "c95af922eae69f190717a0b7148960af8c55a072"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "8d9a1b665b338530deef434f168913ba1184f835aa5bfed3a213a14c613bc17e"
solver-name = "gps-cdcl"
solver-version = 1

23
Gopkg.toml Normal file
View File

@@ -0,0 +1,23 @@
[[constraint]]
name = "github.com/fatih/color"
version = "1.5.0"
[[constraint]]
branch = "master"
name = "github.com/golang/glog"
[[constraint]]
name = "github.com/jinzhu/gorm"
version = "1.0.0"
[[constraint]]
name = "github.com/spf13/cobra"
version = "0.0.1"
[[constraint]]
name = "github.com/spf13/viper"
version = "1.0.0"
[prune]
go-tests = true
unused-packages = true

103
README.md
View File

@@ -3,51 +3,92 @@
[![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 1.6 Benchmark v1.0.0.
kube-bench is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/).
Tests are configured with YAML files, making this tool easy to update as test specifications evolve.
Tests are configured with YAML files, making this tool easy to update as test specifications evolve.
![Kubernetes Bench for Security](https://raw.githubusercontent.com/aquasecurity/kube-bench/master/images/output.png "Kubernetes Bench for Security")
## CIS Kubernetes Benchmark support
kube-bench supports the tests for multiple versions of Kubernetes (1.6, 1.7, 1.8, and 1.11) as defined in the CIS Benchmarks 1.0.0, 1.1.0, 1.2.0, and 1.30 respectively. It will determine the test set to run based on the Kubernetes version running on the machine.
## 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
2. Install from sources:
If Go is installed on the target machines, you can simply clone this repository and run as follows:
```go get github.com/aquasecurity/kube-bench```
```cp $GOROOT/bin/kube-bench .```
```./kube-bench <master|node>```
## Usage
```./kube-bench [command]```
You can avoid installing kube-bench on the host by running it inside a container using the host PID namespace.
```
Available Commands:
federated Run benchmark checks for a Kubernetes federated deployment.
help Help about any command
master Run benchmark checks for a Kubernetes master node.
node Run benchmark checks for a Kubernetes node.
docker run --pid=host -t 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 -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yaml aquasec/kube-bench:latest <master|node>
```
> Note: the tests require either the kubelet or kubectl binary in the path in order to know the Kubernetes version. You can pass `-v $(which kubectl):/usr/bin/kubectl` to the above invocations to resolve this.
### Running in a kubernetes cluster
Run the master check
```
kubectl run --rm -i -t kube-bench-master --image=aquasec/kube-bench:latest --restart=Never --overrides="{ \"apiVersion\": \"v1\", \"spec\": { \"hostPID\": true, \"nodeSelector\": { \"kubernetes.io/role\": \"master\" }, \"tolerations\": [ { \"key\": \"node-role.kubernetes.io/master\", \"operator\": \"Exists\", \"effect\": \"NoSchedule\" } ] } }" -- master --version 1.11
```
Run the node check
```
kubectl run --rm -i -t kube-bench-node --image=aquasec/kube-bench:latest --restart=Never --overrides="{ \"apiVersion\": \"v1\", \"spec\": { \"hostPID\": true } }" -- node --version 1.11
```
### 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
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)):
```shell
go get github.com/aquasecurity/kube-bench
go get github.com/golang/dep/cmd/dep
cd $GOPATH/src/github.com/aquasecurity/kube-bench
$GOPATH/bin/dep ensure -vendor-only
go build -o kube-bench .
# See all supported options
./kube-bench --help
# Run the all checks on a master node
./kube-bench master
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)
```
## Configuration
Kubernetes config and binary file locations and names can vary from installation to installation, so these are configurable in the `cfg/config.yaml` file.
Kubernetes config and binary file locations and names can vary from installation to installation, so these are configurable in the `cfg/config.yaml` file.
They also tend to vary according to which tool was used to install Kubernetes. You can use the `--installation` flag to pick up a different default set of file names and locations. Again these defaults are configurable through `cfg/config.yaml` (and pull requests to correct or add default file locations are especially welcome).
For each type of node (*master*, *node* or *federated*) there is a list of components, and for each component there is a set of binaries (*bins*) and config files (*confs*) that kube-bench will look for (in the order they are listed). If your installation uses a different binary name or config file location for a Kubernetes component, you can add it to `cfg/config.yaml`.
* **bins** - If there is a *bins* list for a component, at least one of these binaries must be running. The tests will consider the parameters for the first binary in the list found to be running.
* **podspecs** - From version 1.2.0 of the benchmark (tests for Kubernetes 1.8), the remediation instructions were updated to assume that the configuration for several kubernetes components is defined in a pod YAML file, and podspec settings define where to look for that configuration.
* **confs** - If one of the listed config files is found, this will be considered for the test. Tests can continue even if no config file is found. If no file is found at any of the listed locations, and a *defaultconf* location is given for the component, the test will give remediation advice using the *defaultconf* location.
* **unitfiles** - From version 1.2.0 of the benchmark (tests for Kubernetes 1.8), the remediation instructions were updated to assume that kubelet configuration is defined in a service file, and this setting defines where to look for that configuration.
## Test config YAML representation
The tests are represented as YAML documents (installed by default into ./cfg).
@@ -106,5 +147,7 @@ These operations are:
- `has`: tests if the flag value contains the compared value.
- `nothave`: tests if the flag value does not contain the compared value.
# Roadmap
The tests are up-to-date with the CIS Benchmark 1.1.0, which refers to Kubernetes 1.7. Going forward we should release updates to kube-bench to reflect new releases of the Benchmark, which in turn we can anticipate being made for each new Kubernetes release.
# Roadmap
Going forward we plan to release updates to kube-bench to add support for new releases of the Benchmark, which in turn we can anticipate being made for each new Kubernetes release.
We welcome PRs and issue reports.

47
cfg/1.11/config.yaml Normal file
View File

@@ -0,0 +1,47 @@
---
## 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:
confs:
- /etc/kubernetes/manifests/kube-apiserver.yaml
- /etc/kubernetes/manifests/kube-apiserver.manifest
defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
confs:
- /etc/kubernetes/manifests/kube-scheduler.yaml
- /etc/kubernetes/manifests/kube-scheduler.manifest
defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml
controllermanager:
confs:
- /etc/kubernetes/manifests/kube-controller-manager.yaml
- /etc/kubernetes/manifests/kube-controller-manager.manifest
defaultconf: /etc/kubernetes/manifests/kube-controller-manager.yaml
etcd:
confs:
- /etc/kubernetes/manifests/etcd.yaml
- /etc/kubernetes/manifests/etcd.manifest
defaultconf: /etc/kubernetes/manifests/etcd.yaml
node:
kubelet:
confs:
- /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
- /etc/kubernetes/kubelet.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

1442
cfg/1.11/master.yaml Normal file

File diff suppressed because it is too large Load Diff

497
cfg/1.11/node.yaml Normal file
View File

@@ -0,0 +1,497 @@
---
controls:
version: 1.11
id: 2
text: "Worker Node Security Configuration"
type: "node"
groups:
- id: 2.1
text: "Kubelet"
checks:
- id: 2.1.1
text: "Ensure that the --allow-privileged argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--allow-privileged"
compare:
op: eq
value: false
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.2
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
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
$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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.3
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
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
$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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.4
text: "Ensure that the --client-ca-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--client-ca-file"
set: true
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
$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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.5
text: "Ensure that the --read-only-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--read-only-port"
compare:
op: eq
value: 0
set: true
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
$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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.6
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--streaming-connection-idle-timeout"
compare:
op: noteq
value: 0
set: true
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
$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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.7
text: "Ensure that the --protect-kernel-defaults argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--protect-kernel-defaults"
compare:
op: eq
value: true
set: true
remediation: |
If using a Kubelet config file, edit the file to set protectKernelDefaults: true .
If using command line arguments, 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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.8
text: "Ensure that the --make-iptables-util-chains argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--make-iptables-util-chains"
compare:
op: eq
value: true
set: true
remediation: |
If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true .
If using command line arguments, 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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.9
text: "Ensure that the --hostname-override argument is not set (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--hostname-override"
set: false
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.10
text: "Ensure that the --event-qps argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--event-qps"
compare:
op: eq
value: 0
set: true
remediation: |
If using a Kubelet config file, edit the file to set eventRecordQPS: 0 .
If using command line arguments, 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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.11
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
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
$kubeletconf on each worker node and
set the below parameters in KUBELET_CERTIFICATE_ARGS variable.
--tls-cert-file=<path/to/tls-certificate-file>
file=<path/to/tls-key-file>
Based on your system, restart the kubelet service. For example:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.12
text: "Ensure that the --cadvisor-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--cadvisor-port"
compare:
op: eq
value: 0
set: true
- flag: "--cadvisor-port"
set: false
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.13
text: "Ensure that the --rotate-certificates argument is not set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--rotate-certificates"
compare:
op: eq
value: true
set: true
remediation: |
If using a Kubelet config file, edit the file to add the line rotateCertificates: true.
If using command line arguments, edit the kubelet service file $kubeletconf
on each worker node and add --rotate-certificates=true argument to 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: 2.1.14
text: "Ensure that the RotateKubeletServerCertificate argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "RotateKubeletServerCertificate"
compare:
op: eq
value: true
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.15
text: "Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Not Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--tls-cipher-suites"
compare:
op: eq
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"
set: true
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
If using executable arguments, edit the kubelet service file $kubeletconf on each worker node and set the below parameter.
--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
scored: false
- id: 2.2
text: "Configuration Files"
checks:
- id: 2.2.1
text: "Ensure that the kubelet.conf file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 644 $kubeletconf
scored: true
- id: 2.2.2
text: "Ensure that the kubelet.conf file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: root:root
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $kubeletconf
scored: true
- 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 $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 755 $kubeletconf
scored: true
- id: 2.2.4
text: "Ensure that the kubelet service file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $kubeletconf
scored: true
- id: 2.2.5
text: "Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %a $proxyconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 644 $proxyconf
scored: true
- id: 2.2.6
text: "Ensure that the proxy kubeconfig file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %U:%G $proxyconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $proxyconf
scored: true
- id: 2.2.7
text: "Ensure that the certificate authorities file permissions are set to
644 or more restrictive (Scored)"
type: manual
remediation: |
Run the following command to modify the file permissions of the --client-ca-file
chmod 644 <filename>
scored: true
- id: 2.2.8
text: "Ensure that the client certificate authorities file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $ca-file; then stat -c %U:%G $ca-file; fi'"
type: manual
remediation: |
Run the following command to modify the ownership of the --client-ca-file .
chown root:root <filename>
scored: true
- id: 2.2.9
text: "Ensure that the kubelet configuration file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $/var/lib/kubelet/config.yaml; then stat -c %U:%G $/var/lib/kubelet/config.yaml; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: |
Run the following command (using the config file location identied in the Audit step)
chown root:root /etc/kubernetes/kubelet.conf
scored: true
- id: 2.2.10
text: "Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $/var/lib/kubelet/config.yaml; then stat -c %a $/var/lib/kubelet/config.yaml; fi'"
tests:
bin_op: or
test_items:
- 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 following command (using the config file location identied in the Audit step)
chmod 644 /var/lib/kubelet/config.yaml
scored: true

View File

@@ -1,5 +1,6 @@
---
controls:
version: 1.6
id: 3
text: "Federated Deployments"
type: "federated"

966
cfg/1.6/master.yaml Normal file
View File

@@ -0,0 +1,966 @@
---
controls:
version: 1.6
id: 1
text: "Master Node Security Configuration"
type: "master"
groups:
- id: 1.1
text: "API Server"
checks:
- id: 1.1.1
text: "Ensure that the --allow-privileged argument is set to false (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "allow-privileged"
compare:
op: eq
value: false
set: true
remediation: "Edit the $apiserverconf file on the master node and set
the KUBE_ALLOW_PRIV parameter to \"--allow-privileged=false\""
scored: true
- id: 1.1.2
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
remediation: "Edit the $apiserverconf file on the master node and set
the KUBE_API_ARGS parameter to \"--anonymous-auth=false\""
scored: true
- id: 1.1.3
text: "Ensure that the --basic-auth-file argument is not set (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--basic-auth-file"
set: false
remediation: "Follow the documentation and configure alternate mechanisms for
authentication. Then, edit the $apiserverconf file on the master
node and remove the \"--basic-auth-file=<filename>\" argument from the
KUBE_API_ARGS parameter."
scored: true
- id: 1.1.4
text: "Ensure that the --insecure-allow-any-token argument is not set (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-allow-any-token"
set: false
remediation: "Edit the $apiserverconf file on the master node and remove
the --insecure-allow-any-token argument from the KUBE_API_ARGS parameter."
scored: true
- id: 1.1.5
text: "Ensure that the --kubelet-https argument is set to true (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--kubelet-https"
compare:
op: eq
value: true
set: true
- flag: "--kubelet-https"
set: false
remediation: "Edit the $apiserverconf file on the master node and remove
the --kubelet-https argument from the KUBE_API_ARGS parameter."
scored: true
- id: 1.1.6
text: "Ensure that the --insecure-bind-address argument is not set (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-bind-address"
set: false
remediation: "Edit the $apiserverconf file on the master node and remove
the --insecure-bind-address argument from the KUBE_API_ADDRESS parameter."
scored: true
- id: 1.1.7
text: "Ensure that the --insecure-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-port"
compare:
op: eq
value: 0
set: true
remediation: "Edit the $apiserverconf file on the master node and set
--insecure-port=0 in the KUBE_API_PORT parameter."
scored: true
- id: 1.1.8
text: "Ensure that the --secure-port argument is not set to 0 (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--secure-port"
compare:
op: gt
value: 0
set: true
- flag: "--secure-port"
set: false
remediation: "Edit the $apiserverconf file on the master node and either
remove the --secure-port argument from the KUBE_API_ARGS parameter or set
it to a different desired port."
scored: true
- id: 1.1.9
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--profiling=false\""
scored: true
- id: 1.1.10
text: "Ensure that the --repair-malformed-updates argument is set to false (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--repair-malformed-updates"
compare:
op: eq
value: false
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--repair-malformed-updates=false\""
scored: true
- id: 1.1.11
text: "Ensure that the admission control policy is not set to AlwaysAdmit (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: nothave
value: AlwaysAdmit
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to a value that does not include AlwaysAdmit"
scored: true
- id: 1.1.12
text: "Ensure that the admission control policy is set to AlwaysPullImages (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: "AlwaysPullImages"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to \"--admission-control=...,AlwaysPullImages,...\""
scored: true
- id: 1.1.13
text: "Ensure that the admission control policy is set to DenyEscalatingExec (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: "DenyEscalatingExec"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to \"--admission-control=...,DenyEscalatingExec,...\""
scored: true
- id: 1.1.14
text: "Ensure that the admission control policy is set to SecurityContextDeny (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: "SecurityContextDeny"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to \"--admission-control=...,SecurityContextDeny,...\""
scored: true
- id: 1.1.15
text: "Ensure that the admission control policy is set to NamespaceLifecycle (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "admission-control"
compare:
op: has
value: "NamespaceLifecycle"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to \"--admission-control=NamespaceLifecycle,...\""
scored: true
- id: 1.1.16
text: "Ensure that the --audit-log-path argument is set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-path"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--audit-log-path=<filename>\""
scored: true
- id: 1.1.17
text: "Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxage"
compare:
op: gte
value: 30
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--audit-log-maxage=30\""
scored: true
- id: 1.1.18
text: "Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxbackup"
compare:
op: gte
value: 10
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--audit-log-maxbackup=10\""
scored: true
- id: 1.1.19
text: "Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxsize"
compare:
op: gte
value: 100
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--audit-log-maxsize=100\""
scored: true
- id: 1.1.20
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to values other than \"--authorization-mode=AlwaysAllow\""
scored: true
- id: 1.1.21
text: "Ensure that the --token-auth-file parameter is not set (Scored)"
audit: "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 $apiserverconf file on the master node and remove the
\"--tokenauth-file=<filename>\" argument from the KUBE_API_ARGS parameter."
scored: true
- id: 1.1.22
text: "Ensure that the --kubelet-certificate-authority argument is set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--kubelet-certificate-authority"
set: true
remediation: "Follow the Kubernetes documentation and setup the TLS connection between
the apiserver and kubelets. Then, edit the $apiserverconf file on the
master node and set the KUBE_API_ARGS parameter to
\"--kubelet-certificate-authority=<ca-string>\""
scored: true
- id: 1.1.23
text: "Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--kubelet-client-certificate"
set: true
- flag: "--kubelet-client-key"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection between the apiserver
and kubelets. Then, edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to \"--kubelet-clientcertificate=<path/to/client-certificate-file>\"
and \"--kubelet-clientkey=<path/to/client-key-file>\""
scored: true
- id: 1.1.24
text: "Ensure that the --service-account-lookup argument is set to true (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-lookup"
compare:
op: eq
value: true
set: true
remediation: "Edit the $apiserverconf file on the master node and set the KUBE_API_ARGS parameter
to \"--service-account-lookup=true\""
scored: true
- id: 1.1.25
text: "Ensure that the admission control policy is set to PodSecurityPolicy (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: "PodSecurityPolicy"
set: true
remediation: "Follow the documentation and create Pod Security Policy objects as per your environment.
Then, edit the $apiserverconf file on the master node and set the KUBE_ADMISSION_CONTROL
parameter to \"--admission-control=...,PodSecurityPolicy,...\""
scored: true
- id: 1.1.26
text: "Ensure that the --service-account-key-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-key-file"
set: true
remediation: "Edit the $apiserverconf file on the master node and set the KUBE_API_ARGS
parameter to \"--service-account-key-file=<filename>\""
scored: true
- id: 1.1.27
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Scored"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--etcd-certfile"
set: true
- flag: "--etcd-keyfile"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection between the apiserver
and etcd. Then, edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to include \"--etcd-certfile=<path/to/clientcertificate-file>\"
and \"--etcd-keyfile=<path/to/client-key-file>\""
scored: true
- id: 1.1.28
text: "Ensure that the admission control policy is set to ServiceAccount (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: "ServiceAccount"
set: true
remediation: "Follow the documentation and create ServiceAccount objects as per your environment.
Then, edit the $apiserverconf file on the master node and set the
KUBE_ADMISSION_CONTROL parameter to \"--admissioncontrol=...,ServiceAccount,...\""
scored: true
- id: 1.1.29
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the $apiserverconf file on the master node and set the KUBE_API_ARGS parameter to
include \"--tls-cert-file=<path/to/tls-certificatefile>\" and
\"--tls-private-key-file=<path/to/tls-key-file>\""
scored: true
- id: 1.1.30
text: "Ensure that the --client-ca-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--client-ca-file"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to include \"--client-ca-file=<path/to/client-ca-file>\""
scored: true
- id: 1.1.31
text: "Ensure that the --etcd-cafile argument is set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--etcd-cafile"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection between the apiserver
and etcd. Then, edit the $apiserverconf file on the master node and set the
KUBE_API_ARGS parameter to include \"--etcd-cafile=<path/to/ca-file>\""
scored: true
- id: 1.2
text: "Scheduler"
checks:
- id: 1.2.1
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $schedulerbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: "Edit the $schedulerconf file on the master node and set the KUBE_SCHEDULER_ARGS
parameter to \"--profiling=false\""
scored: true
- id: 1.3
text: "Controller Manager"
checks:
- id: 1.3.1
text: "Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--terminated-pod-gc-threshold"
set: true
remediation: "Edit the $controllermanagerconf file on the master node and set the
KUBE_CONTROLLER_MANAGER_ARGS parameter to \"--terminated-pod-gcthreshold=<appropriate-number>\""
scored: true
- id: 1.3.2
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: "Edit the $controllermanagerconf file on the master node and set the
KUBE_CONTROLLER_MANAGER_ARGS parameter to \"--profiling=false\""
scored: true
- id: 1.3.3
text: "Ensure that the --insecure-experimental-approve-all-kubelet-csrs-for-group argument is not set (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-experimental-approve-all-kubelet-csrs-for-group"
set: false
remediation: "Edit the /etc/kubernetes/controller-manager file on the master node and remove the
--insecure-experimental-approve-all-kubelet-csrs-for-group argument from the
KUBE_CONTROLLER_MANAGER_ARGS parameter."
scored: true
- id: 1.3.4
text: "Ensure that the --use-service-account-credentials argument is set"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--use-service-account-credentials"
compare:
op: eq
value: true
set: true
remediation: "Edit the $controllermanagerconf file on the master node and set the
KUBE_CONTROLLER_MANAGER_ARGS parameter to --use-service-account-credentials=true"
scored: true
- id: 1.3.5
text: "Ensure that the --service-account-private-key-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-private-key-file"
set: true
remediation: "Edit the $controllermanagerconf file on the master node and set the
KUBE_CONTROLLER_MANAGER_ARGS parameter to --service-account-private-keyfile=<filename>"
scored: true
- id: 1.3.6
text: "Ensure that the --root-ca-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--root-ca-file"
set: true
remediation: "Edit the $controllermanagerconf file on the master node and set the
KUBE_CONTROLLER_MANAGER_ARGS parameter to include --root-ca-file=<file>"
scored: true
- id: 1.4
text: "Configure Files"
checks:
- id: 1.4.1
text: "Ensure that the apiserver file permissions are set to 644 or more restrictive (Scored)"
# audit: "/bin/bash -c 'if test -e $apiserverconf; then stat -c %a $apiserverconf; fi'"
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %a $apiserverconf; fi'"
tests:
bin_op: or
test_items:
- 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.
\nFor example, chmod 644 $apiserverconf"
scored: true
- id: 1.4.2
text: "Ensure that the apiserver file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $apiserverconf"
scored: true
- id: 1.4.3
text: "Ensure that the config file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'"
tests:
bin_op: or
test_items:
- 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.
\nFor example, chmod 644 $config"
scored: true
- id: 1.4.4
text: "Ensure that the config file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %U:%G $config; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $config"
scored: true
- id: 1.4.5
text: "Ensure that the scheduler file permissions are set to 644 or more restrictive (Scored)"
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: "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.
\nFor example, chmod 644 $schedulerconf"
scored: true
- id: 1.4.6
text: "Ensure that the scheduler file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $schedulerconf"
scored: true
- id: 1.4.7
text: "Ensure that the etcd.conf file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %a $etcdconf; fi'"
tests:
bin_op: or
test_items:
- 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.
\nFor example, chmod 644 $etcdconf"
scored: true
- id: 1.4.8
text: "Ensure that the etcd.conf file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $etcdconf"
scored: true
- id: 1.4.9
text: "Ensure that the flanneld file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $flanneldconf; then stat -c %a $flanneldconf; fi'"
tests:
bin_op: or
test_items:
- 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.
\nFor example, chmod 644 $flanneldconf"
scored: true
- id: 1.4.10
text: "Ensure that the flanneld file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $flanneldconf; then stat -c %U:%G $flanneldconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $flanneldconf"
scored: true
- 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 | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %a
tests:
test_items:
- flag: "700"
compare:
op: eq
value: "700"
set: true
remediation: "On the etcd server node, get the etcd data directory, passed as an argument --data-dir ,
from the below command:\n
ps -ef | grep $etcdbin\n
Run the below command (based on the etcd data directory found above). For example,\n
chmod 700 /var/lib/etcd/default.etcd"
scored: true
- 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 | sed 's%.*data-dir[= ]\(\S*\)%\1%' | xargs stat -c %U:%G
tests:
test_items:
- flag: "etcd:etcd"
set: true
remediation: "On the etcd server node, get the etcd data directory, passed as an argument --data-dir ,
from the below command:\n
ps -ef | grep etcd\n
Run the below command (based on the etcd data directory found above). For example,\n
chown etcd:etcd /var/lib/etcd/default.etcd"
scored: true
- id: 1.5
text: "etcd"
checks:
- id: 1.5.1
text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--cert-file"
set: true
- flag: "--key-file"
set: true
remediation: "Follow the etcd service documentation and configure TLS encryption."
scored: true
- id: 1.5.2
text: "Ensure that the --client-cert-auth argument is set to true (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--client-cert-auth"
compare:
op: eq
value: true
set: true
remediation: "Edit the etcd envrironment file (for example, $etcdconf) on the
etcd server node and set the ETCD_CLIENT_CERT_AUTH parameter to \"true\".
Edit the etcd startup file (for example, /etc/systemd/system/multiuser.target.wants/etcd.service)
and configure the startup parameter for --clientcert-auth and set it to \"${ETCD_CLIENT_CERT_AUTH}\""
scored: true
- id: 1.5.3
text: "Ensure that the --auto-tls argument is not set to true (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--auto-tls"
set: false
- flag: "--auto-tls"
compare:
op: neq
value: true
remediation: "Edit the etcd environment file (for example, $etcdconf) on the etcd server
node and comment out the ETCD_AUTO_TLS parameter. Edit the etcd startup file (for example,
/etc/systemd/system/multiuser.target.wants/etcd.service) and remove the startup parameter
for --auto-tls."
scored: true
- id: 1.5.4
text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--peer-cert-file"
set: true
- flag: "--peer-key-file"
set: true
remediation: "Note: This recommendation is applicable only for etcd clusters. If you are using only
one etcd server in your environment then this recommendation is not applicable.
Follow the etcd service documentation and configure peer TLS encryption as appropriate for
your etcd cluster."
scored: true
- id: 1.5.5
text: "Ensure that the --peer-client-cert-auth argument is set to true (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--peer-client-cert-auth"
compare:
op: eq
value: true
set: true
remediation: "Note: This recommendation is applicable only for etcd clusters. If you are using only
one etcd server in your environment then this recommendation is not applicable.
Edit the etcd environment file (for example, $etcdconf) on the etcd server node
and set the ETCD_PEER_CLIENT_CERT_AUTH parameter to \"true\". Edit the etcd startup file
(for example, /etc/systemd/system/multiuser.target.wants/etcd.service) and configure the
startup parameter for --peer-client-cert-auth and set it to \"${ETCD_PEER_CLIENT_CERT_AUTH}\""
scored: true
- id: 1.5.6
text: "Ensure that the --peer-auto-tls argument is not set to true (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--peer-auto-tls"
set: false
- flag: "--peer-auto-tls"
compare:
op: eq
value: false
set: true
remediation: "Note: This recommendation is applicable only for etcd clusters.
If you are using only one etcd server in your environment then this recommendation is
not applicable. Edit the etcd environment file (for example, $etcdconf)
on the etcd server node and comment out the ETCD_PEER_AUTO_TLS parameter.
Edit the etcd startup file (for example, /etc/systemd/system/multiuser.target.wants/etcd.service)
and remove the startup parameter for --peer-auto-tls."
scored: true
- id: 1.5.7
text: "Ensure that the --wal-dir argument is set as appropriate (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--wal-dir"
set: true
remediation: "Edit the etcd environment file (for example, $etcdconf) on the etcd server node
and set the ETCD_WAL_DIR parameter as appropriate. Edit the etcd startup file (for example,
/etc/systemd/system/multiuser.target.wants/etcd.service) and configure the startup parameter for
--wal-dir and set it to \"${ETCD_WAL_DIR}\""
scored: true
- id: 1.5.8
text: "Ensure that the --max-wals argument is set to 0 (Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--max-wals"
compare:
op: eq
value: 0
set: true
remediation: "Edit the etcd environment file (for example, $etcdconf) on the etcd server node
and set the ETCD_MAX_WALS parameter to 0. Edit the etcd startup file (for example,
/etc/systemd/system/multiuser.target.wants/etcd.service) and configure the startup parameter
for --max-wals and set it to \"${ETCD_MAX_WALS}\"."
scored: true
- id: 1.5.9
text: "Ensure that a unique Certificate Authority is used for etcd (Not Scored)"
audit: "ps -ef | grep $etcdbin | grep -v grep"
tests:
test_items:
- flag: "--trusted-ca-file"
set: true
remediation: "Follow the etcd documentation and create a dedicated certificate authority setup for the
etcd service."
scored: false
- id: 1.6
text: "General Security Primitives"
checks:
- id: 1.6.1
text: "Ensure that the cluster-admin role is only used where required (Not Scored)"
type: "manual"
remediation: "Remove any unneeded clusterrolebindings: kubectl delete clusterrolebinding [name]"
scored: false
- id: 1.6.2
text: "Create Pod Security Policies for your cluster (Not Scored)"
type: "manual"
remediation: "Follow the documentation and create and enforce Pod Security Policies for your cluster.
Additionally, you could refer the \"CIS Security Benchmark for Docker\" and follow the
suggested Pod Security Policies for your environment."
scored: false
- id: 1.6.3
text: "Create administrative boundaries between resources using namespaces (Not Scored)"
type: "manual"
remediation: "Follow the documentation and create namespaces for objects in your deployment as you
need them."
scored: false
- id: 1.6.4
text: "Create network segmentation using Network Policies (Not Scored)"
type: "manual"
remediation: "Follow the documentation and create NetworkPolicy objects as you need them."
scored: false
- id: 1.6.5
text: "Avoid using Kubernetes Secrets (Not Scored)"
type: "manual"
remediation: "Use other mechanisms such as vaults to manage your cluster secrets."
scored: false
- id: 1.6.6
text: "Ensure that the seccomp profile is set to docker/default in your pod definitions (Not Scored)"
type: "manual"
remediation: "Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you
would need to enable alpha features in the apiserver by passing \"--feature-
gates=AllAlpha=true\" argument.\n
Edit the $apiserverconf file on the master node and set the KUBE_API_ARGS
parameter to \"--feature-gates=AllAlpha=true\"
KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\""
scored: false
- id: 1.6.7
text: "Apply Security Context to Your Pods and Containers (Not Scored)"
type: "manual"
remediation: "Follow the Kubernetes documentation and apply security contexts to your pods. For a
suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker
Containers."
scored: false
- id: 1.6.8
text: "Configure Image Provenance using ImagePolicyWebhook admission controller (Not Scored)"
type: "manual"
remediation: "Follow the Kubernetes documentation and setup image provenance."
scored: false

304
cfg/1.6/node.yaml Normal file
View File

@@ -0,0 +1,304 @@
---
controls:
version: 1.6
id: 2
text: "Worker Node Security Configuration"
type: "node"
groups:
- id: 2.1
text: "Kubelet"
checks:
- id: 2.1.1
text: "Ensure that the --allow-privileged argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--allow-privileged"
compare:
op: eq
value: false
set: true
remediation: "Edit the $config file on each node and set the KUBE_ALLOW_PRIV
parameter to \"--allow-privileged=false\""
scored: true
- id: 2.1.2
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
remediation: "Edit the $kubeletconf file on the master node and set the
KUBELET_ARGS parameter to \"--anonymous-auth=false\""
scored: true
- id: 2.1.3
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
remediation: "Edit the $kubeletconf file on each node and set the
KUBELET_ARGS parameter to \"--authorization-mode=Webhook\""
scored: true
- id: 2.1.4
text: "Ensure that the --client-ca-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--client-ca-file"
set: true
remediation: "Follow the Kubernetes documentation and setup the TLS connection between
the apiserver and kubelets. Then, edit the $kubeletconf file on each node
and set the KUBELET_ARGS parameter to \"--client-ca-file=<path/to/client-ca-file>\""
scored: true
- id: 2.1.5
text: "Ensure that the --read-only-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--read-only-port"
compare:
op: eq
value: 0
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
parameter to \"--read-only-port=0\""
scored: true
- id: 2.1.6
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--streaming-connection-idle-timeout"
compare:
op: gt
value: 0
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
parameter to \"--streaming-connection-idle-timeout=<appropriate-timeout-value>\""
scored: true
- id: 2.1.7
text: "Ensure that the --protect-kernel-defaults argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--protect-kernel-defaults"
compare:
op: eq
value: true
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
parameter to \"--protect-kernel-defaults=true\""
scored: true
- id: 2.1.8
text: "Ensure that the --make-iptables-util-chains argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--make-iptables-util-chains"
compare:
op: eq
value: true
set: true
- flag: "--make-iptables-util-chains"
set: false
remediation: "Edit the $kubeletconf file on each node and remove the
--make-iptables-util-chains argument from the KUBELET_ARGS parameter."
scored: true
- id: 2.1.9
text: "Ensure that the --keep-terminated-pod-volumes argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--keep-terminated-pod-volumes"
compare:
op: eq
value: false
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
parameter to \"--keep-terminated-pod-volumes=false\""
scored: true
- id: 2.1.10
text: "Ensure that the --hostname-override argument is not set (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--hostname-override"
set: false
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_HOSTNAME
parameter to \"\""
scored: true
- id: 2.1.11
text: "Ensure that the --event-qps argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--event-qps"
compare:
op: eq
value: 0
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
parameter to \"--event-qps=0\""
scored: true
- id: 2.1.12
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection on the Kubelet.
Then, edit the $kubeletconf file on the master node and set the KUBELET_ARGS
parameter to include \"--tls-cert-file=<path/to/tls-certificate-file>\" and
\"--tls-private-key-file=<path/to/tls-key-file>\""
scored: true
- id: 2.1.13
text: "Ensure that the --cadvisor-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--cadvisor-port"
compare:
op: eq
value: 0
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS parameter
to \"--cadvisor-port=0\""
scored: true
- id: 2.2
text: "Configuration Files"
checks:
- id: 2.2.1
text: "Ensure that the config file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'"
tests:
bin_op: or
test_items:
- 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 each worker node.
\nFor example, chmod 644 $config"
scored: true
- id: 2.2.2
text: "Ensure that the config file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %U:%G $config; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: root:root
set: true
remediation: "Run the below command (based on the file location on your system) on the each worker node.
\nFor example, chown root:root $config"
scored: true
- id: 2.2.3
text: "Ensure that the kubelet file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker node.
\nFor example, chmod 644 $kubeletconf"
scored: true
- id: 2.2.4
text: "Ensure that the kubelet file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the each worker node.
\nFor example, chown root:root $kubeletconf"
scored: true
- id: 2.2.5
text: "Ensure that the proxy file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %a $proxyconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker node.
\nFor example, chmod 644 $proxyconf"
scored: true
- id: 2.2.6
text: "Ensure that the proxy file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %U:%G $proxyconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the each worker node.
\nFor example, chown root:root $proxyconf"
scored: true

285
cfg/1.7/federated.yaml Normal file
View File

@@ -0,0 +1,285 @@
---
controls:
version: 1.7
id: 3
text: "Federated Deployments"
type: "federated"
groups:
- id: 3.1
text: "Federation API Server"
checks:
- id: 3.1.1
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
remediation: "Edit the deployment specs and set --anonymous-auth=false.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.2
text: "Ensure that the --basic-auth-file argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--basic-auth-file"
set: false
remediation: "Follow the documentation and configure alternate mechanisms for authentication.
Then, edit the deployment specs and remove \"--basic-auth-file=<filename>\".\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.3
text: "Ensure that the --insecure-allow-any-token argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-allow-any-token"
set: false
remediation: "Edit the deployment specs and remove --insecure-allow-any-token.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.4
text: "Ensure that the --insecure-bind-address argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-bind-address"
set: false
remediation: "Edit the deployment specs and remove --insecure-bind-address.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.5
text: "Ensure that the --insecure-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-port"
compare:
op: eq
value: 0
set: true
remediation: "Edit the deployment specs and set --insecure-port=0.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.6
text: "Ensure that the --secure-port argument is not set to 0 (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--secure-port"
compare:
op: gt
value: 0
set: true
- flag: "--secure-port"
set: false
remediation: "Edit the deployment specs and set the --secure-port argument to the desired port.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.7
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: "Edit the deployment specs and set \"--profiling=false\".\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
score: true
- id: 3.1.8
text: "Ensure that the admission control policy is not set to AlwaysAdmit (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: nothave
value: AlwaysAdmit
set: true
remediation: "Edit the deployment specs and set --admission-control argument to a value that does
not include AlwaysAdmit.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.9
text: "Ensure that the admission control policy is set to NamespaceLifecycle (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "admission-control"
compare:
op: has
value: "NamespaceLifecycle"
set: true
remediation: "Edit the deployment specs and set --admission-control argument to a value that includes NamespaceLifecycle.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.10
text: "Ensure that the --audit-log-path argument is set as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-path"
set: true
remediation: "Edit the deployment specs and set --audit-log-path argument as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.11
text: "Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxage"
compare:
op: gte
value: 30
set: true
remediation: "Edit the deployment specs and set --audit-log-maxage to 30 or as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.12
text: "Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxbackup"
compare:
op: gte
value: 10
set: true
remediation: "Edit the deployment specs and set --audit-log-maxbackup to 10 or as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.13
text: "Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxsize"
compare:
op: gte
value: 100
set: true
remediation: "Edit the deployment specs and set --audit-log-maxsize=100 to 100 or as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.14
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
remediation: "Edit the deployment specs and set --authorization-mode argument to a value other than AlwaysAllow.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.15
text: "Ensure that the --token-auth-file parameter is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | 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 deployment specs and remove the --token-auth-file=<filename> argument.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.16
text: "Ensure that the --service-account-lookup argument is set to true (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-lookup"
compare:
op: eq
value: true
set: true
remediation: "Edit the deployment specs and set \"--service-account-lookup=true\".\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.17
text: "Ensure that the --service-account-key-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-key-file"
set: true
remediation: "Edit the deployment specs and set --service-account-key-file argument as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.18
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Scored"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--etcd-certfile"
set: true
- flag: "--etcd-keyfile"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection between the
federation apiserver and etcd. Then, edit the deployment specs and set \"--etcd-
certfile=<path/to/client-certificate-file>\" and \"--etcd-
keyfile=<path/to/client-key-file>\" arguments.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.19
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
remediation: "Follow the Kubernetes documentation and set up the TLS connection on the federation
apiserver. Then, edit the deployment specs and set \"--tls-cert-file=<path/to/tls-
certificate-file>\" and \"--tls-private-key-file=<path/to/tls-key-file>\" :
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.2
text: "Federation Controller Manager"
checks:
- id: 3.2.1
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $fedcontrollermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: "Edit the deployment specs and set \"--profiling=false\".\n
kubectl edit deployments federation-controller-manager-deployment --namespace=federation-system"
scored: true

View File

@@ -1,5 +1,6 @@
---
controls:
version: 1.7
id: 1
text: "Master Node Security Configuration"
type: "master"
@@ -310,7 +311,7 @@ groups:
scored: true
- id: 1.1.23
text: "Ensure that the --kubelet-client-certificate and --kubelet-clientkey arguments are set as appropriate (Scored)"
text: "Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: and
@@ -636,7 +637,7 @@ groups:
- id: 1.4.3
text: "Ensure that the config file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'"
audit: "/bin/sh -c 'if test -e $kubernetesconf; then stat -c %a $kubernetesconf; fi'"
tests:
bin_op: or
test_items:
@@ -656,12 +657,12 @@ groups:
value: "600"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chmod 644 $config"
\nFor example, chmod 644 $kubernetesconf"
scored: true
- id: 1.4.4
text: "Ensure that the config file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %U:%G $config; fi'"
audit: "/bin/sh -c 'if test -e $kubernetesconf; then stat -c %U:%G $kubernetesconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -670,7 +671,7 @@ groups:
value: "root:root"
set: true
remediation: "Run the below command (based on the file location on your system) on the master node.
\nFor example, chown root:root $config"
\nFor example, chown root:root $kubernetesconf"
scored: true
- id: 1.4.5
@@ -792,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"
@@ -809,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"

View File

@@ -1,5 +1,6 @@
---
controls:
version: 1.7
id: 2
text: "Worker Node Security Configuration"
type: "node"
@@ -17,7 +18,7 @@ groups:
op: eq
value: false
set: true
remediation: "Edit the $config file on each node and set the KUBE_ALLOW_PRIV
remediation: "Edit the $kubeletconf file on each node and set the KUBE_ALLOW_PRIV
parameter to \"--allow-privileged=false\""
scored: true
@@ -79,10 +80,11 @@ groups:
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--streaming-connection-idle-timeout"
compare:
op: gt
op: noteq
value: 0
set: true
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS
@@ -198,7 +200,7 @@ groups:
op: eq
value: true
set: true
remediation: "Edit the /etc/kubernetes/kubelet file on each node and set the KUBELET_ARGS parameter
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS parameter
to a value to include \"--feature-gates=RotateKubeletClientCertificate=true\"."
scored: true
@@ -212,7 +214,7 @@ groups:
op: eq
value: true
set: true
remediation: "Edit the /etc/kubernetes/kubelet file on each node and set the KUBELET_ARGS parameter
remediation: "Edit the $kubeletconf file on each node and set the KUBELET_ARGS parameter
to a value to include \"--feature-gates=RotateKubeletServerCertificate=true\"."
scored: true
@@ -221,7 +223,7 @@ groups:
checks:
- id: 2.2.1
text: "Ensure that the config file permissions are set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'"
audit: "/bin/sh -c 'if test -e $kubernetesconf; then stat -c %a $kubernetesconf; fi'"
tests:
bin_op: or
test_items:
@@ -241,12 +243,12 @@ groups:
value: "600"
set: true
remediation: "Run the below command (based on the file location on your system) on the each worker node.
\nFor example, chmod 644 $config"
\nFor example, chmod 644 $kubernetesconf"
scored: true
- id: 2.2.2
text: "Ensure that the config file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $config; then stat -c %U:%G $config; fi'"
audit: "/bin/sh -c 'if test -e $kubernetesconf; then stat -c %U:%G $kubernetesconf; fi'"
tests:
test_items:
- flag: "root:root"
@@ -255,7 +257,7 @@ groups:
value: root:root
set: true
remediation: "Run the below command (based on the file location on your system) on the each worker node.
\nFor example, chown root:root $config"
\nFor example, chown root:root $kubernetesconf"
scored: true
- id: 2.2.3

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

@@ -0,0 +1,44 @@
---
## 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:
confs:
- /etc/kubernetes/manifests/kube-apiserver.yaml
- /etc/kubernetes/manifests/kube-apiserver.manifest
defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
confs:
- /etc/kubernetes/manifests/kube-scheduler.yaml
- /etc/kubernetes/manifests/kube-scheduler.manifest
defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml
controllermanager:
confs:
- /etc/kubernetes/manifests/kube-controller-manager.yaml
- /etc/kubernetes/manifests/kube-controller-manager.manifest
defaultconf: /etc/kubernetes/manifests/kube-controller-manager.yaml
etcd:
confs:
- /etc/kubernetes/manifests/etcd.yaml
- /etc/kubernetes/manifests/etcd.manifest
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

309
cfg/1.8/federated.yaml Normal file
View File

@@ -0,0 +1,309 @@
---
controls:
version: 1.8
id: 3
text: "Federated Deployments"
type: "federated"
groups:
- id: 3.1
text: "Federation API Server"
checks:
- id: 3.1.1
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
remediation: |
Edit the deployment specs and set --anonymous-auth=false.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.2
text: "Ensure that the --basic-auth-file argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--basic-auth-file"
set: false
remediation: |
Follow the documentation and configure alternate mechanisms for authentication. Then,
edit the deployment specs and remove "--basic-auth-file=<filename>".
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.3
text: "Ensure that the --insecure-allow-any-token argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-allow-any-token"
set: false
remediation: |
Edit the deployment specs and remove --insecure-allow-any-token.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.4
text: "Ensure that the --insecure-bind-address argument is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-bind-address"
set: false
remediation: |
Edit the deployment specs and remove --insecure-bind-address.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.5
text: "Ensure that the --insecure-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--insecure-port"
compare:
op: eq
value: 0
set: true
remediation: |
Edit the deployment specs and set --insecure-port=0.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.6
text: "Ensure that the --secure-port argument is not set to 0 (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--secure-port"
compare:
op: gt
value: 0
set: true
- flag: "--secure-port"
set: false
remediation: |
Edit the deployment specs and set the --secure-port argument to the desired port.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.7
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: |
Edit the deployment specs and set "--profiling=false":
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
score: true
- id: 3.1.8
text: "Ensure that the admission control policy is not set to AlwaysAdmit (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--admission-control"
compare:
op: nothave
value: AlwaysAdmit
set: true
remediation: |
Edit the deployment specs and set --admission-control argument to a value that does not
include AlwaysAdmit .
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.9
text: "Ensure that the admission control policy is set to NamespaceLifecycle (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "admission-control"
compare:
op: has
value: "NamespaceLifecycle"
set: true
remediation: |
Edit the deployment specs and set --admission-control argument to a value that includes
NamespaceLifecycle.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.10
text: "Ensure that the --audit-log-path argument is set as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-path"
set: true
remediation: "Edit the deployment specs and set --audit-log-path argument as appropriate.\n
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system"
scored: true
- id: 3.1.11
text: "Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxage"
compare:
op: gte
value: 30
set: true
remediation: |
Edit the deployment specs and set --audit-log-maxage to 30 or as appropriate.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.12
text: "Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxbackup"
compare:
op: gte
value: 10
set: true
remediation: |
Edit the deployment specs and set --audit-log-maxbackup to 10 or as appropriate.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.13
text: "Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--audit-log-maxsize"
compare:
op: gte
value: 100
set: true
remediation: |
Edit the deployment specs and set --audit-log-maxsize=100 to 100 or as appropriate.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.14
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
remediation: |
Edit the deployment specs and set --authorization-mode argument to a value other than
AlwaysAllow
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.15
text: "Ensure that the --token-auth-file parameter is not set (Scored)"
audit: "ps -ef | grep $fedapiserverbin | 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 deployment specs and remove the --token-auth-file=<filename> argument.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.16
text: "Ensure that the --service-account-lookup argument is set to true (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-lookup"
compare:
op: eq
value: true
set: true
remediation: |
Edit the deployment specs and set "--service-account-lookup=true" .
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.17
text: "Ensure that the --service-account-key-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
test_items:
- flag: "--service-account-key-file"
set: true
remediation: |
Edit the deployment specs and set --service-account-key-file argument as appropriate.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.18
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as
appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--etcd-certfile"
set: true
- flag: "--etcd-keyfile"
set: true
remediation: |
Follow the Kubernetes documentation and set up the TLS connection between the
federation apiserver and etcd. Then, edit the deployment specs and set
"--etcd-certfile=<path/to/client-certificate-file>" and
"--etcd-keyfile=<path/to/client-key-file>" arguments.
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.1.19
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as
appropriate (Scored)"
audit: "ps -ef | grep $fedapiserverbin | grep -v grep"
tests:
bin_op: and
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
remediation: |
Follow the Kubernetes documentation and set up the TLS connection on the federation
apiserver. Then, edit the deployment specs and set
"--tls-cert-file=<path/to/tls-certificate-file>" and
"--tls-private-key-file=<path/to/tls-key-file>":
kubectl edit deployments federation-apiserver-deployment --namespace=federation-system
scored: true
- id: 3.2
text: "Federation Controller Manager"
checks:
- id: 3.2.1
text: "Ensure that the --profiling argument is set to false (Scored)"
audit: "ps -ef | grep $fedcontrollermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
set: true
remediation: |
Edit the deployment specs and set "--profiling=false":
kubectl edit deployments federation-controller-manager-deployment --namespace=federation-system
scored: true

1358
cfg/1.8/master.yaml Normal file

File diff suppressed because it is too large Load Diff

440
cfg/1.8/node.yaml Normal file
View File

@@ -0,0 +1,440 @@
---
controls:
version: 1.8
id: 2
text: "Worker Node Security Configuration"
type: "node"
groups:
- id: 2.1
text: "Kubelet"
checks:
- id: 2.1.1
text: "Ensure that the --allow-privileged argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--allow-privileged"
compare:
op: eq
value: false
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.2
text: "Ensure that the --anonymous-auth argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--anonymous-auth"
compare:
op: eq
value: false
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.3
text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--authorization-mode"
compare:
op: nothave
value: "AlwaysAllow"
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.4
text: "Ensure that the --client-ca-file argument is set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--client-ca-file"
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.5
text: "Ensure that the --read-only-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--read-only-port"
compare:
op: eq
value: 0
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.6
text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--streaming-connection-idle-timeout"
compare:
op: noteq
value: 0
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.7
text: "Ensure that the --protect-kernel-defaults argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--protect-kernel-defaults"
compare:
op: eq
value: true
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.8
text: "Ensure that the --make-iptables-util-chains argument is set to true (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--make-iptables-util-chains"
compare:
op: eq
value: true
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.9
text: "Ensure that the --keep-terminated-pod-volumes argument is set to false (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--keep-terminated-pod-volumes"
compare:
op: eq
value: false
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.10
text: "Ensure that the --hostname-override argument is not set (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--hostname-override"
set: false
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.11
text: "Ensure that the --event-qps argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--event-qps"
compare:
op: eq
value: 0
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.12
text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--tls-cert-file"
set: true
- flag: "--tls-private-key-file"
set: true
remediation: |
Follow the Kubernetes documentation and set up the TLS connection on the Kubelet.
Then edit the kubelet service file /etc/systemd/system/kubelet.service.d/10-
kubeadm.conf on each worker node and set the below parameters in
KUBELET_CERTIFICATE_ARGS variable.
--tls-cert-file=<path/to/tls-certificate-file>
file=<path/to/tls-key-file>
--tls-private-key-
Based on your system, restart the kubelet service. For example:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.13
text: "Ensure that the --cadvisor-port argument is set to 0 (Scored)"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "--cadvisor-port"
compare:
op: eq
value: 0
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.1.14
text: "Ensure that the RotateKubeletClientCertificate argument is set to true"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "RotateKubeletClientCertificate"
compare:
op: eq
value: true
set: true
remediation: |
Edit the kubelet service file $kubeletconf
on each worker node and remove the --feature-
gates=RotateKubeletClientCertificate=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: 2.1.15
text: "Ensure that the RotateKubeletServerCertificate argument is set to true"
audit: "ps -ef | grep $kubeletbin | grep -v grep"
tests:
test_items:
- flag: "RotateKubeletServerCertificate"
compare:
op: eq
value: true
set: true
remediation: |
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:
systemctl daemon-reload
systemctl restart kubelet.service
scored: true
- id: 2.2
text: "Configuration Files"
checks:
- id: 2.2.1
text: "Ensure that the kubelet.conf file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 644 $kubeletconf
scored: true
- id: 2.2.2
text: "Ensure that the kubelet.conf file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
compare:
op: eq
value: root:root
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root /etc/kubernetes/kubelet.conf
scored: true
- 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 $kubeletconf; then stat -c %a $kubeletconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 755 $kubeletconf
scored: true
- id: 2.2.4
text: "2.2.4 Ensure that the kubelet service file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $kubeletconf
scored: true
- id: 2.2.5
text: "Ensure that the proxy kubeconfig file permissions are set to 644 or more
restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %a $proxyconf; fi'"
tests:
bin_op: or
test_items:
- 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 each worker
node. For example,
chmod 644 $proxyconf
scored: true
- id: 2.2.6
text: "Ensure that the proxy kubeconfig file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $proxyconf; then stat -c %U:%G $proxyconf; fi'"
tests:
test_items:
- flag: "root:root"
set: true
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $proxyconf
scored: true
- id: 2.2.7
text: "Ensure that the certificate authorities file permissions are set to
644 or more restrictive (Scored)"
type: manual
remediation: |
Run the following command to modify the file permissions of the --client-ca-file
chmod 644 <filename>
scored: true
- id: 2.2.8
text: "Ensure that the client certificate authorities file ownership is set to root:root"
audit: "/bin/sh -c 'if test -e $ca-file; then stat -c %U:%G $ca-file; fi'"
type: manual
remediation: |
Run the following command to modify the ownership of the --client-ca-file .
chown root:root <filename>
scored: true

View File

@@ -7,106 +7,105 @@
# nodeControls: ./cfg/node.yaml
# federatedControls: ./cfg/federated.yaml
## Support components
etcd:
bin: etcd
conf: /etc/etcd/etcd.conf
master:
components:
- apiserver
- scheduler
- controllermanager
- etcd
- flanneld
# kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark
- kubernetes
flanneld:
bin: flanneld
conf: /etc/sysconfig/flanneld
kubernetes:
defaultconf: /etc/kubernetes/config
# Installation
# Configure kubernetes component binaries and paths to their configuration files.
installation:
default:
config: /etc/kubernetes/config
master:
bin:
apiserver: apiserver
scheduler: scheduler
controller-manager: controller-manager
conf:
apiserver: /etc/kubernetes/apiserver
scheduler: /etc/kubernetes/scheduler
controller-manager: /etc/kubernetes/controller-manager
node:
bin:
kubelet: kubelet
proxy: proxy
conf:
kubelet: /etc/kubernetes/kubelet
proxy: /etc/kubernetes/proxy
federated:
bin:
apiserver: federation-apiserver
controller-manager: federation-controller-manager
apiserver:
bins:
- "kube-apiserver"
- "hyperkube apiserver"
- "apiserver"
confs:
- /etc/kubernetes/apiserver.conf
- /etc/kubernetes/apiserver
defaultconf: /etc/kubernetes/apiserver
kops:
config: /etc/kubernetes/config
master:
bin:
apiserver: apiserver
scheduler: scheduler
controller-manager: controller-manager
conf:
apiserver: /etc/kubernetes/apiserver
scheduler: /etc/kubernetes/scheduler
controller-manager: /etc/kubernetes/apiserver
node:
bin:
kubelet: kubelet
proxy: proxy
conf:
kubelet: /etc/kubernetes/kubelet
proxy: /etc/kubernetes/proxy
federated:
bin:
apiserver: federation-apiserver
controller-manager: federation-controller-manager
scheduler:
bins:
- "kube-scheduler"
- "hyperkube scheduler"
- "scheduler"
confs:
- /etc/kubernetes/scheduler.conf
- /etc/kubernetes/scheduler
defaultconf: /etc/kubernetes/scheduler
hyperkube:
config: /etc/kubernetes/config
master:
bin:
apiserver: hyperkube apiserver
scheduler: hyperkube scheduler
controller-manager: hyperkube controller-manager
conf:
apiserver: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler: /etc/kubernetes/manifests/kube-scheduler.yaml
controller-manager: /etc/kubernetes/manifests/kube-controller-manager.yaml
node:
bin:
kubelet: hyperkube kubelet
proxy: hyperkube proxy
conf:
kubelet: /etc/kubernetes/kubelet
proxy: /etc/kubernetes/addons/kube-proxy-daemonset.yaml
federated:
bin:
apiserver: hyperkube federation-apiserver
controller-manager: hyperkube federation-controller-manager
controllermanager:
bins:
- "kube-controller-manager"
- "hyperkube controller-manager"
- "controller-manager"
confs:
- /etc/kubernetes/controller-manager.conf
- /etc/kubernetes/controller-manager
defaultconf: /etc/kubernetes/controller-manager
kubeadm:
config: /etc/kubernetes/config
master:
bin:
apiserver: kube-apiserver
scheduler: kube-scheduler
controller-manager: kube-controller-manager
conf:
apiserver: /etc/kubernetes/admin.conf
scheduler: /etc/kubernetes/scheduler.conf
controller-manager: /etc/kubernetes/controller-manager.conf
node:
bin:
kubelet: kubelet
proxy: kube-proxy
conf:
kubelet: /etc/kubernetes/kubelet.conf
proxy: /etc/kubernetes/proxy.conf
federated:
bin:
apiserver: kube-federation-apiserver
controller-manager: kube-federation-controller-manager
etcd:
optional: true
bins:
- "etcd"
confs:
- /etc/etcd/etcd.conf
defaultconf: /etc/etcd/etcd.conf
flanneld:
optional: true
bins:
- flanneld
defaultconf: /etc/sysconfig/flanneld
node:
components:
- kubelet
- proxy
# kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark
- kubernetes
kubernetes:
defaultconf: /etc/kubernetes/config
kubelet:
bins:
- "hyperkube kubelet"
- "kubelet"
confs:
- /etc/kubernetes/kubelet.conf
- /etc/kubernetes/kubelet
defaultconf: "/etc/kubernetes/kubelet.conf"
proxy:
bins:
- "kube-proxy"
- "hyperkube proxy"
- "proxy"
confs:
- /etc/kubernetes/proxy.conf
- /etc/kubernetes/proxy
- /etc/kubernetes/addons/kube-proxy-daemonset.yaml
federated:
components:
- fedapiserver
- fedcontrollermanager
fedapiserver:
bins:
- "hyperkube federation-apiserver"
- "kube-federation-apiserver"
- "federation-apiserver"
fedcontrollermanager:
bins:
- "hyperkube federation-controller-manager"
- "kube-federation-controller-manager"
- "federation-controller-manager"

View File

@@ -60,15 +60,17 @@ func handleError(err error, context string) (errmsg string) {
// Check contains information about a recommendation in the
// CIS Kubernetes 1.6+ document.
type Check struct {
ID string `yaml:"id" json:"id"`
Text string
ID string `yaml:"id" json:"test_number"`
Text string `json:"test_desc"`
Audit string `json:"omit"`
Type string `json:"type"`
Commands []*exec.Cmd `json:"omit"`
Tests *tests `json:"omit"`
Set bool `json:"omit"`
Remediation string
State
Remediation string `json:"-"`
TestInfo []string `json:"test_info"`
State `json:"status"`
ActualValue string `json:"actual_value"`
}
// Run executes the audit commands specified in a check and outputs
@@ -156,13 +158,25 @@ func (c *Check) Run() {
i++
}
glog.V(2).Info("%s\n", errmsgs)
res := c.Tests.execute(out.String())
if res {
c.State = PASS
finalOutput := c.Tests.execute(out.String())
if finalOutput != nil {
c.ActualValue = finalOutput.actualResult
if finalOutput.testResult {
c.State = PASS
} else {
c.State = FAIL
}
} else {
c.State = FAIL
errmsgs += handleError(
fmt.Errorf("final output is nil"),
fmt.Sprintf("failed to run: %s\n",
c.Audit,
),
)
}
if errmsgs != "" {
glog.V(2).Info(errmsgs)
}
}

View File

@@ -23,25 +23,29 @@ import (
// Controls holds all controls to check for master nodes.
type Controls struct {
ID string `yaml:"id"`
Text string
Type NodeType
Groups []*Group
ID string `yaml:"id" json:"id"`
Version string `json:"version"`
Text string `json:"text"`
Type NodeType `json:"node_type"`
Groups []*Group `json:"tests"`
Summary
}
// Group is a collection of similar checks.
type Group struct {
ID string `yaml:"id"`
Text string
Checks []*Check
ID string `yaml:"id" json:"section"`
Pass int `json:"pass"`
Fail int `json:"fail"`
Warn int `json:"warn"`
Text string `json:"desc"`
Checks []*Check `json:"results"`
}
// Summary is a summary of the results of control checks run.
type Summary struct {
Pass int
Fail int
Warn int
Pass int `json:"total_pass"`
Fail int `json:"total_fail"`
Warn int `json:"total_warn"`
}
// NewControls instantiates a new master Controls object.
@@ -83,7 +87,9 @@ func (controls *Controls) RunGroup(gids ...string) Summary {
if gid == group.ID {
for _, check := range group.Checks {
check.Run()
check.TestInfo = append(check.TestInfo, check.Remediation)
summarize(controls, check)
summarizeGroup(group, check)
}
g = append(g, group)
@@ -111,6 +117,7 @@ func (controls *Controls) RunChecks(ids ...string) Summary {
for _, id := range ids {
if id == check.ID {
check.Run()
check.TestInfo = append(check.TestInfo, check.Remediation)
summarize(controls, check)
// Check if we have already added this checks group.
@@ -177,3 +184,14 @@ func summarize(controls *Controls, check *Check) {
controls.Summary.Warn++
}
}
func summarizeGroup(group *Group, check *Check) {
switch check.State {
case PASS:
group.Pass++
case FAIL:
group.Fail++
case WARN:
group.Warn++
}
}

View File

@@ -11,22 +11,31 @@ const cfgDir = "../cfg/"
// validate that the files we're shipping are valid YAML
func TestYamlFiles(t *testing.T) {
files, err := ioutil.ReadDir(cfgDir)
if err != nil {
t.Fatalf("error reading %s directory: %v", cfgDir, err)
}
for _, file := range files {
fileName := file.Name()
in, err := ioutil.ReadFile(cfgDir + fileName)
// TODO: make this list dynamic
dirs := []string{"1.6/", "1.7/"}
for _, dir := range dirs {
dir = cfgDir + dir
files, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatalf("error opening file %s: %v", fileName, err)
t.Fatalf("error reading %s directory: %v", dir, err)
}
c := new(Controls)
for _, file := range files {
err = yaml.Unmarshal(in, c)
if err != nil {
t.Fatalf("failed to load YAML from %s: %v", fileName, err)
fileName := file.Name()
in, err := ioutil.ReadFile(dir + fileName)
if err != nil {
t.Fatalf("error opening file %s: %v", fileName, err)
}
c := new(Controls)
err = yaml.Unmarshal(in, c)
if err != nil {
t.Fatalf("failed to load YAML from %s: %v", fileName, err)
}
}
}
}

View File

@@ -17,7 +17,7 @@ groups:
- id: 1
text: "flag is not set"
tests:
test_item:
test_items:
- flag: "--basic-auth"
set: false
@@ -116,3 +116,45 @@ groups:
op: eq
value: "600"
set: true
- id: 10
text: "flag value includes some value in a comma-separated list, value is last in list"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: RBAC
set: true
- id: 11
text: "flag value includes some value in a comma-separated list, value is first in list"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: WebHook
set: true
- id: 12
text: "flag value includes some value in a comma-separated list, value middle of list"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: Something
set: true
- id: 13
text: "flag value includes some value in a comma-separated list, value only one in list"
tests:
test_items:
- flag: "--admission-control"
compare:
op: has
value: Something
set: true

View File

@@ -49,8 +49,13 @@ type compare struct {
Value string
}
func (t *testItem) execute(s string) (result bool) {
result = false
type testOutput struct {
testResult bool
actualResult string
}
func (t *testItem) execute(s string) *testOutput {
result := &testOutput{}
match := strings.Contains(s, t.Flag)
if t.Set {
@@ -62,7 +67,8 @@ func (t *testItem) execute(s string) (result bool) {
// --flag=somevalue
// --flag
// somevalue
pttn := `(` + t.Flag + `)(=)*([^\s,]*) *`
//pttn := `(` + t.Flag + `)(=)*([^\s,]*) *`
pttn := `(` + t.Flag + `)(=)*([^\s]*) *`
flagRe := regexp.MustCompile(pttn)
vals := flagRe.FindStringSubmatch(s)
@@ -77,45 +83,57 @@ func (t *testItem) execute(s string) (result bool) {
os.Exit(1)
}
result.actualResult = strings.ToLower(flagVal)
switch t.Compare.Op {
case "eq":
result = flagVal == t.Compare.Value
value := strings.ToLower(flagVal)
// Do case insensitive comparaison for booleans ...
if value == "false" || value == "true" {
result.testResult = value == t.Compare.Value
} else {
result.testResult = flagVal == t.Compare.Value
}
case "noteq":
result = !(flagVal == t.Compare.Value)
value := strings.ToLower(flagVal)
// Do case insensitive comparaison for booleans ...
if value == "false" || value == "true" {
result.testResult = !(value == t.Compare.Value)
} else {
result.testResult = !(flagVal == t.Compare.Value)
}
case "gt":
a, b := toNumeric(flagVal, t.Compare.Value)
result = a > b
result.testResult = a > b
case "gte":
a, b := toNumeric(flagVal, t.Compare.Value)
result = a >= b
result.testResult = a >= b
case "lt":
a, b := toNumeric(flagVal, t.Compare.Value)
result = a < b
result.testResult = a < b
case "lte":
a, b := toNumeric(flagVal, t.Compare.Value)
result = a <= b
result.testResult = a <= b
case "has":
result = strings.Contains(flagVal, t.Compare.Value)
result.testResult = strings.Contains(flagVal, t.Compare.Value)
case "nothave":
result = !strings.Contains(flagVal, t.Compare.Value)
result.testResult = !strings.Contains(flagVal, t.Compare.Value)
}
} else {
result = isset
result.testResult = isset
}
} else {
notset := !match
result = notset
result.testResult = notset
}
return
return result
}
type tests struct {
@@ -123,13 +141,19 @@ type tests struct {
BinOp binOp `yaml:"bin_op"`
}
func (ts *tests) execute(s string) (result bool) {
res := make([]bool, len(ts.TestItems))
func (ts *tests) execute(s string) *testOutput {
finalOutput := &testOutput{}
for i, t := range ts.TestItems {
res[i] = t.execute(s)
res := make([]testOutput, len(ts.TestItems))
if len(res) == 0 {
return finalOutput
}
for i, t := range ts.TestItems {
res[i] = *(t.execute(s))
}
var result bool
// If no binary operation is specified, default to AND
switch ts.BinOp {
default:
@@ -138,16 +162,19 @@ func (ts *tests) execute(s string) (result bool) {
case and, "":
result = true
for i := range res {
result = result && res[i]
result = result && res[i].testResult
}
case or:
result = false
for i := range res {
result = result || res[i]
result = result || res[i].testResult
}
}
return
finalOutput.testResult = result
finalOutput.actualResult = res[0].actualResult
return finalOutput
}
func toNumeric(a, b string) (c, d int) {

View File

@@ -94,10 +94,26 @@ func TestTestExecute(t *testing.T) {
controls.Groups[0].Checks[9],
"600",
},
{
controls.Groups[0].Checks[10],
"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40",
},
{
controls.Groups[0].Checks[11],
"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40",
},
{
controls.Groups[0].Checks[12],
"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,Something,RBAC ---audit-log-maxage=40",
},
{
controls.Groups[0].Checks[13],
"2:45 ../kubernetes/kube-apiserver --option --admission-control=Something ---audit-log-maxage=40",
},
}
for _, c := range cases {
res := c.Tests.execute(c.str)
res := c.Tests.execute(c.str).testResult
if !res {
t.Errorf("%s, expected:%v, got:%v\n", c.Text, true, res)
}

View File

@@ -18,70 +18,24 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/aquasecurity/kube-bench/check"
"github.com/golang/glog"
"github.com/spf13/viper"
)
var (
apiserverBin string
apiserverConf string
schedulerBin string
schedulerConf string
controllerManagerBin string
controllerManagerConf string
config string
etcdBin string
etcdConf string
flanneldBin string
flanneldConf string
kubeletBin string
kubeletConf string
proxyBin string
proxyConf string
fedApiserverBin string
fedControllerManagerBin string
errmsgs string
// TODO: Consider specifying this in config file.
kubeMajorVersion = "1"
kubeMinorVersion = "7"
)
func runChecks(t check.NodeType) {
func runChecks(nodetype check.NodeType) {
var summary check.Summary
var file string
var err error
var typeConf *viper.Viper
// Master variables
apiserverBin = viper.GetString("installation." + installation + ".master.bin.apiserver")
apiserverConf = viper.GetString("installation." + installation + ".master.conf.apiserver")
schedulerBin = viper.GetString("installation." + installation + ".master.bin.scheduler")
schedulerConf = viper.GetString("installation." + installation + ".master.conf.scheduler")
controllerManagerBin = viper.GetString("installation." + installation + ".master.bin.controller-manager")
controllerManagerConf = viper.GetString("installation." + installation + ".master.conf.controller-manager")
config = viper.GetString("installation." + installation + ".config")
etcdBin = viper.GetString("etcd.bin")
etcdConf = viper.GetString("etcd.conf")
flanneldBin = viper.GetString("flanneld.bin")
flanneldConf = viper.GetString("flanneld.conf")
// Node variables
kubeletBin = viper.GetString("installation." + installation + ".node.bin.kubelet")
kubeletConf = viper.GetString("installation." + installation + ".node.conf.kubelet")
proxyBin = viper.GetString("installation." + installation + ".node.bin.proxy")
proxyConf = viper.GetString("installation." + installation + ".node.conf.proxy")
// Federated
fedApiserverBin = viper.GetString("installation." + installation + ".federated.bin.apiserver")
fedControllerManagerBin = viper.GetString("installation." + installation + ".federated.bin.controller-manager")
// Run kubernetes installation validation checks.
verifyKubeVersion(kubeMajorVersion, kubeMinorVersion)
verifyNodeType(t)
switch t {
switch nodetype {
case check.MASTER:
file = masterFile
case check.NODE:
@@ -90,36 +44,50 @@ func runChecks(t check.NodeType) {
file = federatedFile
}
in, err := ioutil.ReadFile(file)
runningVersion, err := getKubeVersion()
if err != nil && kubeVersion == "" {
exitWithError(fmt.Errorf("Version check failed: %s\nAlternatively, you can specify the version with --version", err))
}
path, err := getConfigFilePath(kubeVersion, runningVersion, file)
if err != nil {
exitWithError(fmt.Errorf("error opening %s controls file: %v", t, err))
exitWithError(fmt.Errorf("can't find %s controls file in %s: %v", nodetype, cfgDir, err))
}
// Variable substitutions. Replace all occurrences of variables in controls files.
s := multiWordReplace(string(in), "$apiserverbin", apiserverBin)
s = multiWordReplace(s, "$apiserverconf", apiserverConf)
s = multiWordReplace(s, "$schedulerbin", schedulerBin)
s = multiWordReplace(s, "$schedulerconf", schedulerConf)
s = multiWordReplace(s, "$controllermanagerbin", controllerManagerBin)
s = multiWordReplace(s, "$controllermanagerconf", controllerManagerConf)
s = multiWordReplace(s, "$config", config)
s = multiWordReplace(s, "$etcdbin", etcdBin)
s = multiWordReplace(s, "$etcdconf", etcdConf)
s = multiWordReplace(s, "$flanneldbin", flanneldBin)
s = multiWordReplace(s, "$flanneldconf", flanneldConf)
s = multiWordReplace(s, "$kubeletbin", kubeletBin)
s = multiWordReplace(s, "$kubeletconf", kubeletConf)
s = multiWordReplace(s, "$proxybin", proxyBin)
s = multiWordReplace(s, "$proxyconf", proxyConf)
s = multiWordReplace(s, "$fedapiserverbin", fedApiserverBin)
s = multiWordReplace(s, "$fedcontrollermanagerbin", fedControllerManagerBin)
controls, err := check.NewControls(t, []byte(s))
def := filepath.Join(path, file)
in, err := ioutil.ReadFile(def)
if err != nil {
exitWithError(fmt.Errorf("error setting up %s controls: %v", t, err))
exitWithError(fmt.Errorf("error opening %s controls file: %v", nodetype, err))
}
glog.V(1).Info(fmt.Sprintf("Using benchmark file: %s\n", def))
// Merge kubernetes version specific config if any.
viper.SetConfigFile(path + "/config.yaml")
err = viper.MergeInConfig()
if err != nil {
if os.IsNotExist(err) {
glog.V(2).Info(fmt.Sprintf("No version-specific config.yaml file in %s", path))
} else {
exitWithError(fmt.Errorf("couldn't read config file %s: %v", path+"/config.yaml", err))
}
} else {
glog.V(1).Info(fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed()))
}
// 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.
typeConf = viper.Sub(string(nodetype))
binmap := getBinaries(typeConf)
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)
controls, err := check.NewControls(nodetype, []byte(s))
if err != nil {
exitWithError(fmt.Errorf("error setting up %s controls: %v", nodetype, err))
}
if groupList != "" && checkList == "" {
@@ -143,41 +111,16 @@ func runChecks(t check.NodeType) {
fmt.Println(string(out))
} else {
prettyPrint(controls, summary)
}
}
// verifyNodeType checks the executables and config files are as expected
// for the specified tests (master, node or federated).
func verifyNodeType(t check.NodeType) {
var bins []string
var confs []string
switch t {
case check.MASTER:
bins = []string{apiserverBin, schedulerBin, controllerManagerBin}
confs = []string{apiserverConf, schedulerConf, controllerManagerConf}
case check.NODE:
bins = []string{kubeletBin, proxyBin}
confs = []string{kubeletConf, proxyConf}
case check.FEDERATED:
bins = []string{fedApiserverBin, fedControllerManagerBin}
}
for _, bin := range bins {
if !verifyBin(bin, ps) {
printlnWarn(fmt.Sprintf("%s is not running", bin))
}
}
for _, conf := range confs {
_, err := os.Stat(conf)
if err != nil {
if os.IsNotExist(err) {
printlnWarn(fmt.Sprintf("Missing kubernetes config file: %s", conf))
} else {
exitWithError(fmt.Errorf("error looking for file %s: %v", conf, err))
// if we want to store in PostgreSQL, convert to JSON and save it
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))
}
savePgsql(string(out))
} else {
prettyPrint(controls, summary)
}
}
}
@@ -190,43 +133,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("Using config file: %s\n", viper.ConfigFileUsed()))
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,
)
}
}

60
cmd/database.go Normal file
View File

@@ -0,0 +1,60 @@
package cmd
import (
"fmt"
"os"
"time"
"github.com/golang/glog"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres" // database packages get blank imports
"github.com/spf13/viper"
)
func savePgsql(jsonInfo string) {
envVars := map[string]string{
"PGSQL_HOST": viper.GetString("PGSQL_HOST"),
"PGSQL_USER": viper.GetString("PGSQL_USER"),
"PGSQL_DBNAME": viper.GetString("PGSQL_DBNAME"),
"PGSQL_SSLMODE": viper.GetString("PGSQL_SSLMODE"),
"PGSQL_PASSWORD": viper.GetString("PGSQL_PASSWORD"),
}
for k, v := range envVars {
if v == "" {
exitWithError(fmt.Errorf("environment variable %s is missing", envVarsPrefix+"_"+k))
}
}
connInfo := fmt.Sprintf("host=%s user=%s dbname=%s sslmode=%s password=%s",
envVars["PGSQL_HOST"],
envVars["PGSQL_USER"],
envVars["PGSQL_DBNAME"],
envVars["PGSQL_SSLMODE"],
envVars["PGSQL_PASSWORD"],
)
hostname, err := os.Hostname()
if err != nil {
exitWithError(fmt.Errorf("received error looking up hostname: %s", err))
}
timestamp := time.Now()
type ScanResult struct {
gorm.Model
ScanHost string `gorm:"type:varchar(63) not null"` // https://www.ietf.org/rfc/rfc1035.txt
ScanTime time.Time `gorm:"not null"`
ScanInfo string `gorm:"type:jsonb not null"`
}
db, err := gorm.Open("postgres", connInfo)
defer db.Close()
if err != nil {
exitWithError(fmt.Errorf("received error connecting to database: %s", err))
}
db.Debug().AutoMigrate(&ScanResult{})
db.Save(&ScanResult{ScanHost: hostname, ScanTime: timestamp, ScanInfo: jsonInfo})
glog.V(2).Info(fmt.Sprintf("successfully stored result to: %s", envVars["PGSQL_HOST"]))
}

View File

@@ -33,7 +33,7 @@ func init() {
federatedCmd.PersistentFlags().StringVarP(&federatedFile,
"file",
"f",
cfgDir+"/federated.yaml",
"/federated.yaml",
"Alternative YAML file for federated checks",
)

View File

@@ -33,7 +33,7 @@ func init() {
masterCmd.PersistentFlags().StringVarP(&masterFile,
"file",
"f",
cfgDir+"/master.yaml",
"/master.yaml",
"Alternative YAML file for master checks",
)

View File

@@ -33,7 +33,7 @@ func init() {
nodeCmd.PersistentFlags().StringVarP(&nodeFile,
"file",
"f",
cfgDir+"/node.yaml",
"/node.yaml",
"Alternative YAML file for node checks",
)

View File

@@ -25,30 +25,28 @@ import (
)
var (
cfgDir = "./cfg"
cfgFile string
jsonFmt bool
checkList string
groupList string
masterFile string
nodeFile string
federatedFile string
loud bool
kubeConfDir string
etcdConfDir string
flanneldConfDir string
installation string
envVarsPrefix = "KUBE_BENCH"
defaultKubeVersion = "1.6"
kubeVersion string
cfgFile string
cfgDir string
jsonFmt 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
var RootCmd = &cobra.Command{
Use: os.Args[0],
Short: "Run CIS Benchmarks checks against a Kubernetes deployment",
Long: `This tool runs the CIS Kubernetes 1.6 Benchmark v1.0.0 checks.`,
Long: `This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)`,
}
// Execute adds all child commands to the root command sets flags appropriately.
@@ -66,13 +64,13 @@ func Execute() {
func init() {
cobra.OnInitialize(initConfig)
// Output control
RootCmd.PersistentFlags().BoolVar(&noResults, "noresults", false, "Disable printing 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().StringVar(
&installation,
"installation",
"default",
"Specify how kubernetes cluster was installed. Possible values are default,hyperkube,kops,kubeadm",
)
RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL")
RootCmd.PersistentFlags().StringVarP(
&checkList,
"check",
@@ -88,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)
@@ -104,7 +104,7 @@ func initConfig() {
viper.AddConfigPath(cfgDir) // adding ./cfg as first search path
}
viper.SetEnvPrefix("KUBE_BENCH")
viper.SetEnvPrefix(envVarsPrefix)
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.

View File

@@ -4,12 +4,15 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/aquasecurity/kube-bench/check"
"github.com/fatih/color"
"github.com/golang/glog"
"github.com/spf13/viper"
)
var (
@@ -22,6 +25,14 @@ var (
}
)
var psFunc func(string) string
var statFunc func(string) (os.FileInfo, error)
func init() {
psFunc = ps
statFunc = os.Stat
}
func printlnWarn(msg string) {
fmt.Fprintf(os.Stderr, "[%s] %s\n",
colors[check.WARN].Sprintf("%s", check.WARN),
@@ -43,7 +54,7 @@ func exitWithError(err error) {
func continueWithError(err error, msg string) string {
if err != nil {
glog.V(1).Info(err)
glog.V(2).Info(err)
}
if msg != "" {
@@ -75,8 +86,126 @@ func ps(proc string) string {
return string(out)
}
// getBinaries finds which of the set of candidate executables are running
func getBinaries(v *viper.Viper) map[string]string {
binmap := make(map[string]string)
for _, component := range v.GetStringSlice("components") {
s := v.Sub(component)
if s == nil {
continue
}
optional := s.GetBool("optional")
bins := s.GetStringSlice("bins")
if len(bins) > 0 {
bin, err := findExecutable(bins)
if err != nil && !optional {
exitWithError(fmt.Errorf("need %s executable but none of the candidates are running", component))
}
// Default the executable name that we'll substitute to the name of the component
if bin == "" {
bin = component
glog.V(2).Info(fmt.Sprintf("Component %s not running", component))
} else {
glog.V(2).Info(fmt.Sprintf("Component %s uses running binary %s", component, bin))
}
binmap[component] = bin
}
}
return binmap
}
// getConfigFilePath locates the config files we should be using based on either the specified
// version, or the running version of kubernetes if not specified
func getConfigFilePath(specifiedVersion string, runningVersion string, filename string) (path string, err error) {
var fileVersion string
if specifiedVersion != "" {
fileVersion = specifiedVersion
} else {
fileVersion = runningVersion
}
glog.V(2).Info(fmt.Sprintf("Looking for config for version %s", fileVersion))
for {
path = filepath.Join(cfgDir, fileVersion)
file := filepath.Join(path, string(filename))
glog.V(2).Info(fmt.Sprintf("Looking for config file: %s\n", file))
if _, err = os.Stat(file); !os.IsNotExist(err) {
if specifiedVersion == "" && fileVersion != runningVersion {
glog.V(1).Info(fmt.Sprintf("No test file found for %s - using tests for Kubernetes %s\n", runningVersion, fileVersion))
}
return path, nil
}
// If we were given an explicit version to look for, don't look for any others
if specifiedVersion != "" {
return "", err
}
fileVersion = decrementVersion(fileVersion)
if fileVersion == "" {
return "", fmt.Errorf("no test files found <= runningVersion")
}
}
}
// decrementVersion decrements the version number
// We want to decrement individually even through versions where we don't supply test files
// just in case someone wants to specify their own test files for that version
func decrementVersion(version string) string {
split := strings.Split(version, ".")
minor, err := strconv.Atoi(split[1])
if err != nil {
return ""
}
if minor <= 1 {
return ""
}
split[1] = strconv.Itoa(minor - 1)
return strings.Join(split, ".")
}
// 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) map[string]string {
confmap := make(map[string]string)
for _, component := range v.GetStringSlice("components") {
s := v.Sub(component)
if s == nil {
continue
}
// See if any of the candidate config files exist
conf := findConfigFile(s.GetStringSlice("confs"))
if conf == "" {
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
glog.V(2).Info(fmt.Sprintf("Missing config file for %s", component))
conf = component
}
} else {
glog.V(2).Info(fmt.Sprintf("Component %s uses config file '%s'", component, conf))
}
confmap[component] = conf
}
return confmap
}
// verifyBin checks that the binary specified is running
func verifyBin(bin string, psFunc func(string) string) bool {
func verifyBin(bin string) bool {
// Strip any quotes
bin = strings.Trim(bin, "'\"")
@@ -87,68 +216,46 @@ func verifyBin(bin string, psFunc func(string) string) bool {
proc := strings.Fields(bin)[0]
out := psFunc(proc)
return strings.Contains(out, bin)
}
func verifyKubeVersion(major string, minor string) {
// These executables might not be on the user's path.
_, err := exec.LookPath("kubectl")
if err != nil {
continueWithError(err, sprintlnWarn("Kubernetes version check skipped"))
return
}
cmd := exec.Command("kubectl", "version")
out, err := cmd.Output()
if err != nil {
s := fmt.Sprintf("Kubernetes version check skipped with error %v", err)
continueWithError(err, sprintlnWarn(s))
if len(out) == 0 {
return
// There could be multiple lines in the ps output
// The binary needs to be the first word in the ps output, except that it could be preceded by a path
// e.g. /usr/bin/kubelet is a match for kubelet
// but apiserver is not a match for kube-apiserver
reFirstWord := regexp.MustCompile(`^(\S*\/)*` + bin)
lines := strings.Split(out, "\n")
for _, l := range lines {
if reFirstWord.Match([]byte(l)) {
return true
}
}
msg := checkVersion("Client", string(out), major, minor)
if msg != "" {
continueWithError(fmt.Errorf(msg), msg)
}
msg = checkVersion("Server", string(out), major, minor)
if msg != "" {
continueWithError(fmt.Errorf(msg), msg)
}
return false
}
var regexVersionMajor = regexp.MustCompile("Major:\"([0-9]+)\"")
var regexVersionMinor = regexp.MustCompile("Minor:\"([0-9]+)\"")
func checkVersion(x string, s string, expMajor string, expMinor string) string {
regexVersion, err := regexp.Compile(x + " Version: version.Info{(.*)}")
if err != nil {
return fmt.Sprintf("Error checking Kubernetes version: %v", err)
}
ss := regexVersion.FindString(s)
major := versionMatch(regexVersionMajor, ss)
minor := versionMatch(regexVersionMinor, ss)
if major == "" || minor == "" {
return fmt.Sprintf("Couldn't find %s version from kubectl output '%s'", x, s)
}
if major != expMajor || minor != expMinor {
return fmt.Sprintf("Unexpected %s version %s.%s", x, major, minor)
// fundConfigFile looks through a list of possible config files and finds the first one that exists
func findConfigFile(candidates []string) string {
for _, c := range candidates {
_, err := statFunc(c)
if err == nil {
return c
}
if !os.IsNotExist(err) {
exitWithError(fmt.Errorf("error looking for file %s: %v", c, err))
}
}
return ""
}
func versionMatch(r *regexp.Regexp, s string) string {
match := r.FindStringSubmatch(s)
if len(match) < 2 {
return ""
// findExecutable looks through a list of possible executable names and finds the first one that's running
func findExecutable(candidates []string) (string, error) {
for _, c := range candidates {
if verifyBin(c) {
return c, nil
}
glog.V(1).Info(fmt.Sprintf("executable '%s' not running", c))
}
return match[1]
return "", fmt.Errorf("no candidates running")
}
func multiWordReplace(s string, subname string, sub string) string {
@@ -159,3 +266,73 @@ func multiWordReplace(s string, subname string, sub string) string {
return strings.Replace(s, subname, sub, -1)
}
func getKubeVersion() (string, error) {
// These executables might not be on the user's path.
_, err := exec.LookPath("kubectl")
if err != nil {
_, err = exec.LookPath("kubelet")
if err != nil {
return "", fmt.Errorf("need kubectl or kubelet binaries to get kubernetes version")
}
return getKubeVersionFromKubelet(), nil
}
return getKubeVersionFromKubectl(), nil
}
func getKubeVersionFromKubectl() string {
cmd := exec.Command("kubectl", "version", "--short")
out, err := cmd.CombinedOutput()
if err != nil {
continueWithError(fmt.Errorf("%s", out), "")
}
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)
if len(subs) < 2 {
printlnWarn(fmt.Sprintf("Unable to get kubectl version, using default version: %s", defaultKubeVersion))
return defaultKubeVersion
}
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
if v == "" {
glog.V(2).Info(fmt.Sprintf("No subsitution for '%s'\n", subst))
continue
}
glog.V(2).Info(fmt.Sprintf("Substituting %s with '%s'\n", subst, v))
s = multiWordReplace(s, subst, v)
}
return s
}

View File

@@ -15,73 +15,30 @@
package cmd
import (
"regexp"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strconv"
"testing"
"github.com/spf13/viper"
)
func TestCheckVersion(t *testing.T) {
kubeoutput := `Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T09:51:01Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}`
cases := []struct {
t string
s string
major string
minor string
exp string
}{
{t: "Client", s: kubeoutput, major: "1", minor: "7"},
{t: "Server", s: kubeoutput, major: "1", minor: "7"},
{t: "Client", s: kubeoutput, major: "1", minor: "6", exp: "Unexpected Client version 1.7"},
{t: "Client", s: kubeoutput, major: "2", minor: "0", exp: "Unexpected Client version 1.7"},
{t: "Server", s: "something unexpected", major: "2", minor: "0", exp: "Couldn't find Server version from kubectl output 'something unexpected'"},
}
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
m := checkVersion(c.t, c.s, c.major, c.minor)
if m != c.exp {
t.Fatalf("Got: %s, expected: %s", m, c.exp)
}
})
}
}
func TestVersionMatch(t *testing.T) {
minor := regexVersionMinor
major := regexVersionMajor
client := `Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T09:51:01Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}`
server := `Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}`
cases := []struct {
r *regexp.Regexp
s string
exp string
}{
{r: major, s: server, exp: "1"},
{r: minor, s: server, exp: "7"},
{r: major, s: client, exp: "1"},
{r: minor, s: client, exp: "7"},
{r: major, s: "Some unexpected string"},
{r: minor}, // Checking that we don't fall over if the string is empty
}
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
m := versionMatch(c.r, c.s)
if m != c.exp {
t.Fatalf("Got %s expected %s", m, c.exp)
}
})
}
}
var g string
var e []error
var eIndex int
func fakeps(proc string) string {
return g
}
func fakestat(file string) (os.FileInfo, error) {
err := e[eIndex]
eIndex++
return nil, err
}
func TestVerifyBin(t *testing.T) {
cases := []struct {
proc string
@@ -95,14 +52,110 @@ func TestVerifyBin(t *testing.T) {
{proc: "cmd", psOut: "cmd param1 param2", exp: true},
{proc: "cmd param", psOut: "cmd param1 param2", exp: true},
{proc: "cmd param", psOut: "cmd", exp: false},
{proc: "cmd", psOut: "cmd x \ncmd y", exp: true},
{proc: "cmd y", psOut: "cmd x \ncmd y", exp: true},
{proc: "cmd", psOut: "/usr/bin/cmd", exp: true},
{proc: "cmd", psOut: "kube-cmd", exp: false},
{proc: "cmd", psOut: "/usr/bin/kube-cmd", exp: false},
}
psFunc = fakeps
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
g = c.psOut
v := verifyBin(c.proc)
if v != c.exp {
t.Fatalf("Expected %v got %v", c.exp, v)
}
})
}
}
func TestFindExecutable(t *testing.T) {
cases := []struct {
candidates []string // list of executables we'd consider
psOut string // fake output from ps
exp string // the one we expect to find in the (fake) ps output
expErr bool
}{
{candidates: []string{"one", "two", "three"}, psOut: "two", exp: "two"},
{candidates: []string{"one", "two", "three"}, psOut: "two three", exp: "two"},
{candidates: []string{"one double", "two double", "three double"}, psOut: "two double is running", exp: "two double"},
{candidates: []string{"one", "two", "three"}, psOut: "blah", expErr: true},
{candidates: []string{"one double", "two double", "three double"}, psOut: "two", expErr: true},
{candidates: []string{"apiserver", "kube-apiserver"}, psOut: "kube-apiserver", exp: "kube-apiserver"},
{candidates: []string{"apiserver", "kube-apiserver", "hyperkube-apiserver"}, psOut: "kube-apiserver", exp: "kube-apiserver"},
}
psFunc = fakeps
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
g = c.psOut
e, err := findExecutable(c.candidates)
if e != c.exp {
t.Fatalf("Expected %v got %v", c.exp, e)
}
if err == nil && c.expErr {
t.Fatalf("Expected error")
}
if err != nil && !c.expErr {
t.Fatalf("Didn't expect error: %v", err)
}
})
}
}
func TestGetBinaries(t *testing.T) {
cases := []struct {
config map[string]interface{}
psOut string
exp map[string]string
}{
{
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}},
psOut: "kube-apiserver",
exp: map[string]string{"apiserver": "kube-apiserver"},
},
{
// "thing" is not in the list of components
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
psOut: "kube-apiserver thing",
exp: map[string]string{"apiserver": "kube-apiserver"},
},
{
// "anotherthing" in list of components but doesn't have a defintion
config: map[string]interface{}{"components": []string{"apiserver", "anotherthing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
psOut: "kube-apiserver thing",
exp: map[string]string{"apiserver": "kube-apiserver"},
},
{
// more than one component
config: map[string]interface{}{"components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
psOut: "kube-apiserver \nthing",
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
},
{
// default binary to component name
config: map[string]interface{}{"components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}, "optional": true}},
psOut: "kube-apiserver \notherthing some params",
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
},
}
v := viper.New()
psFunc = fakeps
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
g = c.psOut
v := verifyBin(c.proc, fakeps)
if v != c.exp {
t.Fatalf("Expected %v got %v", c.exp, v)
for k, val := range c.config {
v.Set(k, val)
}
m := getBinaries(v)
if !reflect.DeepEqual(m, c.exp) {
t.Fatalf("Got %v\nExpected %v", m, c.exp)
}
})
}
@@ -129,3 +182,171 @@ func TestMultiWordReplace(t *testing.T) {
})
}
}
func TestKubeVersionRegex(t *testing.T) {
ver := getVersionFromKubectlOutput(`Client Version: v1.8.0
Server Version: v1.8.12
`)
if ver != "1.8" {
t.Fatalf("Expected 1.8 got %s", ver)
}
ver = getVersionFromKubectlOutput("Something completely different")
if ver != "1.6" {
t.Fatalf("Expected 1.6 got %s", ver)
}
}
func TestFindConfigFile(t *testing.T) {
cases := []struct {
input []string
statResults []error
exp string
}{
{input: []string{"myfile"}, statResults: []error{nil}, exp: "myfile"},
{input: []string{"thisfile", "thatfile"}, statResults: []error{os.ErrNotExist, nil}, exp: "thatfile"},
{input: []string{"thisfile", "thatfile"}, statResults: []error{os.ErrNotExist, os.ErrNotExist}, exp: ""},
}
statFunc = fakestat
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
e = c.statResults
eIndex = 0
conf := findConfigFile(c.input)
if conf != c.exp {
t.Fatalf("Got %s expected %s", conf, c.exp)
}
})
}
}
func TestGetConfigFiles(t *testing.T) {
cases := []struct {
config map[string]interface{}
exp map[string]string
statResults []error
}{
{
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}},
statResults: []error{os.ErrNotExist, nil},
exp: map[string]string{"apiserver": "kube-apiserver"},
},
{
// Component "thing" isn't included in the list of components
config: map[string]interface{}{
"components": []string{"apiserver"},
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}},
statResults: []error{os.ErrNotExist, nil},
exp: map[string]string{"apiserver": "kube-apiserver"},
},
{
// More than one component
config: map[string]interface{}{
"components": []string{"apiserver", "thing"},
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}},
statResults: []error{os.ErrNotExist, nil, nil},
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "/my/file/thing"},
},
{
// Default thing to specified default config
config: map[string]interface{}{
"components": []string{"apiserver", "thing"},
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}, "defaultconf": "another/thing"}},
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "another/thing"},
},
{
// Default thing to component name
config: map[string]interface{}{
"components": []string{"apiserver", "thing"},
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}},
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
},
}
v := viper.New()
statFunc = fakestat
for id, c := range cases {
t.Run(strconv.Itoa(id), func(t *testing.T) {
for k, val := range c.config {
v.Set(k, val)
}
e = c.statResults
eIndex = 0
m := getConfigFiles(v)
if !reflect.DeepEqual(m, c.exp) {
t.Fatalf("Got %v\nExpected %v", m, c.exp)
}
})
}
}
func TestMakeSubsitutions(t *testing.T) {
cases := []struct {
input string
subst map[string]string
exp string
}{
{input: "Replace $thisbin", subst: map[string]string{"this": "that"}, exp: "Replace that"},
{input: "Replace $thisbin", subst: map[string]string{"this": "that", "here": "there"}, exp: "Replace that"},
{input: "Replace $thisbin and $herebin", subst: map[string]string{"this": "that", "here": "there"}, exp: "Replace that and there"},
}
for _, c := range cases {
t.Run(c.input, func(t *testing.T) {
s := makeSubstitutions(c.input, "bin", c.subst)
if s != c.exp {
t.Fatalf("Got %s expected %s", s, c.exp)
}
})
}
}
func TestGetConfigFilePath(t *testing.T) {
var err error
cfgDir, err = ioutil.TempDir("", "kube-bench-test")
if err != nil {
t.Fatalf("Failed to create temp directory")
}
defer os.RemoveAll(cfgDir)
d := filepath.Join(cfgDir, "1.8")
err = os.Mkdir(d, 0666)
if err != nil {
t.Fatalf("Failed to create temp file")
}
ioutil.WriteFile(filepath.Join(d, "master.yaml"), []byte("hello world"), 0666)
cases := []struct {
specifiedVersion string
runningVersion string
succeed bool
exp string
}{
{runningVersion: "1.8", succeed: true, exp: d},
{runningVersion: "1.9", succeed: true, exp: d},
{runningVersion: "1.10", succeed: true, exp: d},
{runningVersion: "1.1", succeed: false},
{specifiedVersion: "1.8", succeed: true, exp: d},
{specifiedVersion: "1.9", succeed: false},
{specifiedVersion: "1.10", succeed: false},
}
for _, c := range cases {
t.Run(c.specifiedVersion+"-"+c.runningVersion, func(t *testing.T) {
path, err := getConfigFilePath(c.specifiedVersion, c.runningVersion, "/master.yaml")
if err != nil && c.succeed {
t.Fatalf("Error %v", err)
}
if path != c.exp {
t.Fatalf("Got %s expected %s", path, 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