Compare commits

...

246 commits

Author SHA1 Message Date
Thomas Sjögren
ff26d67f25
Merge pull request from cyphar/dist-libexec
dist: adjust script imports to be able to use /usr/libexec
2024-10-21 09:26:06 +02:00
Aleksa Sarai
a18798fcfa
dist: adjust script imports to be able to use /usr/libexec
In order to make installation easier for distributions, make all script
imports based on a single variable that distributions can adjust based
on how the script is packaged for each distribution.

Ideally we would actually install the script in /usr/libexec rather than
/ in our Dockerfile, but this is a simpler fix that still lets you run
the script from the repo directory.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-10-18 17:43:13 +11:00
Thomas Sjögren
5c42b8ad5f
Merge pull request from spedersen-emailage/log-level-fix
modified get_docker_configuration_file_args jq command to remove null response
2024-05-16 16:35:13 +02:00
Sean Pedersen
c4b7d36042 modified get_docker_configuration_file_args jq command to remove \'null\' return 2024-05-15 10:21:02 -07:00
Thomas Sjögren
23110269a6
Merge pull request from konstruktoid/issue548
include /run in get_service_file
2024-04-16 18:12:13 +02:00
Thomas Sjögren
c495b3a774
Merge pull request from konstruktoid/gha
update github action
2024-04-16 10:24:28 +02:00
Thomas Sjögren
12f085d42f
update SLSA action
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2024-04-16 08:23:14 +00:00
Thomas Sjögren
966929427e correct tests and instructions
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2024-04-16 07:32:23 +00:00
Thomas Sjögren
5d5ca0a3da
correct tests and instructions
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2024-04-16 07:29:45 +00:00
Thomas Sjögren
287fd8774b
systemctl always returns an FragmentPath
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2024-04-12 08:17:17 +00:00
Thomas Sjögren
e081393ad7
include /run in get_service_file
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2024-04-11 21:45:15 +00:00
Thomas Sjögren
820abe98c3
Merge pull request from konstruktoid/issue538
check if restart policy is 5 or less
2024-02-11 11:25:09 +01:00
Thomas Sjögren
ba0b402ea5
Merge pull request from martipoe/master
Update check ID and add check groups for CIS Controls v8 (v1.6.0 - 06-14-2023)
2023-12-20 15:41:02 +01:00
MaPoe
684512b888 feat: check groups for CIS Controls v8 IG1-3 mapped recommendations 2023-12-17 16:45:13 +01:00
MaPoe
958f5fa6c3 feat: update swarm mode check id from 7.1 to 5.1 2023-12-17 15:57:54 +01:00
Thomas Sjögren
0fd702afed
Merge pull request from UlisesGascon/fix/pin-dependency
feat: use SHA instead of tags for base image
2023-11-19 22:04:37 +00:00
Ulises Gascón
8bbdaf6540
feat: use SHA instead of tags for base image 2023-11-19 21:08:05 +01:00
Thomas Sjögren
4edccd7859
Merge pull request from halfluke/fix537
fix537
2023-10-23 09:45:55 +00:00
halfluke
8d97756c62 fix537_proper 2023-10-21 01:55:29 +01:00
halfluke
b6e4380937 fix537 2023-10-21 01:43:46 +01:00
Thomas Sjögren
7287a35a21
Merge pull request from ismailarilik/patch-1
"above" -> "below"
2023-10-06 07:13:44 +00:00
İsmail Arılık
5c647c1b86
"above" -> "below"
It is not above but below.
2023-10-06 08:51:33 +03:00
Thomas Sjögren
e680ab2465
update restart_policy w/o swarm
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-09-25 15:29:45 +00:00
Thomas Sjögren
ab2190819d
check if restart policy is 5 or less
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-09-25 09:05:44 +00:00
Thomas Sjögren
b7a5284ce4
Merge pull request from konstruktoid/v160
Update version v1.6.0
2023-08-25 14:38:42 +02:00
Thomas Sjögren
8da1cc26df
v1.6.0
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-08-25 12:37:35 +00:00
Thomas Sjögren
9120d426ce
Merge pull request from konstruktoid/issue532
Fix image sprawl miscalculation
2023-08-25 14:18:55 +02:00
Thomas Sjögren
26f80fb331
Fix image sprawl miscalculation
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-08-25 12:17:48 +00:00
Thomas Sjögren
5555c37560
Merge pull request from lekpamartin/master
add label filtering config
2023-07-26 17:51:28 +00:00
LEKPA Martin
8ea918620e update doc 2023-07-26 18:47:50 +02:00
Martin LEKPA
59fe573db2
update help 2023-07-25 21:38:20 +02:00
Martin LEKPA
2dfb1bac51
Update README.md 2023-07-25 21:37:03 +02:00
LEKPA Martin
223baf94d1 update doc 2023-07-21 18:53:01 +02:00
Thomas Sjögren
d9f1d02102
Merge pull request from andreagalle/issue_521_restart_policy
Issue 521 restart policy
2023-07-07 19:16:48 +00:00
LEKPA Martin
bfbeda9263 add label filtering config 2023-07-01 11:19:04 +02:00
Thomas Sjögren
1f9933a867
Merge pull request from konstruktoid/issue527
tr is required, not truncate
2023-06-13 11:55:41 +02:00
Thomas Sjögren
d6005f0211
tr is required, not truncate
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-06-13 09:54:22 +00:00
Thomas Sjögren
26dc83ed28
Merge pull request from konstruktoid/docker
update Docker container instructions, remove out-of-date Dockerfiles
2023-06-02 22:18:33 +00:00
Thomas Sjögren
2647070692
update Docker container instructions, remove out-of-date Dockerfiles
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-06-02 22:16:31 +00:00
Thomas Sjögren
1d29a1f405
Merge pull request from brsolomon-deloitte/bugfix/get_docker_configuration_file_args
fix: allow get_docker_configuration_file_args to parse minified json
2023-06-02 21:46:09 +00:00
Brad Solomon
523556b4ac move HAVE_JQ into req_programs 2023-06-02 17:36:29 -04:00
Brad Solomon
79407ce361 remove non-universal tr -u flag 2023-06-02 17:26:21 -04:00
Brad Solomon
39963dad60 fix: allow get_docker_configuration_file_args to parse minified json
Closes .
2023-06-02 09:18:42 -04:00
andreagalle
0dc2d2b1e6 should fix the: Error response from daemon: This node is not a swarm manager. issue 2023-04-26 07:04:53 +00:00
andreagalle
412f514bb4 just a typo 2023-04-12 14:51:01 +00:00
andreagalle
f97b420af9 couple typos & performance improvements 2023-04-12 14:46:13 +00:00
andreagalle
c8c90ee523 checking for the MaxAttempts=5 too at service level 2023-04-12 13:27:36 +00:00
Thomas Sjögren
16c235080d
Merge pull request from konstruktoid/gha
update slsa gha permissions
2023-03-15 17:12:35 +01:00
Thomas Sjögren
9bf4dea527
update slsa gha permissions
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-15 17:11:38 +01:00
Thomas Sjögren
93227bf6c0
Merge pull request from konstruktoid/readme
fix version in readme
2023-03-15 16:52:18 +01:00
Thomas Sjögren
d0ccaca6a9
Merge pull request from konstruktoid/issuegha
update issue assignment gha
2023-03-15 16:51:53 +01:00
Thomas Sjögren
949c6a034a
fix version in readme
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-15 16:51:15 +01:00
Thomas Sjögren
f16cd8dd62
update Issue assignment gha
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-15 16:50:08 +01:00
Thomas Sjögren
6dad6fc405
Merge pull request from konstruktoid/slsa
update slsa gha
2023-03-15 16:47:32 +01:00
Thomas Sjögren
df36db7a70
update slsa gha
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-15 16:46:47 +01:00
Thomas Sjögren
5a450fc5ba
Merge pull request from konstruktoid/rel
update image
2023-03-15 16:43:19 +01:00
Thomas Sjögren
956ca6bb34
update image
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-15 16:41:10 +01:00
Thomas Sjögren
faa0e88479
slsa gha
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-13 15:52:27 +01:00
Thomas Sjögren
41a44f54d3
Merge pull request from konstruktoid/helper
update yell helper with correct version
2023-03-06 13:17:53 +01:00
Thomas Sjögren
316b610178
update yell helper with correct version
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-06 13:17:11 +01:00
Thomas Sjögren
dde48fc185
Merge pull request from konstruktoid/version150
update version and add version table
2023-03-06 13:11:50 +01:00
Thomas Sjögren
e82fa2cf5d
update version and add version table
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-06 13:11:02 +01:00
Thomas Sjögren
ce38d3dd3c
Merge pull request from konstruktoid/150
align tests to CIS Docker Benchmark 1.5.0
2023-03-06 13:01:33 +01:00
Thomas Sjögren
cbd07bb051
align tests to CIS Benchmark 1.5.0
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-03-06 12:59:56 +01:00
Thomas Sjögren
f375045741
Merge pull request from konstruktoid/issue510
add support for .NanoCpus
2023-02-02 22:12:27 +01:00
Thomas Sjögren
75ccbc78a3
Merge pull request from QuentinServais/fix/check_2_7_TLS
Fix check_2_7 TLS  check with json config
2023-02-02 11:49:10 +01:00
Thomas Sjögren
941518887b
add support for .NanoCpus
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2023-02-02 11:47:18 +01:00
QuentinServais
ee718c40c0
Fix check_2_7 TLS check with json config 2022-12-27 23:39:17 +01:00
Thomas Sjögren
5a8d6434e6
Merge pull request from docker/atomist/pin-docker-base-image/distros/dockerfile.debian
Pin Docker base image in distros/Dockerfile.debian
2022-10-05 15:13:31 +02:00
Atomist Bot
553c11f3a9 Pin Docker image debian:sid
debian:sid
->
debian:sid@sha256:022a3cafe84d704c272794863ca5e383667c99312358e816ad1ff6e9a41ce4f6

 [atomist:generated]
 [atomist-skill:atomist/docker-base-image-policy]

Signed-off-by: Atomist Bot <bot@atomist.com>
2022-10-05 13:00:43 +00:00
Thomas Sjögren
8ccd83a6f0
Merge pull request from gavinmporter/bsd-sed-fix
Fix sed commands for BSD sed
2022-07-19 13:42:49 +02:00
Gavin Porter
b29f676bbb Fix sed commands for BSD sed 2022-07-19 11:11:19 +12:00
Thomas Sjögren
44fdceb331
Merge pull request from konstruktoid/issue498
grep host* in config file before testing 2.7
2022-05-23 11:31:04 +02:00
Thomas Sjögren
558fca319f grep host* in config file before testing 2.7
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-05-09 12:26:01 +02:00
Thomas Sjögren
7c7390e723
Merge pull request from konstruktoid/vagrant
add Vagrantfile
2022-04-30 12:05:22 +02:00
Thomas Sjögren
d4c4538bc8 add Vagrantfile
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-04-30 12:03:57 +02:00
Thomas Sjögren
58e732f3d1
Merge pull request from konstruktoid/action
add github actions
2022-04-30 12:01:23 +02:00
Thomas Sjögren
bb032f154a add github actions
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-04-30 12:00:35 +02:00
Thomas Sjögren
cd1619c375
Merge pull request from konstruktoid/version
Version
2022-03-07 13:40:44 +01:00
Thomas Sjögren
3cfa505ecc update version information
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-03-07 13:39:45 +01:00
Thomas Sjögren
3fe40815ee ignore Vagrant files
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-03-07 13:39:22 +01:00
Thomas Sjögren
d44c2a9d47
Merge pull request from konstruktoid/artifactvalidation
add 4.12 check
2022-03-07 13:06:06 +01:00
Thomas Sjögren
68c8e53dac add 4.12 check
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-03-07 13:05:22 +01:00
Thomas Sjögren
715de9c607
Merge pull request from jammasterj89/master
Update alpine to 3.15
2022-01-11 14:01:36 +01:00
jammasterj89
975820f52b
Update alpine to 3.15
Updated alpine version to latest - 3.15

Signed-off-by: Niall T <19202716+jammasterj89@users.noreply.github.com>
2022-01-11 12:34:38 +00:00
Thomas Sjögren
d33139cedc
Merge pull request from konstruktoid/imagenotice
add note regarding docker image
2022-01-06 21:33:48 +01:00
Thomas Sjögren
5c7acd72a5 add note regarding docker image
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2022-01-06 21:32:59 +01:00
Thomas Sjögren
1ff4a62836
Merge pull request from konstruktoid/ISSUE492
if configured with no-new-privileges, pass check 5.25
2021-12-16 10:36:23 +01:00
Thomas Sjögren
0d5874877b if the docker daemon is configure with no-new-privileges, pass check 5.25
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-12-02 11:10:12 +01:00
Thomas Sjögren
3f3ff4fb2d
Merge pull request from SericaLaw/fix-check-5-3
fix style and false warning in check_5_3
2021-12-01 10:49:06 +01:00
serica
0ae544dd03 fix style and false warning in check_5_3 2021-11-30 18:38:36 -08:00
Thomas Sjögren
ec211a3277
Merge pull request from joaocfernandes/fix_typos
Fix description typos
2021-11-12 10:07:56 +01:00
João Fernandes
a409e03d99
Fix typo in check_5_21 2021-11-11 20:39:22 +00:00
João Fernandes
7e89ea067d
Fix typo in check_4_11
Fix the text description for check_4_11 .
2021-11-11 20:39:00 +00:00
Thomas Sjögren
ec3ddf2acd
Merge pull request from nikitastupin/feature-list-open-ports
Implement listing of open ports
2021-10-31 12:50:27 +01:00
Thomas Sjögren
fd93a6ee93
Merge pull request from nikitastupin/feature-specific-capability-checks
Add checks for capabilities that allows container escape
2021-10-31 12:26:40 +01:00
Thomas Sjögren
a40b888ee9
Merge pull request from garettmd/master
Add /etc/hostname fix for macOS
2021-10-01 22:04:59 +02:00
Garett Dunn
8ac4513d24
Add /etc/hostname fix for macOS 2021-10-01 11:39:17 -04:00
Thomas Sjögren
1891eaa8b3
Merge pull request from AErmie/patch-1
Updated log file name
2021-09-30 15:23:24 +02:00
Adin Ermie
d98a054c2f
Updated log file name
From testing, the default logfile name is `docker-bench-security.log.json` not `docker-bench-security.sh.log.json`
2021-09-30 09:02:41 -04:00
Thomas Sjögren
f656a5d683
Merge pull request from AErmie/patch-1
Added multiple check groups example
2021-09-29 10:20:25 +02:00
Adin Ermie
e6a742ba38
Added multiple check groups example
Added an example of running multiple groups of checks, as the documentation did not clearly show this is possible (and the proper syntax).
2021-09-28 17:51:40 -04:00
Thomas Sjögren
dfb3a90f67
Merge pull request from konstruktoid/ISSUE477
fix socket check
2021-07-12 21:55:31 +00:00
Thomas Sjögren
683c5a92b5 fix socket check
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-07-12 15:22:12 +02:00
Nikita Stupin
cf93e9ed07 Add checks for capabilities that allows container escape 2021-07-08 13:10:12 +03:00
Nikita Stupin
dacc7372bf Implement listing of open ports 2021-07-08 13:00:21 +03:00
Thomas Sjögren
2024e16f09
Merge pull request from denhamparry/master
fix: set docker-bench-security to sh
2021-07-07 11:05:42 +00:00
Lewis Denham-Parry
e31e7aa0ae
fix: set docker-bench-security to sh
- Set script to execute with sh rather than bash
- Set CMD Dockerfile to use /bin/sh
2021-07-07 08:22:59 +01:00
Thomas Sjögren
c6256295fc
Merge pull request from aagot/master
Update 2_docker_daemon_configuration.sh
2021-06-26 16:14:39 +00:00
aagot
08a7b09d4d
Update 2_docker_daemon_configuration.sh 2021-06-25 14:38:02 +02:00
Thomas Sjögren
3769a64a2f
Merge pull request from konstruktoid/v131
Initial v1.3.1 PR
2021-05-25 18:52:43 +00:00
Thomas Sjögren
c1457e6ad3 initial commit of tests/99_community_checks.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
32c5e5f1fb initial commit of tests/8_docker_enterprise_configuration.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
4e379bbaf9 initial commit of tests/7_docker_swarm_configuration.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
3a9deae328 initial commit of tests/6_docker_security_operations.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
bd05445528 initial commit of tests/5_container_runtime.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
28fa0393da initial commit of tests/4_container_images.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:46 +02:00
Thomas Sjögren
6f574b07c1 initial commit of tests/3_docker_daemon_configuration_files.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:45 +02:00
Thomas Sjögren
6a685524eb initial commit of tests/2_docker_daemon_configuration.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:45 +02:00
Thomas Sjögren
4a4ae81a03 initial commit of tests/1_host_configuration.sh v1.3.1
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:49:45 +02:00
Thomas Sjögren
ca4ef8fa57 linting
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:46:07 +02:00
Thomas Sjögren
2466ab4826 update wording
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:45:38 +02:00
Thomas Sjögren
17026093f1 update check functions and remove docker_enterprise_configuration from default
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:45:20 +02:00
Thomas Sjögren
cff5d7f32c wording and set printremediation="0"
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:44:18 +02:00
Thomas Sjögren
addefc6ee4 update documentation
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2021-05-25 20:43:33 +02:00
Thomas Sjögren
6a8fdcf72e
Merge pull request from razvanstoica89/master
Small improvement of user experience
2021-04-27 08:46:53 +00:00
Razvan Stoica
0a59baa9fb Change "Impact" to "Remediation Impact" in bash log 2021-04-19 09:51:48 +03:00
Razvan Stoica
e4d9bd1556 Set remediationImpact for 5.31 test to None. 2021-04-14 11:17:22 +03:00
Razvan Stoica
15aa1eecd5 Update remediation impact message for test 5.31 2021-04-14 10:58:53 +03:00
Razvan Stoica
38ac7ef8d8 Fix the printing error when using bash 2021-04-10 12:01:33 +03:00
Razvan Stoica
c67469d96b Fix systemctl error when running inside a container 2021-03-29 16:20:01 +03:00
Razvan Stoica
81ac358e82 Remove temporary files 2021-03-29 15:32:34 +03:00
Razvan Stoica
d0443cc817 Bug fixing and improving source code readability 2021-03-29 15:22:14 +03:00
Razvan Stoica
86985f854f Overwrite the json log at each run. Beautify the json log. 2021-03-28 11:08:15 +03:00
Razvan Stoica
8a934aebf1 Remove the Debian family-specific installation command 2021-03-28 09:47:49 +03:00
Razvan Stoica
4b68c2e040 Rename logs without the .sh extension 2021-03-27 09:36:10 +02:00
Razvan Stoica
f31e60c379 Add more remediation stuff 2021-03-22 09:43:56 +02:00
Razvan Stoica
c8721c90fa Displays the correct current time 2021-03-19 13:51:31 +02:00
Razvan Stoica
68cb493117 Log the remediation measure in JSON file only if the -p flag is not set 2021-03-19 09:29:55 +02:00
Razvan Stoica
cc8171fbfe Add remediation stuff on enterprise configuration 2021-03-18 10:32:02 +02:00
Razvan Stoica
3a7fe3bb24 Add remediation stuff on swarm configuration 2021-03-18 10:31:22 +02:00
Razvan Stoica
25de0bd826 Add remediation stuff on security operations 2021-03-18 10:30:30 +02:00
Razvan Stoica
c05c58674a Add remediation stuff on daemon configuration 2021-03-18 10:29:28 +02:00
Razvan Stoica
7e89fdd364 Add remediation stuff on host configuration 2021-03-18 10:28:45 +02:00
Razvan Stoica
68bcd14fb3 Increase version 2021-03-17 14:05:48 +02:00
Razvan Stoica
e5efe2bf40 Add explanations for newly added features 2021-03-16 10:13:31 +02:00
Razvan Stoica
091b4b954a Add option to specify trusted users. Add option to disable the printing of remediation measures. 2021-03-16 10:11:29 +02:00
Razvan Stoica
9722e5d89a Move the help scripts to a dedicated folder 2021-03-16 10:07:48 +02:00
Razvan Stoica
7144b947de Tests update 2021-03-16 10:05:49 +02:00
Razvan Stoica
ca03a37db6 Remove duplicate Dockerfile 2021-03-16 10:00:45 +02:00
Razvan Stoica
b757aa7334 Connection to the apk repositories is HTTPS by default 2021-03-16 09:58:57 +02:00
Razvan Stoica
2986d618f4 Ignore all. Whitelist only essential things. 2021-03-16 09:53:32 +02:00
Razvan Stoica
ee5972cb69 Add new folders to improve code segmentation 2021-03-16 09:50:12 +02:00
Razvan Stoica
bf11d68522 Add new check groups 2021-03-11 16:17:11 +02:00
Razvan Stoica
11886d47d8 Fixed invalid JSON log 2021-03-11 15:00:12 +02:00
Razvan Stoica
82ecb7e089 README file updated with new default logs location 2021-03-11 13:29:15 +02:00
Razvan Stoica
ed23f2d285 Change default log locations 2021-03-11 13:24:58 +02:00
Razvan Stoica
ad62371ace Move all pictures to a dedicated folder 2021-03-11 13:12:05 +02:00
Razvan Stoica
59a63dd49a Print more details in help message 2021-03-11 10:21:13 +02:00
Razvan Stoica
c623d3afdd Print the remediation measure only if the check is not passed 2021-03-11 09:32:29 +02:00
Razvan Stoica
b3a36e8d94 Print Section B only if it contains remediation measures 2021-03-11 09:26:31 +02:00
Razvan Stoica
82bbe1d562 Update benchmark log photo 2021-03-11 09:12:46 +02:00
Razvan Stoica
1623c4585e Set a relative image link 2021-03-11 08:34:55 +02:00
Razvan Stoica
85117ea1a2 Improve wording 2021-03-11 08:30:01 +02:00
Razvan Stoica
f769a32e9b Update benchmark log photo 2021-03-11 08:26:35 +02:00
Razvan Stoica
6c586b4e08 Print remediation measures at the end of the logs 2021-03-10 21:47:52 +02:00
Razvan Stoica
9ae0d92b5d Fix "nohealthlocal: command not found" error 2021-03-10 14:58:58 +02:00
Razvan Stoica
2132b03b92 Usage instructions aligned between the README.md and docker-bench-security.sh files 2021-03-10 10:01:18 +02:00
Razvan Stoica
c00ef4330b Add details about remediations measure for host configuration tests 2021-03-09 21:43:25 +02:00
Razvan Stoica
58205d4ef5 Add new programs to the list of required programs 2021-03-09 17:50:00 +02:00
Razvan Stoica
519f20befd Append JSON logs when run multiple times 2021-03-09 16:06:38 +02:00
Razvan Stoica
c3511209f9 Add support for logging remediation measures in JSON format 2021-03-09 13:35:40 +02:00
Razvan Stoica
8e0daa11de Print date and time in ISO 8601 UTC format 2021-03-09 13:27:32 +02:00
Razvan Stoica
94900eedb9 Change global variable used only locally to local variable for simplification 2021-03-09 12:42:48 +02:00
Thomas Sjögren
1aa919e918
Merge pull request from razvanstoica89/master
Add current year to the copyright header
2021-03-08 11:45:13 +00:00
Razvan Stoica
4b4fdd9f77
Add current year to the copyright header 2021-03-08 13:38:07 +02:00
Thomas Sjögren
c8984e9591
Merge pull request from archaeogeek/patch-2
Update 4_container_images.sh
2021-02-25 22:10:39 +00:00
Jo Cook
e9b9bfd270
Update 4_container_images.sh
Correcting an extremely minor grammatical error (sorry)
2021-02-25 19:04:05 +00:00
Thomas Sjögren
dcf478884b
Merge pull request from archaeogeek/patch-1
Update README.md
2021-02-23 20:28:31 +00:00
Jo Cook
3732a475cb
Update README.md
Extended my two edits to specify that they only apply if running in a container.
2021-02-23 17:25:12 +00:00
Jo Cook
cf7c50bf33
Update README.md
Clarified that log files are created inside the container so that new users (ie me) don't spend ages wondering where the logs are!
2021-02-23 12:15:22 +00:00
Thomas Sjögren
7c881b4b0b
Merge pull request from jammasterj89/master
Fix check_2 to -le 644
2021-01-15 13:39:29 +00:00
jammasterj89
f8c9b0fd5b
Replace multiple -eq with -le
Replace multiple -eq with -le for file permission checks. Except for line 228 which uses slightly different logic so is -ge.

Signed-off-by: Niall T 19202716+jammasterj89@users.noreply.github.com
2021-01-15 11:20:59 +00:00
jammasterj89
47e4cc173c
Fix check_2 to -le 644
Issue  raised that check_2 was only checking for 644 or 600 permissions, this now checks for anything less than or equal to 644.

Signed-off-by: Niall T 19202716+jammasterj89@users.noreply.github.com
2021-01-15 10:29:11 +00:00
Thomas Sjögren
8bd04d683f
Merge pull request from jammasterj89/master
Update alpine to 3.13.0
2021-01-15 10:21:31 +00:00
Thomas Sjögren
d3d25c8fc8
Update Dockerfile
Co-authored-by: Sebastiaan van Stijn <thaJeztah@users.noreply.github.com>
2021-01-15 10:20:35 +00:00
jammasterj89
f47f61538e
Update alpine to 3.13.0
Updated alpine version to latest - 3.13.0

Signed-off-by: Niall T <19202716+jammasterj89@users.noreply.github.com>
2021-01-15 09:30:14 +00:00
Thomas Sjögren
75fe107048
Merge pull request from sa7mon/patch-1
Grammar fixes in README
2020-11-30 16:26:33 +00:00
Dan Salmon
b7d8805ce1
Update README.md
Grammar fixes
2020-11-30 14:44:00 +00:00
Thomas Sjögren
ca0db8898f
Merge pull request from Constantin07/do_not_leave_dangling_container_after_run
Remove container after run.
2020-11-18 09:22:08 +00:00
Constantin Bugneac
1ea667f2f0 Remove container after run. 2020-11-17 21:49:07 +00:00
Thomas Sjögren
6ad1a1ef77
Merge pull request from konstruktoid/imgname
print img if empty RepoTags, and fix tabbing
2020-11-02 08:27:59 +00:00
Thomas Sjögren
3877abd975 print img if empty RepoTags, and fix tabbing
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-11-02 09:26:20 +01:00
Thomas Sjögren
93c619f018
Merge pull request from thaJeztah/no_experimental
Deprecate rule 2.16 for Docker > 19.03
2020-10-02 17:31:15 +00:00
Sebastiaan van Stijn
0f3dfe70fe
Deprecate rule 2.16 for Docker > 19.03
The upcoming 20.x docker release will always have experimental features
enabled, which will stop this test from working.

More details can be found in docker/cli##2774

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-02 18:01:57 +02:00
Thomas Sjögren
f3e9c791ce
Merge pull request from markdumay/partition
Support user namespaces in partition check (1.2.1)
2020-09-29 11:24:17 +00:00
mark
d85c73316a Updated mountpoint check to support user namespace 2020-09-29 12:41:25 +02:00
mark
919816dbbf Changed to 'df' to support user namespaces 2020-09-28 08:04:17 +02:00
Thomas Sjögren
b6478e9367
Merge pull request from draios/limit-num-items-reported
Limit the number of reported items
2020-07-13 11:22:49 +00:00
Mark Stemm
4cfb58f675 Limit the number of reported items
In some evironments, there may be a very large number of images,
containers, etc not satisfying a given test. For example, in one
environment, we saw *378k* images not satisfying 4.6, mostly because
the customer was never cleaning up old images.

To avoid overly long lists of items, add a new option "-n LIMIT" that
limits the number of items included in JSON output. When the limit is
reached, the list will be truncated and a trailing (truncated) will be
added. Here's an example:

```
{"id": "5.9", "desc": "Ensure the host's network namespace is not
shared", "result": "WARN", "details": "Containers running with
networking mode 'host':  k8s_POD_storage-provisioner_kube-system_ef960ef5-62c5-11e9-802f-08002719228f_0
k8s_POD_kube-proxy-xfln8_kube-system_ee70c4c3-62c5-11e9-802f-08002719228f_0 (truncated)",
"items":
["k8s_POD_storage-provisioner_kube-system_ef960ef5-62c5-11e9-802f-08002719228f_0","k8s_POD_kube-proxy-xfln8_kube-system_ee70c4c3-62c5-11e9-802f-08002719228f_0","(truncated)"]},
```

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2020-07-10 13:00:29 -07:00
Thomas Sjögren
41593e80d0
Merge pull request from roman-mueller/fix_description
Remove prefix of check ID in description
2020-06-02 14:10:21 +00:00
Roman Mueller
b3182ca8f5 Remove prefix of check ID 2020-06-02 15:57:33 +02:00
Thomas Sjögren
d6969dd2a4
Merge pull request from konstruktoid/alpine
alpine:3.12
2020-06-01 07:31:05 +00:00
Thomas Sjögren
aa984c44db alpine:3.12
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-06-01 09:30:09 +02:00
Thomas Sjögren
1e0a10b71f
Merge pull request from konstruktoid/macnetstat
more flexible binary usage, better support for mac os
2020-05-08 11:10:57 +00:00
Thomas Sjögren
8aec461d46 more flexible binary usage, better support for mac os
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-05-08 13:09:52 +02:00
Thomas Sjögren
375d32c0db
Merge pull request from konstruktoid/scoring
map desc_ to benchmark headings
2020-05-08 10:41:41 +00:00
Thomas Sjögren
98acc66436 map desc_ to benchmark headings
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-05-08 12:38:08 +02:00
Thomas Sjögren
735938a8f1
Merge pull request from HristoStoyanovMM/CIS_Level1_only_checks
Add CIS Level 1 only functions
2020-05-08 08:46:28 +00:00
herc1
4612146563 Add CIS Level 1 only functions
Signed-off-by: HristoStoyanovMM <hristo.stoyanov@mentormate.com>
2020-05-07 19:44:56 +03:00
Thomas Sjögren
79ef925df1
Merge pull request from konstruktoid/ISSUE422b
by an appropriate
2020-04-17 11:12:51 +00:00
Thomas Sjögren
5210cc9ff9 by an appropriate
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-04-17 13:11:37 +02:00
Thomas Sjögren
d32d4f3ce3
Merge pull request from konstruktoid/ISSUE422
fix MacOSX volume, and lint
2020-04-17 06:26:30 +00:00
Thomas Sjögren
1c2b912aa2 fix MacOSX volume, and lint
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-04-17 08:25:44 +02:00
Thomas Sjögren
d53ac42de1
Merge pull request from konstruktoid/ISSUE424
update README, correct volume binary paths
2020-04-16 15:18:38 +00:00
Thomas Sjögren
3c38419c5b update README, correct volume binary paths
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-04-16 17:17:51 +02:00
Thomas Sjögren
2cdfa3df25
Merge pull request from illyaMs/master
[Ubuntu] Fix issue with docker.service and docker.socket files not found
2020-04-15 09:05:50 +00:00
Thomas Sjögren
2972b685fc
Merge pull request from konstruktoid/ISSUE425
use opensuse/leap, and remove awk linkage
2020-04-15 08:55:27 +00:00
Thomas Sjögren
9f92e46df8 use opensuse/leap, and remove awk linkage
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-04-15 10:54:17 +02:00
Ilya Dus
51bc75eb55 fix(docs): explain the need of mounting /lib/systemd/system folder for Ubuntu
Signed-off-by: Ilya Dus <ilyadoos@gmail.com>
2020-04-10 16:27:32 +03:00
Ilya Dus
d42fedc370 fix(sh): check default ubuntu locations of docker.service and docker.socket files
Signed-off-by: Ilya Dus <ilyadoos@gmail.com>
2020-04-10 16:26:25 +03:00
Thomas Sjögren
0307da4c61
Merge pull request from konstruktoid/issue158
macOS user instructions. ref 
2020-04-01 13:20:41 +02:00
Thomas Sjögren
b3488e7d1f macOS user instructions. ref
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2020-04-01 13:19:55 +02:00
Thomas Sjögren
937ec4958a
Merge pull request from zawazawa0316/fix_5
Fix check conditions
2020-03-09 14:54:32 +00:00
zawazawa0316
33566331d1 fix line 230
Signed-off-by: zawazawa0316 <37421794+zawazawa0316@users.noreply.github.com>
2020-03-09 23:48:10 +09:00
zawazawa0316
b046f930bc remove single space at line 230
Signed-off-by: zawazawa0316 <37421794+zawazawa0316@users.noreply.github.com>
2020-03-09 23:45:25 +09:00
zawazawa0316
12f19d9f64 Fix check conditions
Signed-off-by: zawazawa0316 <37421794+zawazawa0316@users.noreply.github.com>
2020-03-07 05:24:24 +09:00
Thomas Sjögren
e1feca8620
Merge pull request from zawazawa0316/fix_2_5
Fix check condition
2020-03-03 14:04:32 +00:00
zawazawa0316
b16da2c2ed Fix check condition
Signed-off-by: zawazawa0316 <37421794+zawazawa0316@users.noreply.github.com>
2020-03-03 21:51:49 +09:00
Thomas Sjögren
11da147df9
Merge pull request from Intermax-Cloudsourcing/allow-include-checks-mixing
fix: allow combining include and exclude
2020-01-29 12:07:32 +00:00
wilmardo
4054055546 fix: uncomment PATH variable
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2020-01-29 10:31:15 +01:00
Thomas Sjögren
9696a8bd6a
Merge pull request from konstruktoid/alpineupdate
alpine:3.11
2019-12-21 20:32:28 +00:00
Thomas Sjögren
685236f4e6 alpine:3.11
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2019-12-21 21:31:33 +01:00
Thomas Sjögren
d9a70bc006
Merge pull request from konstruktoid/ISSUE410b
locate configuration file before we run the tests 
2019-12-18 07:21:32 +00:00
Thomas Sjögren
269b71eed8 locate configuration file before we run the tests
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2019-12-17 15:03:54 +01:00
Thomas Sjögren
19173cb954
Merge pull request from konstruktoid/ISSUE410
correct grep 
2019-12-17 09:19:39 +00:00
Thomas Sjögren
c8c5615061 correct grep
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2019-12-16 09:57:21 +01:00
Thomas Sjögren
3c545daccf
Merge pull request from konstruktoid/ISSUE408
catch json w/o space 
2019-12-13 13:00:06 +00:00
Thomas Sjögren
e21999c5c7 catch json w/o space
Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com>
2019-12-12 11:03:23 +01:00
wilmardo
155c739fc9 feat: all mixes of include and excludes are now supported
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-09 15:19:17 +01:00
wilmardo
f1c4dc4cd6 docs: Adds example of combining include and exclude
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-05 16:21:46 +01:00
wilmardo
91d36b62f9 refact: removes variable, use result directly in loop
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-05 16:20:47 +01:00
wilmardo
cf9baa76ae feat: improve sed match
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-05 15:51:14 +01:00
wilmardo
1b37a1e6bc fix: allow combining include and exclude
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-04 15:35:11 +01:00
Thomas Sjögren
c35d71f533
Merge pull request from jammasterj89/master
Reorder of sed command on images
2019-12-04 11:23:33 +00:00
jammasterj89
d2963b4c42
Reorder of sed command on images
Ensure sed command is first when filtering on images to ensure the description row is removed correctly.

Signed-off-by: Niall T <jammasterj89@gmail.com>
2019-12-04 11:14:43 +00:00
32 changed files with 3882 additions and 3005 deletions

View file

@ -1,5 +1,6 @@
.git
*.md
*.png
distros
*
!docker-bench-security.sh
!functions/
!tests/
!log/
log/*

19
.github/workflows/issues.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: Issue assignment
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
auto-assign:
permissions:
issues: write
runs-on: ubuntu-latest
steps:
- name: 'auto-assign issue'
uses: pozil/auto-assign-issue@74b9f64cc1a08f99358061073e243a4c3d7dd5c4 # v1.11.0
with:
assignees: konstruktoid

80
.github/workflows/slsa.yml vendored Normal file
View file

@ -0,0 +1,80 @@
---
name: SLSA
on:
push:
release:
permissions:
contents: write
types: [published, released]
permissions:
contents: read
jobs:
build:
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- run: echo "REPOSITORY_NAME=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV
shell: bash
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Build artifacts
run: |
find *.sh functions/* tests/* Dockerfile Vagrantfile -exec sha256sum {} \; > ${{ env.REPOSITORY_NAME }}.sha256
- name: Generate hashes
shell: bash
id: hash
run: |
echo "hashes=$(sha256sum ${{ env.REPOSITORY_NAME }}.sha256 | base64 -w0)" >> "$GITHUB_OUTPUT"
- name: Upload ${{ env.REPOSITORY_NAME }}.sha256
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: ${{ env.REPOSITORY_NAME }}.sha256
path: ${{ env.REPOSITORY_NAME }}.sha256
if-no-files-found: error
retention-days: 5
provenance:
needs: [build]
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0
with:
base64-subjects: "${{ needs.build.outputs.hashes }}"
upload-assets: ${{ startsWith(github.ref, 'refs/tags/') }}
release:
permissions:
actions: read
id-token: write
contents: write
needs: [build, provenance]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- run: echo "REPOSITORY_NAME=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV
shell: bash
- name: Download ${{ env.REPOSITORY_NAME }}.sha256
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: ${{ env.REPOSITORY_NAME }}.sha256
- name: Upload asset
uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v2.0.4
with:
files: |
${{ env.REPOSITORY_NAME }}.sha256

4
.gitignore vendored
View file

@ -1 +1,3 @@
*.log*
log/*
*.swp*
.vagrant/

View file

@ -8,13 +8,10 @@ project, and follows the same rules and principles. If you're already familiar
with the way Docker does things, you'll feel right at home.
Otherwise, go read
[Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md).
[Contribute to the Moby Project](https://github.com/moby/moby/blob/master/CONTRIBUTING.md).
## Development Environment Setup
The only thing you need to hack on Docker Bench for Security is a POSIX 2004
compliant shell. We try to keep the project compliant for maximum portability.
### Start hacking
You can build the container that wraps the docker-bench for security:
@ -53,12 +50,9 @@ tests/
```
To modify the Docker Bench for Security you should first clone the repository,
make your changes, check your code with `shellcheck`, `checkbashisms` or similar
tools, and then sign off on your commits. After that feel free to send us a
pull request with the changes.
make your changes, check your code with `shellcheck`, or similar tools, and
then sign off on your commits. After that feel free to send us a pull request
with the changes.
While this tool was inspired by the [CIS Docker 1.11.0 benchmark](https://www.cisecurity.org/benchmark/docker/)
and its successors, feel free to add new tests. We will try to turn
[dockerbench.com](https://dockerbench.com) into a list of good community
benchmarks for both security and performance, and we would love community
contributions.
and its successors, feel free to add new tests.

View file

@ -1,25 +1,20 @@
FROM alpine:3.10
FROM alpine:3.18@sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978
LABEL \
org.label-schema.name="docker-bench-security" \
org.label-schema.url="https://dockerbench.com" \
org.label-schema.vcs-url="https://github.com/docker/docker-bench-security.git"
# Switch to the HTTPS endpoint for the apk repositories
# https://github.com/gliderlabs/docker-alpine/issues/184
RUN set -eux; \
sed -i 's!http://dl-cdn.alpinelinux.org/!https://alpine.global.ssl.fastly.net/!g' /etc/apk/repositories && \
apk add --no-cache \
iproute2 \
RUN apk add --no-cache iproute2 \
docker-cli \
dumb-init
dumb-init \
jq
COPY ./*.sh /usr/local/bin/
COPY ./tests/*.sh /usr/local/bin/tests/
COPY . /usr/local/bin/
HEALTHCHECK CMD exit 0
WORKDIR /usr/local/bin
ENTRYPOINT [ "/usr/bin/dumb-init", "docker-bench-security.sh" ]
ENTRYPOINT [ "/usr/bin/dumb-init", "/bin/sh", "docker-bench-security.sh" ]
CMD [""]

235
README.md
View file

@ -1,107 +1,25 @@
# Docker Bench for Security
![Docker Bench for Security running](https://raw.githubusercontent.com/docker/docker-bench-security/master/benchmark_log.png "Docker Bench for Security running")
![Docker Bench for Security running](img/benchmark_log.png)
The Docker Bench for Security is a script that checks for dozens of common
best-practices around deploying Docker containers in production. The tests are
all automated, and are inspired by the [CIS Docker Benchmark v1.2.0](https://www.cisecurity.org/benchmark/docker/).
The Docker Bench for Security is a script that checks for dozens of common best-practices around deploying Docker containers in production. The tests are all automated, and are based on the [CIS Docker Benchmark v1.6.0](https://www.cisecurity.org/benchmark/docker/).
We are making this available as an open-source utility so the Docker community
can have an easy way to self-assess their hosts and docker containers against
this benchmark.
We are making this available as an open-source utility so the Docker community can have an easy way to self-assess their hosts and Docker containers against this benchmark.
Release | CIS |
:---:|:---:|
1.6.0|1.6.0|
1.5.0|1.5.0|
1.3.6|1.4.0|
1.3.5|1.2.0|
1.3.3|1.1.0|
1.3.0|1.13.0|
## Running Docker Bench for Security
We packaged docker bench as a small container for your convenience. Note that
this container is being run with a *lot* of privilege -- sharing the host's
filesystem, pid and network namespaces, due to portions of the benchmark
applying to the running host. Don't forget to adjust the shared volumes
according to your operating system, for example it might not use systemd.
### Run from your base host
The easiest way to run your hosts against the Docker Bench for Security is by
running our pre-built container:
```sh
docker run -it --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/docker-containerd:/usr/bin/docker-containerd:ro \
-v /usr/bin/docker-runc:/usr/bin/docker-runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker/docker-bench-security
```
Docker bench requires Docker 1.13.0 or later in order to run.
Note that when distributions doesn't contain `auditctl`, the audit tests will
check `/etc/audit/audit.rules` to see if a rule is present instead.
Distribution specific Dockerfiles that fixes this issue are available in the
[distros directory](https://github.com/docker/docker-bench-security/tree/master/distros).
The [distribution specific Dockerfiles](https://github.com/docker/docker-bench-security/tree/master/distros)
may also help if the distribution you're using haven't yet shipped Docker
version 1.13.0 or later.
### Docker Bench for Security options
```sh
-b optional Do not print colors
-h optional Print this help message
-l FILE optional Log output in FILE
-c CHECK optional Comma delimited list of specific check(s)
-e CHECK optional Comma delimited list of specific check(s) to exclude
-i INCLUDE optional Comma delimited list of patterns within a container or image name to check
-x EXCLUDE optional Comma delimited list of patterns within a container or image name to exclude from check
```
By default the Docker Bench for Security script will run all available CIS tests
and produce logs in the current directory named `docker-bench-security.sh.log.json`
and `docker-bench-security.sh.log`.
The CIS based checks are named `check_<section>_<number>`, e.g. `check_2_6`
and community contributed checks are named `check_c_<number>`.
A complete list of checks are present in [functions_lib.sh](functions_lib.sh).
`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -c check_2_2`
will only run check `2.2 Ensure the logging level is set to 'info'`.
`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -e check_2_2`
will run all available checks except `2.2 Ensure the logging level is set to 'info'`.
Note that when submitting checks, provide information why it is a
reasonable test to add and please include some kind of official documentation
verifying that information.
## Building Docker Bench for Security
If you wish to build and run this container yourself, you can follow the
following steps:
```sh
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker build --no-cache -t docker-bench-security .
docker run -it --net host --pid host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /etc:/etc:ro --label docker_bench_security \
docker-bench-security
```
or use [Docker Compose](https://docs.docker.com/compose/):
```sh
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker-compose run --rm docker-bench-security
```
Also, this script can also be simply run from your base host by running:
You can simply run this script from your base host by running:
```sh
git clone https://github.com/docker/docker-bench-security.git
@ -109,5 +27,126 @@ cd docker-bench-security
sudo sh docker-bench-security.sh
```
This script was built to be POSIX 2004 compliant, so it should be portable
across any Unix platform.
> Note: [`jq`](https://jqlang.github.io/jq/) is an optional but recommended dependency.
### Run with Docker
#### Building Docker image
You have two options if you wish to build and run this container yourself:
1. Use Docker Build:
```sh
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker build --no-cache -t docker-bench-security .
```
Followed by an appropriate `docker run` command as stated below.
2. Use Docker Compose:
```sh
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker-compose run --rm docker-bench-security
```
_Please note that the `docker/docker-bench-security` image is out-of-date and and a manual build is required. See [#405](https://github.com/docker/docker-bench-security/issues/405) for more information._
Note that this container is being run with a *lot* of privilege -- sharing the host's filesystem, pid and network namespaces, due to portions of the benchmark applying to the running host.
### Using the container
```sh
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker-bench-security
```
Don't forget to adjust the shared volumes according to your operating system.
Some examples are:
1. On Ubuntu the `docker.service` and `docker.secret` files are located in
`/lib/systemd/system` folder by default.
```sh
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /lib/systemd/system:/lib/systemd/system:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker-bench-security
```
2. The /etc/hostname file is missing on macOS, so it will need to be created first. Also, `Docker Desktop` on macOS doesn't have `/usr/lib/systemd` or the above Docker
binaries.
```sh
sudo touch /etc/hostname
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker-bench-security
```
### Note
Docker bench requires Docker 1.13.0 or later in order to run.
Note that when distributions don't contain `auditctl`, the audit tests will check `/etc/audit/audit.rules` to see if a rule is present instead.
### Docker Bench for Security options
```sh
-b optional Do not print colors
-h optional Print this help message
-l FILE optional Log output in FILE, inside container if run using docker
-u USERS optional Comma delimited list of trusted docker user(s)
-c CHECK optional Comma delimited list of specific check(s) id
-e CHECK optional Comma delimited list of specific check(s) id to exclude
-i INCLUDE optional Comma delimited list of patterns within a container or image name to check
-x EXCLUDE optional Comma delimited list of patterns within a container or image name to exclude from check
-t LABEL optional Comma delimited list of labels within a container or image to check
-n LIMIT optional In JSON output, when reporting lists of items (containers, images, etc.), limit the number of reported items to LIMIT. Default 0 (no limit).
-p PRINT optional Disable the printing of remediation measures. Default: print remediation measures.
```
By default the Docker Bench for Security script will run all available CIS tests and produce
logs in the log folder from current directory, named `docker-bench-security.log.json` and
`docker-bench-security.log`.
If the docker container is used then the log files will be created inside the container in location `/usr/local/bin/log/`. If you wish to access them from the host after the container has been run you will need to mount a volume for storing them in.
The CIS based checks are named `check_<section>_<number>`, e.g. `check_2_6` and community contributed checks are named `check_c_<number>`.
`sh docker-bench-security.sh -c check_2_2` will only run check `2.2 Ensure the logging level is set to 'info'`.
`sh docker-bench-security.sh -e check_2_2` will run all available checks except `2.2 Ensure the logging level is set to 'info'`.
`sh docker-bench-security.sh -e docker_enterprise_configuration` will run all available checks except the docker_enterprise_configuration group
`sh docker-bench-security.sh -e docker_enterprise_configuration,check_2_2` will run all available checks except the docker_enterprise_configuration group and `2.2 Ensure the logging level is set to 'info'`
`sh docker-bench-security.sh -c container_images,container_runtime` will run just the container_images and container_runtime checks
`sh docker-bench-security.sh -c container_images -e check_4_5` will run just the container_images checks except `4.5 Ensure Content trust for Docker is Enabled`
Note that when submitting checks, provide information why it is a reasonable test to add and please include some kind of official documentation verifying that information.

19
Vagrantfile vendored Normal file
View file

@ -0,0 +1,19 @@
Vagrant.configure("2") do |config|
config.vbguest.installer_options = { allow_kernel_upgrade: true }
config.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
v.customize ["modifyvm", :id, "--uart1", "0x3F8", "4"]
v.customize ["modifyvm", :id, "--uartmode1", "file", File::NULL]
end
config.vm.define "jammy" do |jammy|
jammy.ssh.extra_args = ["-o","ConnectTimeout=600"]
jammy.ssh.insert_key = true
jammy.vm.boot_timeout = 600
jammy.vm.box = "ubuntu/jammy64"
jammy.vm.hostname = "jammy"
jammy.vm.provision "shell",
inline: "apt-get update && curl -sSL get.docker.com | sh && addgroup vagrant docker"
end
end

Binary file not shown.

Before

(image error) Size: 275 KiB

View file

@ -1,26 +0,0 @@
FROM alpine:3.10
LABEL \
org.label-schema.name="docker-bench-security" \
org.label-schema.url="https://dockerbench.com" \
org.label-schema.vcs-url="https://github.com/docker/docker-bench-security.git"
# Switch to the HTTPS endpoint for the apk repositories
# https://github.com/gliderlabs/docker-alpine/issues/184
RUN \
sed -i 's/http\:\/\/dl-cdn.alpinelinux.org/https\:\/\/alpine.global.ssl.fastly.net/g' /etc/apk/repositories && \
apk add --no-cache \
iproute2 \
docker \
dumb-init && \
rm -rf /usr/bin/docker?*
COPY ./*.sh /usr/local/bin/
COPY ./tests/*.sh /usr/local/bin/tests/
HEALTHCHECK CMD exit 0
WORKDIR /usr/local/bin
ENTRYPOINT [ "/usr/bin/dumb-init", "docker-bench-security.sh" ]
CMD [""]

View file

@ -1,15 +0,0 @@
# REPOSITORY https://github.com/fatherlinux/docker-bench-security
FROM centos
MAINTAINER smccarty@redhat.com
RUN yum install -y docker iproute audit procps-ng; yum clean all
RUN mkdir /docker-bench-security
COPY . /docker-bench-security
WORKDIR /docker-bench-security
ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]

View file

@ -1,24 +0,0 @@
FROM debian:sid
LABEL org.label-schema.name="docker-bench-security" \
org.label-schema.url="https://github.com/konstruktoid/docker-bench-security" \
org.label-schema.vcs-url="https://github.com/konstruktoid/docker-bench-security.git"
RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install auditd ca-certificates docker.io \
gawk iproute2 procps --no-install-recommends && \
apt-get -y clean && \
apt-get -y autoremove && \
rm -rf /var/lib/apt/lists/* \
/usr/share/doc /usr/share/doc-base \
/usr/share/man /usr/share/locale /usr/share/zoneinfo
RUN mkdir /docker-bench-security
COPY . /docker-bench-security
WORKDIR /docker-bench-security
ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]

View file

@ -1,15 +0,0 @@
# REPOSITORY https://github.com/docker/docker-bench-security
FROM opensuse
MAINTAINER security@suse.com
RUN zypper -n in docker iproute2 audit
RUN mkdir /docker-bench-security
COPY . /docker-bench-security
WORKDIR /docker-bench-security
ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]

View file

@ -1,18 +0,0 @@
# REPOSITORY https://github.com/fatherlinux/docker-bench-security
FROM rhel7
MAINTAINER smccarty@redhat.com
RUN yum install -y yum-utils; yum clean all
RUN yum-config-manager --disable "*" &>/dev/null
RUN yum-config-manager --enable rhel-7-server-rpms --enable rhel-7-server-extras-rpms
RUN yum install -y docker iproute audit procps-ng; yum clean all
RUN mkdir /docker-bench-security
COPY . /docker-bench-security
WORKDIR /docker-bench-security
ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]

View file

@ -1,21 +0,0 @@
# Distribution specific Dockerfiles
## Requirements
### Dockerfile name
The format should be `Dockerfile.{distribution name}`.
### Keep your images up-to-date
Use the distribution package manager to keep your image up-to-date.
### Labels
Use the following labels in your Dockerfile:
```
LABEL org.label-schema.name="docker-bench-security" \
org.label-schema.url="<YOUR GIT REPOSITORY HTTPS ADDRESS>" \
org.label-schema.vcs-url="<YOUR REPOSITORY HTTPS GIT ADDRESS"
```

View file

@ -1,21 +1,23 @@
#!/bin/sh
# ------------------------------------------------------------------------------
#!/bin/bash
# --------------------------------------------------------------------------------------------
# Docker Bench for Security
#
# Docker, Inc. (c) 2015-
# Docker, Inc. (c) 2015-2022
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# ------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------
version='1.3.5'
version='1.6.0'
LIBEXEC="." # Distributions can change this to /usr/libexec or similar.
# Load dependencies
. ./functions_lib.sh
. ./helper_lib.sh
. $LIBEXEC/functions/functions_lib.sh
. $LIBEXEC/functions/helper_lib.sh
# Setup the paths
this_path=$(abspath "$0") ## Path of this file including filename
myname=$(basename "${this_path}") ## file name of this script.
myname=$(basename "${this_path%.*}") ## file name of this script.
readonly version
readonly this_path
@ -24,10 +26,7 @@ readonly myname
export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/"
# Check for required program(s)
req_progs='awk docker grep ss stat'
for p in $req_progs; do
command -v "$p" >/dev/null 2>&1 || { printf "%s command not found.\n" "$p"; exit 1; }
done
req_programs 'awk docker grep sed stat tail tee tr wc xargs'
# Ensure we can connect to docker daemon
if ! docker ps -q >/dev/null 2>&1; then
@ -37,48 +36,78 @@ fi
usage () {
cat <<EOF
usage: ${myname} [options]
Docker Bench for Security - Docker, Inc. (c) 2015-$(date +"%Y")
Checks for dozens of common best-practices around deploying Docker containers in production.
Based on the CIS Docker Benchmark 1.6.0.
Usage: ${myname}.sh [OPTIONS]
Example:
- Only run check "2.2 - Ensure the logging level is set to 'info'":
sh docker-bench-security.sh -c check_2_2
- Run all available checks except the host_configuration group and "2.8 - Enable user namespace support":
sh docker-bench-security.sh -e host_configuration,check_2_8
- Run just the container_images checks except "4.5 - Ensure Content trust for Docker is Enabled":
sh docker-bench-security.sh -c container_images -e check_4_5
Options:
-b optional Do not print colors
-h optional Print this help message
-l FILE optional Log output in FILE
-c CHECK optional Comma delimited list of specific check(s)
-e CHECK optional Comma delimited list of specific check(s) to exclude
-l FILE optional Log output in FILE, inside container if run using docker
-u USERS optional Comma delimited list of trusted docker user(s)
-c CHECK optional Comma delimited list of specific check(s) id
-e CHECK optional Comma delimited list of specific check(s) id to exclude
-i INCLUDE optional Comma delimited list of patterns within a container or image name to check
-x EXCLUDE optional Comma delimited list of patterns within a container or image name to exclude from check
-t LABEL optional Comma delimited list of labels within a container or image to check
-n LIMIT optional In JSON output, when reporting lists of items (containers, images, etc.), limit the number of reported items to LIMIT. Default 0 (no limit).
-p PRINT optional Print remediation measures. Default: Don't print remediation measures.
Complete list of checks: <https://github.com/docker/docker-bench-security/blob/master/tests/>
Full documentation: <https://github.com/docker/docker-bench-security>
Released under the Apache-2.0 License.
EOF
}
# Default values
if [ ! -d log ]; then
mkdir log
fi
logger="log/${myname}.log"
limit=0
printremediation="0"
globalRemediation=""
# Get the flags
# If you add an option here, please
# remember to update usage() above.
while getopts bhl:c:e:i:x:t: args
while getopts bhl:u:c:e:i:x:t:n:p args
do
case $args in
b) nocolor="nocolor";;
h) usage; exit 0 ;;
l) logger="$OPTARG" ;;
u) dockertrustusers="$OPTARG" ;;
c) check="$OPTARG" ;;
e) checkexclude="$OPTARG" ;;
i) include="$OPTARG" ;;
x) exclude="$OPTARG" ;;
t) labels="$OPTARG" ;;
n) limit="$OPTARG" ;;
p) printremediation="1" ;;
*) usage; exit 1 ;;
esac
done
if [ -z "$logger" ]; then
logger="${myname}.log"
fi
# Load output formating
. ./output_lib.sh
. $LIBEXEC/functions/output_lib.sh
yell_info
# Warn if not root
ID=$(id -u)
if [ "x$ID" != "x0" ]; then
warn "Some tests might require root to run"
if [ "$(id -u)" != "0" ]; then
warn "$(yell 'Some tests might require root to run')\n"
sleep 3
fi
@ -88,11 +117,16 @@ fi
totalChecks=0
currentScore=0
logit "Initializing $(date)\n"
logit "Initializing $(date +%Y-%m-%dT%H:%M:%S%:z)\n"
beginjson "$version" "$(date +%s)"
# Load all the tests from tests/ and run them
main () {
logit "\n${bldylw}Section A - Check results${txtrst}"
# Get configuration location
get_docker_configuration_file
# If there is a container with label docker_bench_security, memorize it:
benchcont="nil"
for c in $(docker ps | sed '1d' | awk '{print $NF}'); do
@ -102,7 +136,7 @@ main () {
fi
done
# get the image id of the docker_bench_security_image, memorize it:
# Get the image id of the docker_bench_security_image, memorize it:
benchimagecont="nil"
for c in $(docker images | sed '1d' | awk '{print $3}'); do
if docker inspect --format '{{ .Config.Labels }}' "$c" | \
@ -111,50 +145,76 @@ main () {
fi
done
# Format LABELS
for label in $(echo "$labels" | sed 's/,/ /g'); do
LABELS="$LABELS --filter label=$label"
done
if [ -n "$include" ]; then
pattern=$(echo "$include" | sed 's/,/|/g')
containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -E "$pattern")
images=$(docker images | grep -E "$pattern" | sed '1d' | awk '{print $3}' | grep -v "$benchimagecont")
containers=$(docker ps $LABELS| sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -E "$pattern")
images=$(docker images $LABELS| sed '1d' | grep -E "$pattern" | awk '{print $3}' | grep -v "$benchimagecont")
elif [ -n "$exclude" ]; then
pattern=$(echo "$exclude" | sed 's/,/|/g')
containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -Ev "$pattern")
images=$(docker images | grep -Ev "$pattern" | sed '1d' | awk '{print $3}' | grep -v "$benchimagecont")
containers=$(docker ps $LABELS| sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -Ev "$pattern")
images=$(docker images $LABELS| sed '1d' | grep -Ev "$pattern" | awk '{print $3}' | grep -v "$benchimagecont")
else
containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont")
images=$(docker images -q | grep -v "$benchcont")
containers=$(docker ps $LABELS| sed '1d' | awk '{print $NF}' | grep -v "$benchcont")
images=$(docker images -q $LABELS| grep -v "$benchcont")
fi
if [ -z "$containers" ]; then
running_containers=0
else
running_containers=1
fi
for test in tests/*.sh; do
. ./"$test"
for test in $LIBEXEC/tests/*.sh; do
. "$test"
done
if [ -z "$check" ] && [ ! "$checkexclude" ]; then
# No options just run
cis
elif [ -z "$check" ] && [ "$checkexclude" ]; then
checkexcluded="$(echo ",$checkexclude" | sed -e 's/^/\^/g' -e 's/,/\$|/g' -e 's/$/\$/g')"
for c in $(grep -E 'check_[0-9]|check_[a-z]' functions_lib.sh | grep -vE "$checkexcluded"); do
"$c"
done
else
for i in $(echo "$check" | sed "s/,/ /g"); do
if command -v "$i" 2>/dev/null 1>&2; then
"$i"
else
echo "Check \"$i\" doesn't seem to exist."
continue
fi
done
elif [ -z "$check" ]; then
# No check defined but excludes defined set to calls in cis() function
check=$(sed -ne "/cis() {/,/}/{/{/d; /}/d; p;}" functions/functions_lib.sh)
fi
printf "\n"
for c in $(echo "$check" | sed "s/,/ /g"); do
if ! command -v "$c" 2>/dev/null 1>&2; then
echo "Check \"$c\" doesn't seem to exist."
continue
fi
if [ -z "$checkexclude" ]; then
# No excludes just run the checks specified
"$c"
else
# Exludes specified and check exists
checkexcluded="$(echo ",$checkexclude" | sed -e 's/^/\^/g' -e 's/,/\$|/g' -e 's/$/\$/g')"
if echo "$c" | grep -E "$checkexcluded" 2>/dev/null 1>&2; then
# Excluded
continue
elif echo "$c" | grep -vE 'check_[0-9]|check_[a-z]' 2>/dev/null 1>&2; then
# Function not a check, fill loop_checks with all check from function
loop_checks="$(sed -ne "/$c() {/,/}/{/{/d; /}/d; p;}" functions/functions_lib.sh)"
else
# Just one check
loop_checks="$c"
fi
for lc in $loop_checks; do
if echo "$lc" | grep -vE "$checkexcluded" 2>/dev/null 1>&2; then
# Not excluded
"$lc"
fi
done
fi
done
if [ -n "${globalRemediation}" ] && [ "$printremediation" = "1" ]; then
logit "\n\n${bldylw}Section B - Remediation measures${txtrst}"
logit "${globalRemediation}"
fi
logit "\n\n${bldylw}Section C - Score${txtrst}\n"
info "Checks: $totalChecks"
info "Score: $currentScore"
info "Score: $currentScore\n"
endjson "$totalChecks" "$currentScore" "$(date +%s)"
}

View file

@ -1,21 +1,21 @@
docker-bench-security:
# use image if you have a dedicated build step:
# docker build --rm -t docker-bench-security .
# image: docker-bench-security
services:
docker-bench-security:
# use image if you have a dedicated build step:
# docker build --rm -t docker-bench-security .
# image: docker-bench-security
# use build path to Dockerfile if docker-compose should build the image
build: .
# use build path to Dockerfile if docker-compose should build the image
build: .
cap_add:
- audit_control
labels:
- docker_bench_security
net: host
pid: host
stdin_open: true
tty: true
volumes:
- /var/lib:/var/lib:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /usr/lib/systemd:/usr/lib/systemd:ro
- /etc:/etc:ro
cap_add:
- audit_control
labels:
- docker_bench_security
pid: host
stdin_open: true
tty: true
volumes:
- /var/lib:/var/lib:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /usr/lib/systemd:/usr/lib/systemd:ro
- /etc:/etc:ro

571
functions/functions_lib.sh Normal file
View file

@ -0,0 +1,571 @@
#!/bin/sh
host_configuration() {
check_1
check_1_1
check_1_1_1
check_1_1_2
check_1_1_3
check_1_1_4
check_1_1_5
check_1_1_6
check_1_1_7
check_1_1_8
check_1_1_9
check_1_1_10
check_1_1_11
check_1_1_12
check_1_1_13
check_1_1_14
check_1_1_15
check_1_1_16
check_1_1_17
check_1_1_18
check_1_2
check_1_2_1
check_1_2_2
check_1_end
}
host_configuration_level1() {
check_1
check_1_end
}
linux_hosts_specific_configuration() {
check_1_1
check_1_1_1
check_1_1_2
check_1_1_3
check_1_1_4
check_1_1_5
check_1_1_6
check_1_1_7
check_1_1_8
check_1_1_9
check_1_1_10
check_1_1_11
check_1_1_12
check_1_1_13
check_1_1_14
check_1_1_15
check_1_1_16
check_1_1_17
check_1_1_18
}
host_general_configuration() {
check_1
check_1_2
check_1_2_1
check_1_2_2
check_1_end
}
docker_daemon_configuration() {
check_2
check_2_1
check_2_2
check_2_3
check_2_4
check_2_5
check_2_6
check_2_7
check_2_8
check_2_9
check_2_10
check_2_11
check_2_12
check_2_13
check_2_14
check_2_15
check_2_16
check_2_17
check_2_18
check_2_end
}
docker_daemon_configuration_level1() {
check_2
check_2_end
}
docker_daemon_files() {
check_3
check_3_1
check_3_2
check_3_3
check_3_4
check_3_5
check_3_6
check_3_7
check_3_8
check_3_9
check_3_10
check_3_11
check_3_12
check_3_13
check_3_14
check_3_15
check_3_16
check_3_17
check_3_18
check_3_19
check_3_20
check_3_21
check_3_22
check_3_23
check_3_24
check_3_end
}
docker_daemon_files_level1() {
check_3
check_3_end
}
container_images() {
check_4
check_4_1
check_4_2
check_4_3
check_4_4
check_4_5
check_4_6
check_4_7
check_4_8
check_4_9
check_4_10
check_4_11
check_4_12
check_4_end
}
container_images_level1() {
check_4
check_4_end
}
container_runtime() {
check_5
check_running_containers
check_5_1
check_5_2
check_5_3
check_5_4
check_5_5
check_5_6
check_5_7
check_5_8
check_5_9
check_5_10
check_5_11
check_5_12
check_5_13
check_5_14
check_5_15
check_5_16
check_5_17
check_5_18
check_5_19
check_5_20
check_5_21
check_5_22
check_5_23
check_5_24
check_5_25
check_5_26
check_5_27
check_5_28
check_5_29
check_5_30
check_5_31
check_5_32
check_5_end
}
container_runtime_level1() {
check_5
check_5_end
}
docker_security_operations() {
check_6
check_6_1
check_6_2
check_6_end
}
docker_security_operations_level1() {
check_6
check_6_1
check_6_2
check_6_end
}
docker_swarm_configuration() {
check_7
check_7_1
check_7_2
check_7_3
check_7_4
check_7_5
check_7_6
check_7_7
check_7_8
check_7_9
check_7_end
}
docker_swarm_configuration_level1() {
check_7
check_7_end
}
docker_enterprise_configuration() {
check_8
check_product_license
check_8_1
check_8_1_1
check_8_1_2
check_8_1_3
check_8_1_4
check_8_1_5
check_8_1_6
check_8_1_7
check_8_2
check_8_2_1
check_8_end
}
docker_enterprise_configuration_level1() {
check_8
check_product_license
check_8_1
check_8_1_1
check_8_1_2
check_8_1_3
check_8_1_4
check_8_1_5
check_8_1_6
check_8_1_7
check_8_2
check_8_2_1
check_8_end
}
universal_control_plane_configuration() {
check_8
check_8_1
check_8_1_1
check_8_1_2
check_8_1_3
check_8_1_4
check_8_1_5
check_8_1_6
check_8_1_7
check_8_end
}
docker_trusted_registry_configuration() {
check_8
check_8_2
check_8_2_1
check_8_end
}
community_checks() {
check_c
check_c_1
check_c_1_1
check_c_2
check_c_5_3_1
check_c_5_3_2
check_c_5_3_3
check_c_5_3_4
check_c_end
}
# CIS
cis() {
host_configuration
docker_daemon_configuration
docker_daemon_files
container_images
container_runtime
docker_security_operations
docker_swarm_configuration
}
cis_level1() {
host_configuration_level1
docker_daemon_configuration_level1
docker_daemon_files_level1
container_images_level1
container_runtime_level1
docker_security_operations_level1
docker_swarm_configuration_level1
}
cis_controls_v8_ig1() {
check_1_1_2
check_1_1_3
check_2_1
check_2_13
check_2_14
check_3_1
check_3_2
check_3_3
check_3_4
check_3_5
check_3_6
check_3_7
check_3_8
check_3_9
check_3_10
check_3_11
check_3_12
check_3_13
check_3_14
check_3_15
check_3_16
check_3_17
check_3_18
check_3_19
check_3_20
check_3_21
check_3_22
check_3_23
check_3_24
check_4_8
check_4_11
check_5_5
check_5_14
check_5_18
check_5_22
check_5_23
check_5_24
check_5_25
check_5_26
check_5_32
check_7_2
check_7_6
check_7_7
check_7_8
}
cis_controls_v8_ig2() {
check_1_1_1
check_1_1_2
check_1_1_3
check_1_1_4
check_1_1_5
check_1_1_6
check_1_1_7
check_1_1_8
check_1_1_9
check_1_1_10
check_1_1_11
check_1_1_12
check_1_1_13
check_1_1_14
check_1_1_15
check_1_1_16
check_1_1_17
check_1_1_18
check_1_2_1
check_1_2_2
check_2_1
check_2_2
check_2_3
check_2_4
check_2_5
check_2_7
check_2_8
check_2_11
check_2_13
check_2_14
check_2_15
check_2_16
check_2_18
check_3_1
check_3_2
check_3_3
check_3_4
check_3_5
check_3_6
check_3_7
check_3_8
check_3_9
check_3_10
check_3_11
check_3_12
check_3_13
check_3_14
check_3_15
check_3_16
check_3_17
check_3_18
check_3_19
check_3_20
check_3_21
check_3_22
check_3_23
check_3_24
check_4_2
check_4_3
check_4_4
check_4_7
check_4_8
check_4_9
check_4_11
check_5_1
check_5_2
check_5_3
check_5_4
check_5_5
check_5_7
check_5_10
check_5_11
check_5_12
check_5_14
check_5_16
check_5_17
check_5_18
check_5_19
check_5_21
check_5_22
check_5_23
check_5_24
check_5_25
check_5_26
check_5_27
check_5_30
check_5_31
check_5_32
check_6_1
check_6_2
check_7_2
check_7_3
check_7_5
check_7_6
check_7_7
check_7_8
check_7_9
}
cis_controls_v8_ig3() {
check_1_1_1
check_1_1_2
check_1_1_3
check_1_1_4
check_1_1_5
check_1_1_6
check_1_1_7
check_1_1_8
check_1_1_9
check_1_1_10
check_1_1_11
check_1_1_12
check_1_1_13
check_1_1_14
check_1_1_15
check_1_1_16
check_1_1_17
check_1_1_18
check_1_2_1
check_1_2_2
check_2_1
check_2_2
check_2_3
check_2_4
check_2_5
check_2_7
check_2_8
check_2_11
check_2_13
check_2_14
check_2_15
check_2_16
check_2_18
check_3_1
check_3_2
check_3_3
check_3_4
check_3_5
check_3_6
check_3_7
check_3_8
check_3_9
check_3_10
check_3_11
check_3_12
check_3_13
check_3_14
check_3_15
check_3_16
check_3_17
check_3_18
check_3_19
check_3_20
check_3_21
check_3_22
check_3_23
check_3_24
check_4_2
check_4_3
check_4_4
check_4_6
check_4_7
check_4_8
check_4_9
check_4_11
check_4_12
check_5_1
check_5_2
check_5_3
check_5_4
check_5_5
check_5_7
check_5_8
check_5_9
check_5_10
check_5_11
check_5_12
check_5_14
check_5_16
check_5_17
check_5_18
check_5_19
check_5_21
check_5_22
check_5_23
check_5_24
check_5_25
check_5_26
check_5_27
check_5_30
check_5_31
check_5_32
check_6_1
check_6_2
check_7_2
check_7_3
check_7_5
check_7_6
check_7_7
check_7_8
check_7_9
}
# Community contributed
community() {
community_checks
}
# All
all() {
cis
docker_enterprise_configuration
community
}

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Returns the absolute path of a given string
abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }
@ -6,6 +6,28 @@ abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; es
# Audit rules default path
auditrules="/etc/audit/audit.rules"
# Check for required program(s)
req_programs() {
for p in $1; do
command -v "$p" >/dev/null 2>&1 || { printf "Required program not found: %s\n" "$p"; exit 1; }
done
if command -v jq >/dev/null 2>&1; then
HAVE_JQ=true
else
HAVE_JQ=false
fi
if command -v ss >/dev/null 2>&1; then
netbin=ss
return
fi
if command -v netstat >/dev/null 2>&1; then
netbin=netstat
return
fi
echo "ss or netstat command not found."
exit 1
}
# Compares versions of software of the format X.Y.Z
do_version_check() {
[ "$1" = "$2" ] && return 10
@ -23,9 +45,8 @@ do_version_check() {
[ "$ver2front" = "$2" ] || [ -z "$ver2back" ] && ver2back=0
do_version_check "$ver1back" "$ver2back"
return $?
else
[ "$1" -gt "$2" ] && return 11 || return 9
fi
[ "$1" -gt "$2" ] && return 11 || return 9
}
# Extracts commandline args from the newest running processes named like the first parameter
@ -45,10 +66,9 @@ get_command_line_args() {
get_docker_cumulative_command_line_args() {
OPTION="$1"
line_arg="dockerd"
if ! get_command_line_args "docker daemon" >/dev/null 2>&1 ; then
line_arg="docker daemon"
else
line_arg="dockerd"
fi
get_command_line_args "$line_arg" |
@ -82,41 +102,62 @@ get_docker_effective_command_line_args() {
get_docker_cumulative_command_line_args "$OPTION" | tail -n1
}
get_docker_configuration_file_args() {
OPTION="$1"
get_docker_configuration_file() {
FILE="$(get_docker_effective_command_line_args '--config-file' | \
sed 's/.*=//g')"
if [ -f "$FILE" ]; then
CONFIG_FILE="$FILE"
elif [ -f '/etc/docker/daemon.json' ]; then
CONFIG_FILE='/etc/docker/daemon.json'
else
CONFIG_FILE='/dev/null'
return
fi
grep "$OPTION" "$CONFIG_FILE" | sed 's/.*: //g' | tr -d \",
if [ -f '/etc/docker/daemon.json' ]; then
CONFIG_FILE='/etc/docker/daemon.json'
return
fi
CONFIG_FILE='/dev/null'
}
get_systemd_service_file() {
get_docker_configuration_file_args() {
OPTION="$1"
get_docker_configuration_file
if "$HAVE_JQ"; then
jq --monochrome-output --raw-output "if has(\"${OPTION}\") then .[\"${OPTION}\"] else \"\" end" "$CONFIG_FILE"
else
cat "$CONFIG_FILE" | tr , '\n' | grep "$OPTION" | sed 's/.*://g' | tr -d '" ',
fi
}
get_service_file() {
SERVICE="$1"
if [ -f "/etc/systemd/system/$SERVICE" ]; then
echo "/etc/systemd/system/$SERVICE"
elif systemctl show -p FragmentPath "$SERVICE" 2> /dev/null 1>&2; then
systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//'
else
echo "/usr/lib/systemd/system/$SERVICE"
return
fi
if [ -f "/lib/systemd/system/$SERVICE" ]; then
echo "/lib/systemd/system/$SERVICE"
return
fi
if find /run -name "$SERVICE" 2> /dev/null 1>&2; then
find /run -name "$SERVICE" | head -n1
return
fi
if [ "$(systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//')" != "" ]; then
systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//'
return
fi
echo "/usr/lib/systemd/system/$SERVICE"
}
yell_info() {
yell "# ------------------------------------------------------------------------------
yell "# --------------------------------------------------------------------------------------------
# Docker Bench for Security v$version
#
# Docker, Inc. (c) 2015-
# Docker, Inc. (c) 2015-$(date +"%Y")
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker Benchmark v1.2.0.
# ------------------------------------------------------------------------------"
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------"
}

190
functions/output_lib.sh Normal file
View file

@ -0,0 +1,190 @@
#!/bin/bash
bldred='\033[1;31m' # Bold Red
bldgrn='\033[1;32m' # Bold Green
bldblu='\033[1;34m' # Bold Blue
bldylw='\033[1;33m' # Bold Yellow
txtrst='\033[0m'
if [ -n "$nocolor" ] && [ "$nocolor" = "nocolor" ]; then
bldred=''
bldgrn=''
bldblu=''
bldylw=''
txtrst=''
fi
logit () {
printf "%b\n" "$1" | tee -a "$logger"
}
info () {
local infoCountCheck
local OPTIND c
while getopts c args
do
case $args in
c) infoCountCheck="true" ;;
*) exit 1 ;;
esac
done
if [ "$infoCountCheck" = "true" ]; then
printf "%b\n" "${bldblu}[INFO]${txtrst} $2" | tee -a "$logger"
totalChecks=$((totalChecks + 1))
return
fi
printf "%b\n" "${bldblu}[INFO]${txtrst} $1" | tee -a "$logger"
}
pass () {
local passScored
local passCountCheck
local OPTIND s c
while getopts sc args
do
case $args in
s) passScored="true" ;;
c) passCountCheck="true" ;;
*) exit 1 ;;
esac
done
if [ "$passScored" = "true" ] || [ "$passCountCheck" = "true" ]; then
printf "%b\n" "${bldgrn}[PASS]${txtrst} $2" | tee -a "$logger"
totalChecks=$((totalChecks + 1))
fi
if [ "$passScored" = "true" ]; then
currentScore=$((currentScore + 1))
fi
if [ "$passScored" != "true" ] && [ "$passCountCheck" != "true" ]; then
printf "%b\n" "${bldgrn}[PASS]${txtrst} $1" | tee -a "$logger"
fi
}
warn () {
local warnScored
local OPTIND s
while getopts s args
do
case $args in
s) warnScored="true" ;;
*) exit 1 ;;
esac
done
if [ "$warnScored" = "true" ]; then
printf "%b\n" "${bldred}[WARN]${txtrst} $2" | tee -a "$logger"
totalChecks=$((totalChecks + 1))
currentScore=$((currentScore - 1))
return
fi
printf "%b\n" "${bldred}[WARN]${txtrst} $1" | tee -a "$logger"
}
note () {
local noteCountCheck
local OPTIND c
while getopts c args
do
case $args in
c) noteCountCheck="true" ;;
*) exit 1 ;;
esac
done
if [ "$noteCountCheck" = "true" ]; then
printf "%b\n" "${bldylw}[NOTE]${txtrst} $2" | tee -a "$logger"
totalChecks=$((totalChecks + 1))
return
fi
printf "%b\n" "${bldylw}[NOTE]${txtrst} $1" | tee -a "$logger"
}
yell () {
printf "%b\n" "${bldylw}$1${txtrst}\n"
}
beginjson () {
printf "{\n \"dockerbenchsecurity\": \"%s\",\n \"start\": %s,\n \"tests\": [" "$1" "$2" | tee "$logger.json" 2>/dev/null 1>&2
}
endjson (){
printf "\n ],\n \"checks\": %s,\n \"score\": %s,\n \"end\": %s\n}" "$1" "$2" "$3" | tee -a "$logger.json" 2>/dev/null 1>&2
}
logjson (){
printf "\n \"%s\": \"%s\"," "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
}
SSEP=
SEP=
startsectionjson() {
printf "%s\n {\n \"id\": \"%s\",\n \"desc\": \"%s\",\n \"results\": [" "$SSEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
SEP=
SSEP=","
}
endsectionjson() {
printf "\n ]\n }" | tee -a "$logger.json" 2>/dev/null 1>&2
}
starttestjson() {
printf "%s\n {\n \"id\": \"%s\",\n \"desc\": \"%s\",\n " "$SEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
SEP=","
}
log_to_json() {
if [ $# -eq 1 ]; then
printf "\"result\": \"%s\"" "$1" | tee -a "$logger.json" 2>/dev/null 1>&2
return
fi
if [ $# -eq 2 ] && [ $# -ne 1 ]; then
# Result also contains details
printf "\"result\": \"%s\",\n \"details\": \"%s\"" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
return
fi
# Result also includes details and a list of items. Add that directly to details and to an array property "items"
# Also limit the number of items to $limit, if $limit is non-zero
truncItems=$3
if [ "$limit" != 0 ]; then
truncItems=""
ITEM_COUNT=0
for item in $3; do
truncItems="$truncItems $item"
ITEM_COUNT=$((ITEM_COUNT + 1));
if [ "$ITEM_COUNT" == "$limit" ]; then
truncItems="$truncItems (truncated)"
break;
fi
done
fi
itemsJson=$(printf "[\n "; ISEP=""; ITEMCOUNT=0; for item in $truncItems; do printf "%s\"%s\"" "$ISEP" "$item"; ISEP=","; done; printf "\n ]")
printf "\"result\": \"%s\",\n \"details\": \"%s: %s\",\n \"items\": %s" "$1" "$2" "$truncItems" "$itemsJson" | tee -a "$logger.json" 2>/dev/null 1>&2
}
logcheckresult() {
# Log to JSON
log_to_json "$@"
# Log remediation measure to JSON
if [ -n "$remediation" ] && [ "$1" != "PASS" ] && [ "$printremediation" = "1" ]; then
printf ",\n \"remediation\": \"%s\"" "$remediation" | tee -a "$logger.json" 2>/dev/null 1>&2
if [ -n "$remediationImpact" ]; then
printf ",\n \"remediation-impact\": \"%s\"" "$remediationImpact" | tee -a "$logger.json" 2>/dev/null 1>&2
fi
fi
printf "\n }" | tee -a "$logger.json" 2>/dev/null 1>&2
# Save remediation measure for print log to stdout
if [ -n "$remediation" ] && [ "$1" != "PASS" ]; then
if [ -n "${checkHeader}" ]; then
if [ -n "${addSpaceHeader}" ]; then
globalRemediation="${globalRemediation}\n"
fi
globalRemediation="${globalRemediation}\n${bldblu}[INFO]${txtrst} ${checkHeader}"
checkHeader=""
addSpaceHeader="1"
fi
globalRemediation="${globalRemediation}\n${bldblu}[INFO]${txtrst} ${id} - ${remediation}"
if [ -n "${remediationImpact}" ]; then
globalRemediation="${globalRemediation} Remediation Impact: ${remediationImpact}"
fi
fi
}

View file

@ -1,192 +0,0 @@
#!/bin/sh
host_configuration() {
check_1
check_1_1
check_1_1_1
check_1_1_2
check_1_2
check_1_2_1
check_1_2_2
check_1_2_3
check_1_2_4
check_1_2_5
check_1_2_6
check_1_2_7
check_1_2_8
check_1_2_9
check_1_2_10
check_1_2_11
check_1_2_12
check_1_end
}
docker_daemon_configuration() {
check_2
check_2_1
check_2_2
check_2_3
check_2_4
check_2_5
check_2_6
check_2_7
check_2_8
check_2_9
check_2_10
check_2_11
check_2_12
check_2_13
check_2_14
check_2_15
check_2_16
check_2_17
check_2_end
}
docker_daemon_files() {
check_3
check_3_1
check_3_2
check_3_3
check_3_4
check_3_5
check_3_6
check_3_7
check_3_8
check_3_9
check_3_10
check_3_11
check_3_12
check_3_13
check_3_14
check_3_15
check_3_16
check_3_17
check_3_18
check_3_19
check_3_20
check_3_21
check_3_22
check_3_end
}
container_images() {
check_4
check_4_1
check_4_2
check_4_3
check_4_4
check_4_5
check_4_6
check_4_7
check_4_8
check_4_9
check_4_10
check_4_11
check_4_end
}
container_runtime() {
check_5
check_running_containers
check_5_1
check_5_2
check_5_3
check_5_4
check_5_5
check_5_6
check_5_7
check_5_8
check_5_9
check_5_10
check_5_11
check_5_12
check_5_13
check_5_14
check_5_15
check_5_16
check_5_17
check_5_18
check_5_19
check_5_20
check_5_21
check_5_22
check_5_23
check_5_24
check_5_25
check_5_26
check_5_27
check_5_28
check_5_29
check_5_30
check_5_31
check_5_end
}
docker_security_operations() {
check_6
check_6_1
check_6_2
check_6_end
}
docker_swarm_configuration() {
check_7
check_7_1
check_7_2
check_7_3
check_7_4
check_7_5
check_7_6
check_7_7
check_7_8
check_7_9
check_7_10
check_7_end
}
docker_enterprise_configuration() {
check_8
check_product_license
check_8_1
check_8_1_1
check_8_1_2
check_8_1_3
check_8_1_4
check_8_1_5
check_8_1_6
check_8_1_7
check_8_2
check_8_2_1
check_8_end
}
community_checks() {
check_c
check_c_1
check_c_2
check_c_end
}
# CIS
cis() {
host_configuration
docker_daemon_configuration
docker_daemon_files
container_images
container_runtime
docker_security_operations
docker_swarm_configuration
docker_enterprise_configuration
}
# Community contributed
community() {
community_checks
}
# All
all() {
cis
community
}

BIN
img/benchmark_log.png Normal file

Binary file not shown.

After

(image error) Size: 346 KiB

View file

@ -1,81 +0,0 @@
#!/bin/sh
if [ -n "$nocolor" ] && [ "$nocolor" = "nocolor" ]; then
bldred=''
bldgrn=''
bldblu=''
bldylw=''
txtrst=''
else
bldred='\033[1;31m'
bldgrn='\033[1;32m'
bldblu='\033[1;34m'
bldylw='\033[1;33m' # Yellow
txtrst='\033[0m'
fi
logit () {
printf "%b\n" "$1" | tee -a "$logger"
}
info () {
printf "%b\n" "${bldblu}[INFO]${txtrst} $1" | tee -a "$logger"
}
pass () {
printf "%b\n" "${bldgrn}[PASS]${txtrst} $1" | tee -a "$logger"
}
warn () {
printf "%b\n" "${bldred}[WARN]${txtrst} $1" | tee -a "$logger"
}
note () {
printf "%b\n" "${bldylw}[NOTE]${txtrst} $1" | tee -a "$logger"
}
yell () {
printf "%b\n" "${bldylw}$1${txtrst}\n"
}
beginjson () {
printf "{\n \"dockerbenchsecurity\": \"%s\",\n \"start\": %s,\n \"tests\": [" "$1" "$2" | tee "$logger.json" 2>/dev/null 1>&2
}
endjson (){
printf "\n ], \"checks\": %s, \"score\": %s, \"end\": %s \n}\n" "$1" "$2" "$3" | tee -a "$logger.json" 2>/dev/null 1>&2
}
logjson (){
printf "\n \"%s\": \"%s\"," "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
}
SSEP=
SEP=
startsectionjson() {
printf "%s\n {\"id\": \"%s\", \"desc\": \"%s\", \"results\": [" "$SSEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
SEP=
SSEP=","
}
endsectionjson() {
printf "\n ]}" | tee -a "$logger.json" 2>/dev/null 1>&2
}
starttestjson() {
printf "%s\n {\"id\": \"%s\", \"desc\": \"%s\", " "$SEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
SEP=","
}
resulttestjson() {
if [ $# -eq 1 ]; then
printf "\"result\": \"%s\"}" "$1" | tee -a "$logger.json" 2>/dev/null 1>&2
elif [ $# -eq 2 ]; then
# Result also contains details
printf "\"result\": \"%s\", \"details\": \"%s\"}" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2
else
# Result also includes details and a list of items. Add that directly to details and to an array property "items"
itemsJson=$(printf "["; ISEP=""; for item in $3; do printf "%s\"%s\"" "$ISEP" "$item"; ISEP=","; done; printf "]")
printf "\"result\": \"%s\", \"details\": \"%s: %s\", \"items\": %s}" "$1" "$2" "$3" "$itemsJson" | tee -a "$logger.json" 2>/dev/null 1>&2
fi
}

File diff suppressed because it is too large Load diff

View file

@ -1,430 +1,422 @@
#!/bin/sh
#!/bin/bash
check_2() {
logit "\n"
id_2="2"
desc_2="Docker daemon configuration"
check_2="$id_2 - $desc_2"
info "$check_2"
startsectionjson "$id_2" "$desc_2"
logit ""
local id="2"
local desc="Docker daemon configuration"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
# 2.1
check_2_1() {
id_2_1="2.1"
desc_2_1="Ensure network traffic is restricted between containers on the default bridge"
check_2_1="$id_2_1 - $desc_2_1"
starttestjson "$id_2_1" "$desc_2_1"
local id="2.1"
local desc="Run the Docker daemon as a non-root user, if possible (Manual)"
local remediation="Follow the current Dockerdocumentation on how to install the Docker daemon as a non-root user."
local remediationImpact="There are multiple prerequisites depending on which distribution that is in use, and also known limitations regarding networking and resource limitation. Running in rootless mode also changes the location of any configuration files in use, including all containers using the daemon."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_effective_command_line_args '--icc' | grep false >/dev/null 2>&1; then
pass "$check_2_1"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_configuration_file_args 'icc' | grep "false" >/dev/null 2>&1; then
pass "$check_2_1"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_1"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
note -c "$check"
logcheckresult "INFO"
}
# 2.2
check_2_2() {
id_2_2="2.2"
desc_2_2="Ensure the logging level is set to 'info'"
check_2_2="$id_2_2 - $desc_2_2"
starttestjson "$id_2_2" "$desc_2_2"
local id="2.2"
local desc="Ensure network traffic is restricted between containers on the default bridge (Scored)"
local remediation="Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false."
local remediationImpact="Inter-container communication is disabled on the default network bridge. If any communication between containers on the same host is desired, it needs to be explicitly defined using container linking or custom networks."
local check="$id - $desc"
starttestjson "$id" "$desc"
if get_docker_effective_command_line_args '--icc' | grep false >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
if [[ $(get_docker_configuration_file_args 'icc' | grep "false") ]] && [[ $(get_docker_configuration_file_args 'icc' | grep "false") != "null" ]] ; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
check_2_3() {
local id="2.3"
local desc="Ensure the logging level is set to 'info' (Scored)"
local remediation="Ensure that the Docker daemon configuration file has the following configuration included log-level: info. Alternatively, run the Docker daemon as following: dockerd --log-level=info"
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'log-level' >/dev/null 2>&1; then
if get_docker_configuration_file_args 'log-level' | grep info >/dev/null 2>&1; then
pass "$check_2_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif [ -z "$(get_docker_configuration_file_args 'log-level')" ]; then
pass "$check_2_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_2"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
elif get_docker_effective_command_line_args '-l'; then
if [ -z "$(get_docker_configuration_file_args 'log-level')" ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
return
fi
if get_docker_effective_command_line_args '-l'; then
if get_docker_effective_command_line_args '-l' | grep "info" >/dev/null 2>&1; then
pass "$check_2_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_2"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
else
pass "$check_2_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.3
check_2_3() {
id_2_3="2.3"
desc_2_3="Ensure Docker is allowed to make changes to iptables"
check_2_3="$id_2_3 - $desc_2_3"
starttestjson "$id_2_3" "$desc_2_3"
totalChecks=$((totalChecks + 1))
if get_docker_effective_command_line_args '--iptables' | grep "false" >/dev/null 2>&1; then
warn "$check_2_3"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
elif get_docker_configuration_file_args 'iptables' | grep "false" >/dev/null 2>&1; then
warn "$check_2_3"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
else
pass "$check_2_3"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
fi
}
# 2.4
check_2_4() {
id_2_4="2.4"
desc_2_4="Ensure insecure registries are not used"
check_2_4="$id_2_4 - $desc_2_4"
starttestjson "$id_2_4" "$desc_2_4"
local id="2.4"
local desc="Ensure Docker is allowed to make changes to iptables (Scored)"
local remediation="Do not run the Docker daemon with --iptables=false option."
local remediationImpact="The Docker daemon service requires iptables rules to be enabled before it starts."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_effective_command_line_args '--insecure-registry' | grep "insecure-registry" >/dev/null 2>&1; then
warn "$check_2_4"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
elif ! [ -z "$(get_docker_configuration_file_args 'insecure-registries')" ]; then
if get_docker_configuration_file_args 'insecure-registries' | grep '\[]' >/dev/null 2>&1; then
pass "$check_2_4"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_4"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
else
pass "$check_2_4"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
if get_docker_effective_command_line_args '--iptables' | grep "false" >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
if [[ $(get_docker_configuration_file_args 'iptables' | grep "false") ]] && [[ $(get_docker_configuration_file_args 'iptables' | grep "false") != "null" ]] ; then
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.5
check_2_5() {
id_2_5="2.5"
desc_2_5="Ensure aufs storage driver is not used"
check_2_5="$id_2_5 - $desc_2_5"
starttestjson "$id_2_5" "$desc_2_5"
local id="2.5"
local desc="Ensure insecure registries are not used (Scored)"
local remediation="You should ensure that no insecure registries are in use."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "^Storage Driver:\s*aufs\s*$" >/dev/null 2>&1; then
warn "$check_2_5"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
else
pass "$check_2_5"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
if get_docker_effective_command_line_args '--insecure-registry' | grep "insecure-registry" >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
if [[ $(get_docker_configuration_file_args 'insecure-registries' | grep -v '\[]') ]] && [[ $(get_docker_configuration_file_args 'insecure-registries' | grep -v '\[]') != "null" ]] ; then
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.6
check_2_6() {
id_2_6="2.6"
desc_2_6="Ensure TLS authentication for Docker daemon is configured"
check_2_6="$id_2_6 - $desc_2_6"
starttestjson "$id_2_6" "$desc_2_6"
local id="2.6"
local desc="Ensure aufs storage driver is not used (Scored)"
local remediation="Do not start Docker daemon as using dockerd --storage-driver aufs option."
local remediationImpact="aufs is the only storage driver that allows containers to share executable and shared library memory. Its use should be reviewed in line with your organization's security policy."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if [ grep -i 'tcp://' "$CONFIG_FILE" 2>/dev/null 1>&2 ] || \
[ $(get_docker_cumulative_command_line_args '-H' | grep -vE '(unix|fd)://') >/dev/null 2>&1 ]; then
if docker info 2>/dev/null | grep -e "^\sStorage Driver:\s*aufs\s*$" >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
check_2_7() {
local id="2.7"
local desc="Ensure TLS authentication for Docker daemon is configured (Scored)"
local remediation="Follow the steps mentioned in the Docker documentation or other references. By default, TLS authentication is not configured."
local remediationImpact="You would need to manage and guard certificates and keys for the Docker daemon and Docker clients."
local check="$id - $desc"
starttestjson "$id" "$desc"
if $(grep -qE "host.*tcp://" "$CONFIG_FILE") || \
[ $(get_docker_cumulative_command_line_args '-H' | grep -vE '(unix|fd)://') > /dev/null 2>&1 ]; then
if [ $(get_docker_configuration_file_args '"tlsverify":' | grep 'true') ] || \
[ $(get_docker_cumulative_command_line_args '--tlsverify' | grep 'tlsverify') >/dev/null 2>&1 ]; then
pass "$check_2_6"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif [ $(get_docker_configuration_file_args '"tls":' | grep 'true') ] || \
pass -s "$check"
logcheckresult "PASS"
return
fi
if [ $(get_docker_configuration_file_args '"tls":' | grep 'true') ] || \
[ $(get_docker_cumulative_command_line_args '--tls' | grep 'tls$') >/dev/null 2>&1 ]; then
warn "$check_2_6"
warn -s "$check"
warn " * Docker daemon currently listening on TCP with TLS, but no verification"
resulttestjson "WARN" "Docker daemon currently listening on TCP with TLS, but no verification"
currentScore=$((currentScore - 1))
else
warn "$check_2_6"
warn " * Docker daemon currently listening on TCP without TLS"
resulttestjson "WARN" "Docker daemon currently listening on TCP without TLS"
currentScore=$((currentScore - 1))
logcheckresult "WARN" "Docker daemon currently listening on TCP with TLS, but no verification"
return
fi
else
info "$check_2_6"
info " * Docker daemon not listening on TCP"
resulttestjson "INFO" "Docker daemon not listening on TCP"
currentScore=$((currentScore + 0))
warn -s "$check"
warn " * Docker daemon currently listening on TCP without TLS"
logcheckresult "WARN" "Docker daemon currently listening on TCP without TLS"
return
fi
info -c "$check"
info " * Docker daemon not listening on TCP"
logcheckresult "INFO" "Docker daemon not listening on TCP"
}
# 2.7
check_2_7() {
id_2_7="2.7"
desc_2_7="Ensure the default ulimit is configured appropriately"
check_2_7="$id_2_7 - $desc_2_7"
starttestjson "$id_2_7" "$desc_2_7"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'default-ulimit' | grep -v '{}' >/dev/null 2>&1; then
pass "$check_2_7"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--default-ulimit' | grep "default-ulimit" >/dev/null 2>&1; then
pass "$check_2_7"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
info "$check_2_7"
info " * Default ulimit doesn't appear to be set"
resulttestjson "INFO" "Default ulimit doesn't appear to be set"
currentScore=$((currentScore + 0))
fi
}
# 2.8
check_2_8() {
id_2_8="2.8"
desc_2_8="Enable user namespace support"
check_2_8="$id_2_8 - $desc_2_8"
starttestjson "$id_2_8" "$desc_2_8"
local id="2.8"
local desc="Ensure the default ulimit is configured appropriately (Manual)"
local remediation="Run Docker in daemon mode and pass --default-ulimit as option with respective ulimits as appropriate in your environment and in line with your security policy. Example: dockerd --default-ulimit nproc=1024:2048 --default-ulimit nofile=100:200"
local remediationImpact="If ulimits are set incorrectly this could cause issues with system resources, possibly causing a denial of service condition."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'userns-remap' | grep -v '""'; then
pass "$check_2_8"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--userns-remap' | grep "userns-remap" >/dev/null 2>&1; then
pass "$check_2_8"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_8"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
if [[ $(get_docker_configuration_file_args 'default-ulimits' | grep -v '{}') ]] && [[ $(get_docker_configuration_file_args 'default-ulimits' | grep -v '{}') != "null" ]] ; then
pass -c "$check"
logcheckresult "PASS"
return
fi
if get_docker_effective_command_line_args '--default-ulimit' | grep "default-ulimit" >/dev/null 2>&1; then
pass -c "$check"
logcheckresult "PASS"
return
fi
info -c "$check"
info " * Default ulimit doesn't appear to be set"
logcheckresult "INFO" "Default ulimit doesn't appear to be set"
}
# 2.9
check_2_9() {
id_2_9="2.9"
desc_2_9="Ensure the default cgroup usage has been confirmed"
check_2_9="$id_2_9 - $desc_2_9"
starttestjson "$id_2_9" "$desc_2_9"
local id="2.9"
local desc="Enable user namespace support (Scored)"
local remediation="Please consult the Docker documentation for various ways in which this can be configured depending upon your requirements. The high-level steps are: Ensure that the files /etc/subuid and /etc/subgid exist. Start the docker daemon with --userns-remap flag."
local remediationImpact="User namespace remapping is incompatible with a number of Docker features and also currently breaks some of its functionalities."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'cgroup-parent' | grep -v ''; then
warn "$check_2_9"
info " * Confirm cgroup usage"
resulttestjson "WARN" "Confirm cgroup usage"
currentScore=$((currentScore + 0))
elif get_docker_effective_command_line_args '--cgroup-parent' | grep "cgroup-parent" >/dev/null 2>&1; then
warn "$check_2_9"
info " * Confirm cgroup usage"
resulttestjson "WARN" "Confirm cgroup usage"
currentScore=$((currentScore + 0))
else
pass "$check_2_9"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
if [[ $(get_docker_configuration_file_args 'userns-remap' | grep -v '""') ]] && [[ $(get_docker_configuration_file_args 'userns-remap' | grep -v '""') != "null" ]] ; then
pass -s "$check"
logcheckresult "PASS"
return
fi
if get_docker_effective_command_line_args '--userns-remap' | grep "userns-remap" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
# 2.10
check_2_10() {
id_2_10="2.10"
desc_2_10="Ensure base device size is not changed until needed"
check_2_10="$id_2_10 - $desc_2_10"
starttestjson "$id_2_10" "$desc_2_10"
local id="2.10"
local desc="Ensure the default cgroup usage has been confirmed (Scored)"
local remediation="The default setting is in line with good security practice and can be left in situ."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'storage-opts' | grep "dm.basesize" >/dev/null 2>&1; then
warn "$check_2_10"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
elif get_docker_effective_command_line_args '--storage-opt' | grep "dm.basesize" >/dev/null 2>&1; then
warn "$check_2_10"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
else
pass "$check_2_10"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
if get_docker_configuration_file_args 'cgroup-parent' | grep -v ''; then
warn -s "$check"
info " * Confirm cgroup usage"
logcheckresult "WARN" "Confirm cgroup usage"
return
fi
if get_docker_effective_command_line_args '--cgroup-parent' | grep "cgroup-parent" >/dev/null 2>&1; then
warn -s "$check"
info " * Confirm cgroup usage"
logcheckresult "WARN" "Confirm cgroup usage"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.11
check_2_11() {
id_2_11="2.11"
desc_2_11="Ensure that authorization for Docker client commands is enabled"
check_2_11="$id_2_11 - $desc_2_11"
starttestjson "$id_2_11" "$desc_2_11"
local id="2.11"
local desc="Ensure base device size is not changed until needed (Scored)"
local remediation="Do not set --storage-opt dm.basesize until needed."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]'; then
pass "$check_2_11"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--authorization-plugin' | grep "authorization-plugin" >/dev/null 2>&1; then
pass "$check_2_11"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_11"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
if get_docker_configuration_file_args 'storage-opts' | grep "dm.basesize" >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
if get_docker_effective_command_line_args '--storage-opt' | grep "dm.basesize" >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.12
check_2_12() {
id_2_12="2.12"
desc_2_12="Ensure centralized and remote logging is configured"
check_2_12="$id_2_12 - $desc_2_12"
starttestjson "$id_2_12" "$desc_2_12"
local id="2.12"
local desc="Ensure that authorization for Docker client commands is enabled (Scored)"
local remediation="Install/Create an authorization plugin. Configure the authorization policy as desired. Start the docker daemon using command dockerd --authorization-plugin=<PLUGIN_ID>"
local remediationImpact="Each Docker command needs to pass through the authorization plugin mechanism. This may have a performance impact"
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info --format '{{ .LoggingDriver }}' | grep 'json-file' >/dev/null 2>&1; then
warn "$check_2_12"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
else
pass "$check_2_12"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
if [[ $(get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]') ]] && [[ $(get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]') != "null" ]] ; then
pass -s "$check"
logcheckresult "PASS"
return
fi
if get_docker_effective_command_line_args '--authorization-plugin' | grep "authorization-plugin" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
# 2.13
check_2_13() {
id_2_13="2.13"
desc_2_13="Ensure live restore is Enabled"
check_2_13="$id_2_13 - $desc_2_13"
starttestjson "$id_2_13" "$desc_2_13"
local id="2.13"
local desc="Ensure centralized and remote logging is configured (Scored)"
local remediation="Set up the desired log driver following its documentation. Start the docker daemon using that logging driver. Example: dockerd --log-driver=syslog --log-opt syslog-address=tcp://192.xxx.xxx.xxx"
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Live Restore Enabled:\s*true\s*" >/dev/null 2>&1; then
pass "$check_2_13"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
pass "$check_2_13 (Incompatible with swarm mode)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--live-restore' | grep "live-restore" >/dev/null 2>&1; then
pass "$check_2_13"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_13"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
if docker info --format '{{ .LoggingDriver }}' | grep 'json-file' >/dev/null 2>&1; then
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check"
logcheckresult "PASS"
}
# 2.14
check_2_14() {
id_2_14="2.14"
desc_2_14="Ensure Userland Proxy is Disabled"
check_2_14="$id_2_14 - $desc_2_14"
starttestjson "$id_2_14" "$desc_2_14"
local id="2.14"
local desc="Ensure containers are restricted from acquiring new privileges (Scored)"
local remediation="You should run the Docker daemon using command: dockerd --no-new-privileges"
local remediationImpact="no_new_priv prevents LSMs such as SELinux from escalating the privileges of individual containers."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then
pass "$check_2_14"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--userland-proxy=false' 2>/dev/null | grep "userland-proxy=false" >/dev/null 2>&1; then
pass "$check_2_14"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_14"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
}
# 2.15
check_2_15() {
id_2_15="2.15"
desc_2_15="Ensure that a daemon-wide custom seccomp profile is applied if appropriate"
check_2_15="$id_2_15 - $desc_2_15"
starttestjson "$id_2_15" "$desc_2_15"
totalChecks=$((totalChecks + 1))
if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then
pass "$check_2_15"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
info "$check_2_15"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
fi
}
# 2.16
check_2_16() {
id_2_16="2.16"
desc_2_16="Ensure that experimental features are not implemented in production"
check_2_16="$id_2_16 - $desc_2_16"
starttestjson "$id_2_16" "$desc_2_16"
totalChecks=$((totalChecks + 1))
if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then
pass "$check_2_16"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_16"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
}
# 2.17
check_2_17() {
id_2_17="2.17"
desc_2_17="Ensure containers are restricted from acquiring new privileges"
check_2_17="$id_2_17 - $desc_2_17"
starttestjson "$id_2_17" "$desc_2_17"
totalChecks=$((totalChecks + 1))
if get_docker_effective_command_line_args '--no-new-privileges' | grep "no-new-privileges" >/dev/null 2>&1; then
pass "$check_2_17"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_configuration_file_args 'no-new-privileges' | grep true >/dev/null 2>&1; then
pass "$check_2_17"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_2_17"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
if get_docker_configuration_file_args 'no-new-privileges' | grep true >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
check_2_15() {
local id="2.15"
local desc="Ensure live restore is enabled (Scored)"
local remediation="Run Docker in daemon mode and pass --live-restore option."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
if docker info 2>/dev/null | grep -e "Live Restore Enabled:\s*true\s*" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
pass -s "$check (Incompatible with swarm mode)"
logcheckresult "PASS"
return
fi
if get_docker_effective_command_line_args '--live-restore' | grep "live-restore" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
check_2_16() {
local id="2.16"
local desc="Ensure Userland Proxy is Disabled (Scored)"
local remediation="You should run the Docker daemon using command: dockerd --userland-proxy=false"
local remediationImpact="Some systems with older Linux kernels may not be able to support hairpin NAT and therefore require the userland proxy service. Also, some networking setups can be impacted by the removal of the userland proxy."
local check="$id - $desc"
starttestjson "$id" "$desc"
if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
if get_docker_effective_command_line_args '--userland-proxy=false' 2>/dev/null | grep "userland-proxy=false" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
check_2_17() {
local id="2.17"
local desc="Ensure that a daemon-wide custom seccomp profile is applied if appropriate (Manual)"
local remediation="By default, Docker's default seccomp profile is applied. If this is adequate for your environment, no action is necessary."
local remediationImpact="A misconfigured seccomp profile could possibly interrupt your container environment. You should therefore exercise extreme care if you choose to override the default settings."
local check="$id - $desc"
starttestjson "$id" "$desc"
if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then
pass -c "$check"
logcheckresult "PASS"
return
fi
info -c "$check"
logcheckresult "INFO"
}
check_2_18() {
docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \
| awk '{print $NF; exit}' | tr -d '[:alpha:]-,.' | cut -c 1-4)
local id="2.18"
local desc="Ensure that experimental features are not implemented in production (Scored)"
local remediation="You should not pass --experimental as a runtime parameter to the Docker daemon on production systems."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
if [ "$docker_version" -le 1903 ]; then
if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
return
fi
local desc="$desc (Deprecated)"
local check="$id - $desc"
info -c "$desc"
logcheckresult "INFO"
}
check_2_end() {

File diff suppressed because it is too large Load diff

View file

@ -1,211 +1,200 @@
#!/bin/sh
#!/bin/bash
check_4() {
logit "\n"
id_4="4"
desc_4="Container Images and Build File"
check_4="$id_4 - $desc_4"
info "$check_4"
startsectionjson "$id_4" "$desc_4"
logit ""
local id="4"
local desc="Container Images and Build File"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
# 4.1
check_4_1() {
id_4_1="4.1"
desc_4_1="Ensure a user for the container has been created"
check_4_1="$id_4_1 - $desc_4_1"
starttestjson "$id_4_1" "$desc_4_1"
totalChecks=$((totalChecks + 1))
local id="4.1"
local desc="Ensure that a user for the container has been created (Automated)"
local remediation="You should ensure that the Dockerfile for each container image contains the information: USER <username or ID>. If there is no specific user created in the container base image, then make use of the useradd command to add a specific user before the USER instruction in the Dockerfile."
local remediationImpact="Running as a non-root user can present challenges where you wish to bind mount volumes from the underlying host. In this case, care should be taken to ensure that the user running the contained process can read and write to the bound directory, according to their requirements."
local check="$id - $desc"
starttestjson "$id" "$desc"
# If container_users is empty, there are no running containers
if [ -z "$containers" ]; then
info "$check_4_1"
info -c "$check"
info " * No containers running"
resulttestjson "INFO" "No containers running"
currentScore=$((currentScore + 0))
else
# We have some containers running, set failure flag to 0. Check for Users.
fail=0
# Make the loop separator be a new-line in POSIX compliant fashion
set -f; IFS=$'
'
root_containers=""
for c in $containers; do
user=$(docker inspect --format 'User={{.Config.User}}' "$c")
if [ "$user" = "User=0" ] || [ "$user" = "User=root" ] || [ "$user" = "User=" ] || [ "$user" = "User=[]" ] || [ "$user" = "User=<no value>" ]; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn "$check_4_1"
warn " * Running as root: $c"
root_containers="$root_containers $c"
fail=1
else
warn " * Running as root: $c"
root_containers="$root_containers $c"
fi
fi
done
# We went through all the containers and found none running as root
if [ $fail -eq 0 ]; then
pass "$check_4_1"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
resulttestjson "WARN" "running as root" "$root_containers"
currentScore=$((currentScore - 1))
fi
logcheckresult "INFO" "No containers running"
return
fi
# We have some containers running, set failure flag to 0. Check for Users.
fail=0
# Make the loop separator be a new-line in POSIX compliant fashion
set -f; IFS=$'
'
root_containers=""
for c in $containers; do
user=$(docker inspect --format 'User={{.Config.User}}' "$c")
if [ "$user" = "User=0" ] || [ "$user" = "User=root" ] || [ "$user" = "User=" ] || [ "$user" = "User=[]" ] || [ "$user" = "User=<no value>" ]; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn -s "$check"
warn " * Running as root: $c"
root_containers="$root_containers $c"
fail=1
continue
fi
warn " * Running as root: $c"
root_containers="$root_containers $c"
fi
done
# We went through all the containers and found none running as root
if [ $fail -eq 0 ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "running as root" "$root_containers"
# Make the loop separator go back to space
set +f; unset IFS
}
# 4.2
check_4_2() {
id_4_2="4.2"
desc_4_2="Ensure that containers use only trusted base images"
check_4_2="$id_4_2 - $desc_4_2"
starttestjson "$id_4_2" "$desc_4_2"
local id="4.2"
local desc="Ensure that containers use only trusted base images (Manual)"
local remediation="Configure and use Docker Content trust. View the history of each Docker image to evaluate its risk, dependent on the sensitivity of the application you wish to deploy using it. Scan Docker images for vulnerabilities at regular intervals."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_2"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
# 4.3
check_4_3() {
id_4_3="4.3"
desc_4_3="Ensure that unnecessary packages are not installed in the container"
check_4_3="$id_4_3 - $desc_4_3"
starttestjson "$id_4_3" "$desc_4_3"
local id="4.3"
local desc="Ensure that unnecessary packages are not installed in the container (Manual)"
local remediation="You should not install anything within the container that is not required. You should consider using a minimal base image if you can. Some of the options available include BusyBox and Alpine. Not only can this trim your image size considerably, but there would also be fewer pieces of software which could contain vectors for attack."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_3"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
# 4.4
check_4_4() {
id_4_4="4.4"
desc_4_4="Ensure images are scanned and rebuilt to include security patches"
check_4_4="$id_4_4 - $desc_4_4"
starttestjson "$id_4_4" "$desc_4_4"
local id="4.4"
local desc="Ensure images are scanned and rebuilt to include security patches (Manual)"
local remediation="Images should be re-built ensuring that the latest version of the base images are used, to keep the operating system patch level at an appropriate level. Once the images have been re-built, containers should be re-started making use of the updated images."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_4"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
# 4.5
check_4_5() {
id_4_5="4.5"
desc_4_5="Ensure Content trust for Docker is Enabled"
check_4_5="$id_4_5 - $desc_4_5"
starttestjson "$id_4_5" "$desc_4_5"
local id="4.5"
local desc="Ensure Content trust for Docker is Enabled (Automated)"
local remediation="Add DOCKER_CONTENT_TRUST variable to the /etc/environment file using command echo DOCKER_CONTENT_TRUST=1 | sudo tee -a /etc/environment."
local remediationImpact="This prevents users from working with tagged images unless they contain a signature."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if [ "x$DOCKER_CONTENT_TRUST" = "x1" ]; then
pass "$check_4_5"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_4_5"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
if [ "$DOCKER_CONTENT_TRUST" = "1" ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
# 4.6
check_4_6() {
id_4_6="4.6"
desc_4_6="Ensure that HEALTHCHECK instructions have been added to container images"
check_4_6="$id_4_6 - $desc_4_6"
starttestjson "$id_4_6" "$desc_4_6"
local id="4.6"
local desc="Ensure that HEALTHCHECK instructions have been added to container images (Automated)"
local remediation="You should follow the Docker documentation and rebuild your container images to include the HEALTHCHECK instruction."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
fail=0
no_health_images=""
for img in $images; do
if docker inspect --format='{{.Config.Healthcheck}}' "$img" 2>/dev/null | grep -e "<nil>" >/dev/null 2>&1; then
if [ $fail -eq 0 ]; then
fail=1
warn "$check_4_6"
warn -s "$check"
fi
imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null)
if ! [ "$imgName" = '[]' ]; then
warn " * No Healthcheck found: $imgName"
no_health_images="$no_health_images $imgName"
no_health_images="$no_health_images $imgName"
else
warn " * No Healthcheck found: $img"
no_health_images="$no_health_images $img"
fi
fi
done
if [ $fail -eq 0 ]; then
pass "$check_4_6"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
resulttestjson "WARN" "Images w/o HEALTHCHECK" "$no_health_images"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "Images w/o HEALTHCHECK" "$no_health_images"
}
# 4.7
check_4_7() {
id_4_7="4.7"
desc_4_7="Ensure update instructions are not use alone in the Dockerfile"
check_4_7="$id_4_7 - $desc_4_7"
starttestjson "$id_4_7" "$desc_4_7"
local id="4.7"
local desc="Ensure update instructions are not used alone in the Dockerfile (Manual)"
local remediation="You should use update instructions together with install instructions and version pinning for packages while installing them. This prevent caching and force the extraction of the required versions. Alternatively, you could use the --no-cache flag during the docker build process to avoid using cached layers."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
fail=0
update_images=""
for img in $images; do
if docker history "$img" 2>/dev/null | grep -e "update" >/dev/null 2>&1; then
if [ $fail -eq 0 ]; then
fail=1
info "$check_4_7"
info -c "$check"
fi
imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null)
if ! [ "$imgName" = '[]' ]; then
info " * Update instruction found: $imgName"
update_images="$update_images $imgName"
update_images="$update_images $imgName"
fi
fi
done
if [ $fail -eq 0 ]; then
pass "$check_4_7"
resulttestjson "PASS"
currentScore=$((currentScore + 0))
else
resulttestjson "INFO" "Update instructions found" "$update_images"
currentScore=$((currentScore + 0))
pass -c "$check"
logcheckresult "PASS"
return
fi
logcheckresult "INFO" "Update instructions found" "$update_images"
}
# 4.8
check_4_8() {
id_4_8="4.8"
desc_4_8="Ensure setuid and setgid permissions are removed"
check_4_8="$id_4_8 - $desc_4_8"
starttestjson "$id_4_8" "$desc_4_8"
local id="4.8"
local desc="Ensure setuid and setgid permissions are removed (Manual)"
local remediation="You should allow setuid and setgid permissions only on executables which require them. You could remove these permissions at build time by adding the following command in your Dockerfile, preferably towards the end of the Dockerfile: RUN find / -perm /6000 -type f -exec chmod a-s {} ; || true"
local remediationImpact="The above command would break all executables that depend on setuid or setgid permissions including legitimate ones. You should therefore be careful to modify the command to suit your requirements so that it does not reduce the permissions of legitimate programs excessively. Because of this, you should exercise a degree of caution and examine all processes carefully before making this type of modification in order to avoid outages."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_8"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
# 4.9
check_4_9() {
id_4_9="4.9"
desc_4_9="Ensure that COPY is used instead of ADD in Dockerfiles"
check_4_9="$id_4_9 - $desc_4_9"
starttestjson "$id_4_9" "$desc_4_9"
local id="4.9"
local desc="Ensure that COPY is used instead of ADD in Dockerfiles (Manual)"
local remediation="You should use COPY rather than ADD instructions in Dockerfiles."
local remediationImpact="Care needs to be taken in implementing this control if the application requires functionality that is part of the ADD instruction, for example, if you need to retrieve files from remote URLS."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
fail=0
add_images=""
for img in $images; do
@ -213,49 +202,57 @@ check_4_9() {
sed '$d' | grep -q 'ADD'; then
if [ $fail -eq 0 ]; then
fail=1
info "$check_4_9"
info -c "$check"
fi
imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null)
if ! [ "$imgName" = '[]' ]; then
info " * ADD in image history: $imgName"
add_images="$add_images $imgName"
fi
currentScore=$((currentScore + 0))
fi
done
if [ $fail -eq 0 ]; then
pass "$check_4_9"
resulttestjson "PASS"
currentScore=$((currentScore + 0))
else
resulttestjson "INFO" "Images using ADD" "$add_images"
pass -c "$check"
logcheckresult "PASS"
return
fi
logcheckresult "INFO" "Images using ADD" "$add_images"
}
# 4.10
check_4_10() {
id_4_10="4.10"
desc_4_10="Ensure secrets are not stored in Dockerfiles"
check_4_10="$id_4_10 - $desc_4_10"
starttestjson "$id_4_10" "$desc_4_10"
local id="4.10"
local desc="Ensure secrets are not stored in Dockerfiles (Manual)"
local remediation="Do not store any kind of secrets within Dockerfiles. Where secrets are required during the build process, make use of a secrets management tool, such as the buildkit builder included with Docker."
local remediationImpact="A proper secrets management process will be required for Docker image building."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_10"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
# 4.11
check_4_11() {
id_4_11="4.11"
desc_4_11="Ensure only verified packages are installed"
check_4_11="$id_4_11 - $desc_4_11"
starttestjson "$id_4_11" "$desc_4_11"
local id="4.11"
local desc="Ensure only verified packages are installed (Manual)"
local remediation="You should use a secure package distribution mechanism of your choice to ensure the authenticity of software packages."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_4_11"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "NOTE"
}
check_4_12() {
local id="4.12"
local desc="Ensure all signed artifacts are validated (Manual)"
local remediation="Validate artifacts signatures before uploading to the package registry."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
note -c "$check"
logcheckresult "NOTE"
}
check_4_end() {

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,22 @@
#!/bin/sh
#!/bin/bash
check_6() {
logit "\n"
id_6="6"
desc_6="Docker Security Operations"
check_6="$id_6 - $desc_6"
info "$check_6"
startsectionjson "$id_6" "$desc_6"
logit ""
local id="6"
local desc="Docker Security Operations"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
# 6.1
check_6_1() {
id_6_1="6.1"
desc_6_1="Ensure that image sprawl is avoided"
check_6_1="$id_6_1 - $desc_6_1"
starttestjson "$id_6_1" "$desc_6_1"
local id="6.1"
local desc="Ensure that image sprawl is avoided (Manual)"
local remediation="You should keep only the images that you actually need and establish a workflow to remove old or stale images from the host. Additionally, you should use features such as pull-by-digest to get specific images from the registry."
local remediationImpact="docker system prune -a removes all exited containers as well as all images and volumes that are not referenced by running containers, including for UCP and DTR."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
images=$(docker images -q | sort -u | wc -l | awk '{print $1}')
active_images=0
@ -26,37 +26,33 @@ check_6_1() {
fi
done
info "$check_6_1"
info " * There are currently: $images images"
info -c "$check"
info " * There are currently: $images images"
if [ "$active_images" -lt "$((images / 2))" ]; then
info " * Only $active_images out of $images are in use"
fi
resulttestjson "INFO" "$active_images active/$images in use"
currentScore=$((currentScore + 0))
logcheckresult "INFO" "$active_images active/$images in use"
}
# 6.2
check_6_2() {
id_6_2="6.2"
desc_6_2="Ensure that container sprawl is avoided"
check_6_2="$id_6_2 - $desc_6_2"
starttestjson "$id_6_2" "$desc_6_2"
local id="6.2"
local desc="Ensure that container sprawl is avoided (Manual)"
local remediation="You should periodically check your container inventory on each host and clean up containers which are not in active use with the command: docker container prune"
local remediationImpact="You should retain containers that are actively in use, and delete ones which are no longer needed."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
total_containers=$(docker info 2>/dev/null | grep "Containers" | awk '{print $2}')
running_containers=$(docker ps -q | wc -l | awk '{print $1}')
diff="$((total_containers - running_containers))"
info -c "$check"
if [ "$diff" -gt 25 ]; then
info "$check_6_2"
info " * There are currently a total of $total_containers containers, with only $running_containers of them currently running"
resulttestjson "INFO" "$total_containers total/$running_containers running"
else
info "$check_6_2"
info " * There are currently a total of $total_containers containers, with $running_containers of them currently running"
resulttestjson "INFO" "$total_containers total/$running_containers running"
fi
currentScore=$((currentScore + 0))
logcheckresult "INFO" "$total_containers total/$running_containers running"
}
check_6_end() {

View file

@ -1,93 +1,68 @@
#!/bin/sh
#!/bin/bash
check_7() {
logit "\n"
id_7="7"
desc_7="Docker Swarm Configuration"
check_7="$id_7 - $desc_7"
info "$check_7"
startsectionjson "$id_7" "$desc_7"
logit ""
local id="7"
local desc="Docker Swarm Configuration"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
# 7.1
check_7_1() {
id_7_1="7.1"
desc_7_1="Ensure swarm mode is not Enabled, if not needed"
check_7_1="$id_7_1 - $desc_7_1"
starttestjson "$id_7_1" "$desc_7_1"
local id="7.1"
local desc="Ensure that the minimum number of manager nodes have been created in a swarm (Automated)"
local remediation="If an excessive number of managers is configured, the excess nodes can be demoted to workers using command: docker node demote <manager node ID to be demoted>"
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:*\sinactive\s*" >/dev/null 2>&1; then
pass "$check_7_1"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_7_1"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
fi
}
# 7.2
check_7_2() {
id_7_2="7.2"
desc_7_2="Ensure that the minimum number of manager nodes have been created in a swarm"
check_7_2="$id_7_2 - $desc_7_2"
starttestjson "$id_7_2" "$desc_7_2"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
managernodes=$(docker node ls | grep -c "Leader")
if [ "$managernodes" -eq 1 ]; then
pass "$check_7_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_7_2"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
else
pass "$check_7_2 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.3
check_7_3() {
id_7_3="7.3"
desc_7_3="Ensure that swarm services are bound to a specific host interface"
check_7_3="$id_7_3 - $desc_7_3"
starttestjson "$id_7_3" "$desc_7_3"
check_7_2() {
local id="7.2"
local desc="Ensure that swarm services are bound to a specific host interface (Automated)"
local remediation="Resolving this issues requires re-initialization of the swarm, specifying a specific interface for the --listen-addr parameter."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
ss -lnt | grep -e '\[::]:2377 ' -e ':::2377' -e '*:2377 ' -e ' 0\.0\.0\.0:2377 ' >/dev/null 2>&1
$netbin -lnt | grep -e '\[::]:2377 ' -e ':::2377' -e '*:2377 ' -e ' 0\.0\.0\.0:2377 ' >/dev/null 2>&1
if [ $? -eq 1 ]; then
pass "$check_7_3"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_7_3"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
else
pass "$check_7_3 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
warn -s "$check"
logcheckresult "WARN"
return
fi
pass -s "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.4
check_7_4() {
id_7_4="7.4"
desc_7_4="Ensure that all Docker swarm overlay networks are encrypted"
check_7_4="$id_7_4 - $desc_7_4"
starttestjson "$id_7_4" "$desc_7_4"
check_7_3() {
local id="7.3"
local desc="Ensure that all Docker swarm overlay networks are encrypted (Automated)"
local remediation="You should create overlay networks the with --opt encrypted flag."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
fail=0
unencrypted_networks=""
for encnet in $(docker network ls --filter driver=overlay --quiet); do
@ -95,7 +70,7 @@ check_7_4() {
grep -v 'encrypted:' 2>/dev/null 1>&2; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn "$check_7_4"
warn -s "$check"
fail=1
fi
warn " * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
@ -104,145 +79,128 @@ check_7_4() {
done
# We went through all the networks and found none that are unencrypted
if [ $fail -eq 0 ]; then
pass "$check_7_4"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
resulttestjson "WARN" "Unencrypted overlay networks:" "$unencrypted_networks"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "Unencrypted overlay networks:" "$unencrypted_networks"
}
# 7.5
check_7_5() {
id_7_5="7.5"
desc_7_5="Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster"
check_7_5="$id_7_5 - $desc_7_5"
starttestjson "$id_7_5" "$desc_7_5"
check_7_4() {
local id="7.4"
local desc="Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster (Manual)"
local remediation="You should follow the docker secret documentation and use it to manage secrets effectively."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
if [ "$(docker secret ls -q | wc -l)" -ge 1 ]; then
pass "$check_7_5"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
info "$check_7_5"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
pass -c "$check"
logcheckresult "PASS"
return
fi
else
pass "$check_7_5 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
info -c "$check"
logcheckresult "INFO"
return
fi
pass -c "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.6
check_7_6() {
id_7_6="7.6"
desc_7_6="Ensure that swarm manager is run in auto-lock mode"
check_7_6="$id_7_6 - $desc_7_6"
starttestjson "$id_7_6" "$desc_7_6"
check_7_5() {
local id="7.5"
local desc="Ensure that swarm manager is run in auto-lock mode (Automated)"
local remediation="If you are initializing a swarm, use the command: docker swarm init --autolock. If you want to set --autolock on an existing swarm manager node, use the command: docker swarm update --autolock."
local remediationImpact="A swarm in auto-lock mode will not recover from a restart without manual intervention from an administrator to enter the unlock key. This may not always be desirable, and should be reviewed at a policy level."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
if ! docker swarm unlock-key 2>/dev/null | grep 'SWMKEY' 2>/dev/null 1>&2; then
warn "$check_7_6"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
else
pass "$check_7_6"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
warn -s "$check"
logcheckresult "WARN"
return
fi
else
pass "$check_7_6 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
pass -s "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.7
check_7_7() {
id_7_7="7.7"
desc_7_7="Ensure that the swarm manager auto-lock key is rotated periodically"
check_7_7="$id_7_7 - $desc_7_7"
starttestjson "$id_7_7" "$desc_7_7"
check_7_6() {
local id="7.6"
local desc="Ensure that the swarm manager auto-lock key is rotated periodically (Manual)"
local remediation="You should run the command docker swarm unlock-key --rotate to rotate the keys. To facilitate auditing of this recommendation, you should maintain key rotation records and ensure that you establish a pre-defined frequency for key rotation."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
note "$check_7_7"
resulttestjson "NOTE"
currentScore=$((currentScore + 0))
else
pass "$check_7_7 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
note -c "$check"
logcheckresult "NOTE"
return
fi
pass -c "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.8
check_7_8() {
id_7_8="7.8"
desc_7_8="Ensure that node certificates are rotated as appropriate"
check_7_8="$id_7_8 - $desc_7_8"
starttestjson "$id_7_8" "$desc_7_8"
check_7_7() {
local id="7.7"
local desc="Ensure that node certificates are rotated as appropriate (Manual)"
local remediation="You should run the command docker swarm update --cert-expiry 48h to set the desired expiry time on the node certificate."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
if docker info 2>/dev/null | grep "Expiry Duration: 2 days"; then
pass "$check_7_8"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
info "$check_7_8"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
pass -c "$check"
logcheckresult "PASS"
return
fi
else
pass "$check_7_8 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
info -c "$check"
logcheckresult "INFO"
return
fi
pass -c "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
check_7_8() {
local id="7.8"
local desc="Ensure that CA certificates are rotated as appropriate (Manual)"
local remediation="You should run the command docker swarm ca --rotate to rotate a certificate."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
info -c "$check"
logcheckresult "INFO"
return
fi
pass -c "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
# 7.9
check_7_9() {
id_7_9="7.9"
desc_7_9="Ensure that CA certificates are rotated as appropriate"
check_7_9="$id_7_9 - $desc_7_9"
starttestjson "$id_7_9" "$desc_7_9"
local id="7.9"
local desc="Ensure that management plane traffic is separated from data plane traffic (Manual)"
local remediation="You should initialize the swarm with dedicated interfaces for management and data planes respectively. Example: docker swarm init --advertise-addr=192.168.0.1 --data-path-addr=17.1.0.3"
local remediationImpact="This requires two network interfaces per node."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
info "$check_7_9"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
else
pass "$check_7_9 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
fi
}
# 7.10
check_7_10() {
id_7_10="7.10"
desc_7_10="Ensure that management plane traffic is separated from data plane traffic"
check_7_10="$id_7_10 - $desc_7_10"
starttestjson "$id_7_10" "$desc_7_10"
totalChecks=$((totalChecks + 1))
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
info "$check_7_10"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
else
pass "$check_7_10 (Swarm mode not enabled)"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
info -c "$check"
logcheckresult "INFO"
return
fi
pass -c "$check (Swarm mode not enabled)"
logcheckresult "PASS"
}
check_7_end() {

View file

@ -1,20 +1,19 @@
#!/bin/sh
#!/bin/bash
check_8() {
logit "\n"
id_8="8"
desc_8="Docker Enterprise Configuration"
check_8="$id_8 - $desc_8"
info "$check_8"
startsectionjson "$id_8" "$desc_8"
logit ""
local id="8"
local desc="Docker Enterprise Configuration"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
check_product_license() {
enterprise_license=1
if docker version | grep -Eqi '^Server.*Community$|Version.*-ce$'; then
info " * Community Engine license, skipping section 8"
enterprise_license=0
else
enterprise_license=1
fi
}
@ -23,129 +22,120 @@ check_8_1() {
return
fi
id_8_1="8.1"
desc_8_1="Universal Control Plane Configuration"
check_8_1="$id_8_1 - $desc_8_1"
info "$check_8_1"
local id="8.1"
local desc="Universal Control Plane Configuration"
local check="$id - $desc"
info "$check"
}
# 8.1.1
check_8_1_1() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_1="8.1.1"
desc_8_1_1="Configure the LDAP authentication service"
check_8_1_1="$id_8_1_1 - $desc_8_1_1"
starttestjson "$id_8_1_1" "$desc_8_1_1"
local id="8.1.1"
local desc="Configure the LDAP authentication service (Automated)"
local remediation="You can configure LDAP integration via the UCP Admin Settings UI. LDAP integration can also be enabled via a configuration file"
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_1"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.2
check_8_1_2() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_2="8.1.2"
desc_8_1_2="Use external certificates"
check_8_1_2="$id_8_1_2 - $desc_8_1_2"
starttestjson "$id_8_1_2" "$desc_8_1_2"
local id="8.1.2"
local desc="Use external certificates (Automated)"
local remediation="You can configure your own certificates for UCP either during installation or after installation via the UCP Admin Settings user interface."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_2"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.3
check_8_1_3() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_3="8.1.3"
desc_8_1_3="Enforce the use of client certificate bundles for unprivileged users"
check_8_1_3="$id_8_1_3 - $desc_8_1_3"
starttestjson "$id_8_1_3" "$desc_8_1_3"
local id="8.1.3"
local desc="Enforce the use of client certificate bundles for unprivileged users (Not Scored)"
local remediation="Client certificate bundles can be created in one of two ways. User Management UI: UCP Administrators can provision client certificate bundles on behalf of users. Self-Provision: Users with access to the UCP console can create client certificate bundles themselves."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_3"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.4
check_8_1_4() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_4="8.1.4"
desc_8_1_4="Configure applicable cluster role-based access control policies"
check_8_1_4="$id_8_1_4 - $desc_8_1_4"
starttestjson "$id_8_1_4" "$desc_8_1_4"
local id="8.1.4"
local desc="Configure applicable cluster role-based access control policies (Not Scored)"
local remediation="UCP RBAC components can be configured as required via the UCP User Management UI."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_4"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.5
check_8_1_5() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_5="8.1.5"
desc_8_1_5="Enable signed image enforcement"
check_8_1_5="$id_8_1_5 - $desc_8_1_5"
starttestjson "$id_8_1_5" "$desc_8_1_5"
local id="8.1.5"
local desc="Enable signed image enforcement (Automated)"
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_5"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.6
check_8_1_6() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_6="8.1.6"
desc_8_1_6="Set the Per-User Session Limit to a value of '3' or lower"
check_8_1_6="$id_8_1_6 - $desc_8_1_6"
starttestjson "$id_8_1_6" "$desc_8_1_6"
local id="8.1.6"
local desc="Set the Per-User Session Limit to a value of '3' or lower (Automated)"
local remediation="Retrieve a UCP API token. Retrieve and save UCP config. Open the ucp-config.toml file, set the per_user_limit entry under the [auth.sessions] section to a value of 3 or lower, but greater than 0. Update UCP with the new configuration."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_6"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
# 8.1.7
check_8_1_7() {
if [ "$enterprise_license" -ne 1 ]; then
return
fi
id_8_1_7="8.1.7"
desc_8_1_7="Set the 'Lifetime Minutes' and 'Renewal Threshold Minutes' values to '15' or lower and '0' respectively"
check_8_1_7="$id_8_1_7 - $desc_8_1_7"
starttestjson "$id_8_1_7" "$desc_8_1_7"
local id="8.1.7"
local desc="Set the 'Lifetime Minutes' and 'Renewal Threshold Minutes' values to '15' or lower and '0' respectively (Automated)"
local remediation="Retrieve a UCP API token. Retrieve and save UCP config. Open the ucp-config.toml file, set the lifetime_minutes and renewal_threshold_minutes entries under the [auth.sessions] section to values of 15 or lower and 0 respectively. Update UCP with the new configuration."
local remediationImpact="Setting the Lifetime Minutes setting to a value that is too lower would result in users having to constantly re-authenticate to their Docker Enterprise cluster."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_1_7"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
check_8_2() {
@ -153,11 +143,10 @@ check_8_2() {
return
fi
logit "\n"
id_8_2="8.2"
desc_8_2="Docker Trusted Registry Configuration"
check_8_2="$id_8_2 - $desc_8_2"
info "$check_8_2"
local id="8.2"
local desc="Docker Trusted Registry Configuration"
local check="$id - $desc"
info "$check"
}
check_8_2_1() {
@ -165,15 +154,15 @@ check_8_2_1() {
return
fi
id_8_2_1="8.2.1"
desc_8_2_1="Enable image vulnerability scanning"
check_8_2_1="$id_8_2_1 - $desc_8_2_1"
starttestjson "$id_8_2_1" "$desc_8_2_1"
local id="8.2.1"
local desc="Enable image vulnerability scanning (Automated)"
local remediation="You can navigate to DTR Settings UI and select the Security tab to access the image scanning configuration. Select the Enable Scanning slider to enable this functionality."
local remediationImpact="None."
local check="$id - $desc"
starttestjson "$id" "$desc"
totalChecks=$((totalChecks + 1))
note "$check_8_2_1"
resulttestjson "INFO"
currentScore=$((currentScore + 0))
note -c "$check"
logcheckresult "INFO"
}
check_8_end() {

View file

@ -1,57 +1,232 @@
#!/bin/sh
#!/bin/bash
check_c() {
logit "\n"
id_99="99"
desc_99="Community contributed checks"
check_99="$id_99 - $desc_99"
info "$check_99"
startsectionjson "$id_99" "$desc_99"
logit ""
local id="99"
local desc="Community contributed checks"
checkHeader="$id - $desc"
info "$checkHeader"
startsectionjson "$id" "$desc"
}
# check_c_1
check_c_1() {
check_c_1="C.1 - This is a example check"
totalChecks=$((totalChecks + 1))
local id="C.1"
local desc="This is a example check for a Automated check"
local remediation="This is an example remediation measure for a Automated check"
local remediationImpact="This is an example remediation impact for a Automated check"
local check="$id - $desc"
starttestjson "$id" "$desc"
if docker info --format='{{ .Architecture }}' | grep 'x86_64' 2>/dev/null 1>&2; then
pass "$check_c_1"
resulttestjson "PASS"
else
warn "$check_c_1"
resulttestjson "WARN"
pass -s "$check"
logcheckresult "PASS"
return
fi
if docker info --format='{{ .Architecture }}' | grep 'aarch64' 2>/dev/null 1>&2; then
info -c "$check"
logcheckresult "INFO"
return
fi
warn -s "$check"
logcheckresult "WARN"
}
check_c_1_1() {
local id="C.1.1"
local desc="This is a example check for a Manual check"
local remediation="This is an example remediation measure for a Manual check"
local remediationImpact="This is an example remediation impact for a Manual check"
local check="$id - $desc"
starttestjson "$id" "$desc"
if docker info --format='{{ .Architecture }}' | grep 'x86_64' 2>/dev/null 1>&2; then
pass -c "$check"
logcheckresult "PASS"
return
fi
if docker info --format='{{ .Architecture }}' | grep 'aarch64' 2>/dev/null 1>&2; then
info -c "$check"
logcheckresult "INFO"
return
fi
warn -c "$check"
logcheckresult "WARN"
}
# check_c_2
check_c_2() {
docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \
| awk '{print $NF; exit}' | tr -d '[:alpha:]-,.' | cut -c 1-4)
totalChecks=$((totalChecks + 1))
id_c_2="C.2"
desc_c_2="Ensure operations on legacy registry (v1) are Disabled"
check_c_2="$id_c_2 - $desc_c_2"
starttestjson "$id_c_2" "$desc_c_2"
local id="C.2"
local desc="Ensure operations on legacy registry (v1) are Disabled"
local remediation="Start docker daemon with --disable-legacy-registry=false flag. Starting with Docker 17.12, support for V1 registries has been removed, and the --disable-legacy-registry flag can no longer be used."
local remediationImpact="Prevents the docker daemon from pull, push, and login operations against v1 registries."
local check="$id - $desc"
starttestjson "$id" "$desc"
if [ "$docker_version" -lt 1712 ]; then
if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then
pass "$check_c_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
elif get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then
pass "$check_c_2"
resulttestjson "PASS"
currentScore=$((currentScore + 1))
else
warn "$check_c_2"
resulttestjson "WARN"
currentScore=$((currentScore - 1))
pass -s "$check"
logcheckresult "PASS"
return
fi
else
desc_c_2="$desc_c_2 (Deprecated)"
check_c_2="$id_c_2 - $desc_c_2"
info "$check_c_2"
resulttestjson "INFO"
if get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then
pass -s "$check"
logcheckresult "PASS"
return
fi
warn -s "$check"
logcheckresult "WARN"
return
fi
local desc="$desc (Deprecated)"
local check="$id - $desc"
info -c "$check"
logcheckresult "INFO"
}
check_c_5_3_1() {
local id="C.5.3.1"
local desc="Ensure that CAP_DAC_READ_SEARCH Linux kernel capability is disabled (Automated)"
local remediation="Please refer to https://github.com/cdk-team/CDK/wiki/Exploit:-cap-dac-read-search for PoC."
local remediationImpact=""
local check="$id - $desc"
starttestjson "$id" "$desc"
fail=0
caps_containers=""
for c in $containers; do
container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd }}' "$c")
caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
sed 's/CAPADD/CapAdd/')
if echo "$caps" | grep -q "DAC_READ_SEARCH"; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn -s "$check"
warn " * CAP_DAC_READ_SEARCH added to $c"
caps_containers="$caps_containers $c"
fail=1
continue
fi
warn " * CAP_DAC_READ_SEARCH added to $c"
caps_containers="$caps_containers $c"
fi
done
# We went through all the containers and found none with extra capabilities
if [ $fail -eq 0 ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "CAP_DAC_READ_SEARCH capability added for containers" "$caps_containers"
}
check_c_5_3_2() {
local id="C.5.3.2"
local desc="Ensure that CAP_SYS_MODULE Linux kernel capability is disabled (Automated)"
local remediation="Please refer to https://xcellerator.github.io/posts/docker_escape/ for PoC."
local remediationImpact=""
local check="$id - $desc"
starttestjson "$id" "$desc"
fail=0
caps_containers=""
for c in $containers; do
container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd }}' "$c")
caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
sed 's/CAPADD/CapAdd/')
if echo "$caps" | grep -q "SYS_MODULE"; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn -s "$check"
warn " * CAP_SYS_MODULE added to $c"
caps_containers="$caps_containers $c"
fail=1
continue
fi
warn " * CAP_SYS_MODULE added to $c"
caps_containers="$caps_containers $c"
fi
done
# We went through all the containers and found none with extra capabilities
if [ $fail -eq 0 ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "CAP_SYS_MODULE capability added for containers" "$caps_containers"
}
check_c_5_3_3() {
local id="C.5.3.3"
local desc="Ensure that CAP_SYS_ADMIN Linux kernel capability is disabled (Automated)"
local remediation="Please refer to https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/ for PoC."
local remediationImpact=""
local check="$id - $desc"
starttestjson "$id" "$desc"
fail=0
caps_containers=""
for c in $containers; do
container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd }}' "$c")
caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
sed 's/CAPADD/CapAdd/')
if echo "$caps" | grep -q "SYS_ADMIN"; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn -s "$check"
warn " * CAP_SYS_ADMIN added to $c"
caps_containers="$caps_containers $c"
fail=1
continue
fi
warn " * CAP_SYS_ADMIN added to $c"
caps_containers="$caps_containers $c"
fi
done
# We went through all the containers and found none with extra capabilities
if [ $fail -eq 0 ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "CAP_SYS_ADMIN capability added for containers" "$caps_containers"
}
check_c_5_3_4() {
local id="C.5.3.4"
local desc="Ensure that CAP_SYS_PTRACE Linux kernel capability is disabled (Automated)"
local remediation="Please refer to https://0xn3va.gitbook.io/cheat-sheets/container/escaping/excessive-capabilities#cap_sys_ptrace"
local remediationImpact=""
local check="$id - $desc"
starttestjson "$id" "$desc"
fail=0
caps_containers=""
for c in $containers; do
container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd }}' "$c")
caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
sed 's/CAPADD/CapAdd/')
if echo "$caps" | grep -q "SYS_PTRACE"; then
# If it's the first container, fail the test
if [ $fail -eq 0 ]; then
warn -s "$check"
warn " * CAP_SYS_PTRACE added to $c"
caps_containers="$caps_containers $c"
fail=1
continue
fi
warn " * CAP_SYS_PTRACE added to $c"
caps_containers="$caps_containers $c"
fi
done
# We went through all the containers and found none with extra capabilities
if [ $fail -eq 0 ]; then
pass -s "$check"
logcheckresult "PASS"
return
fi
logcheckresult "WARN" "CAP_SYS_PTRACE capability added for containers" "$caps_containers"
}
check_c_end() {