From 92f0a20ddc4bb281ed474af14386866baf8e732a Mon Sep 17 00:00:00 2001 From: orenzohar Date: Thu, 4 Nov 2021 14:15:30 +0200 Subject: [PATCH 01/13] general changes --- .gitignore | 5 +- compliance/cis.rego | 16 +++--- compliance/lib/common.rego | 6 +++ compliance/lib/osquery.rego | 11 +++- compliance/rules/cis_1_1_1/cis_1_1_1.rego | 20 ++++---- data.json | 5 -- data.yaml | 3 ++ input.json | 62 ++--------------------- main.rego | 2 +- 9 files changed, 46 insertions(+), 84 deletions(-) create mode 100644 compliance/lib/common.rego delete mode 100644 data.json create mode 100644 data.yaml diff --git a/.gitignore b/.gitignore index 524090b7..f5553c9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -data.json -input.json \ No newline at end of file +data.yaml +input.json +output.json \ No newline at end of file diff --git a/compliance/cis.rego b/compliance/cis.rego index 0714b9c4..c99adb8b 100644 --- a/compliance/cis.rego +++ b/compliance/cis.rego @@ -1,13 +1,15 @@ package compliance.cis +import data.compliance.cis.rules + # CIS 1.1.1 -findings[x] { - data.rules.cis_1_1_1 - x = data.compliance.cis.rules.cis_1_1_1.finding +findings[finding] { + data.activated_rules.cis_1_1_1 + finding = rules.cis_1_1_1.finding } -# CIS 1.2.2 -findings[x] { - data.rules.cis_1_2_2 - x = data.compliance.cis.rules.cis_1_2_2.finding +# CIS 1.1.2 +findings[finding] { + data.activated_rules.cis_1_1_2 + finding = rules.cis_1_1_2.finding } \ No newline at end of file diff --git a/compliance/lib/common.rego b/compliance/lib/common.rego new file mode 100644 index 00000000..b855cc2d --- /dev/null +++ b/compliance/lib/common.rego @@ -0,0 +1,6 @@ +package compliance.lib.common + +# set the rule result +calculate_result(evaluation) = "passed" { + evaluation +} else = "violation" \ No newline at end of file diff --git a/compliance/lib/osquery.rego b/compliance/lib/osquery.rego index 0488a6a3..c69a8f55 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/osquery.rego @@ -4,7 +4,6 @@ is_osquery { input.osquery } - is_file { is_osquery input.osquery.filename @@ -18,4 +17,14 @@ filename = x { filemode = x { is_file x = input.osquery.mode +} + +owner_user_id = x { + is_file + x = input.osquery.uid +} + +owner_group_id = x { + is_file + x = input.osquery.gid } \ No newline at end of file diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1.rego b/compliance/rules/cis_1_1_1/cis_1_1_1.rego index a44f1d03..31421edd 100644 --- a/compliance/rules/cis_1_1_1/cis_1_1_1.rego +++ b/compliance/rules/cis_1_1_1/cis_1_1_1.rego @@ -1,17 +1,19 @@ package compliance.cis.rules.cis_1_1_1 import data.compliance.lib.osquery +import data.compliance.lib.common -finding = {"message": msg, "tags": tags, "result": result} { +# Ensure that the API server pod specification file permissions are set to 644 or more restrictive + +finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { osquery.filename == "kube-apiserver.yaml" filemode := osquery.filemode pattern := "0?(0|1|2|3|4|5|6)(0|1|2|3|4)(0|1|2|3|4)" - # not regex.match(pattern, filemode) - result := calculate_result(false) - msg := "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)" - tags := ["cis", "cis 1.1.1", "kubernetes"] -} + rule_evaluation := regex.match(pattern, filemode) -calculate_result(passed) = "passed" { - passed -} else = "violation" \ No newline at end of file + # set result + evaluation := common.calculate_result(rule_evaluation) + fields := [{ "key": "filemode", "value": filemode }] + rule_name := "Ensure that the API server pod specification file permissions are set to 644 or more restrictive" + tags := ["cis", "cis 1.1.1", "kubernetes"] +} \ No newline at end of file diff --git a/data.json b/data.json deleted file mode 100644 index ab562902..00000000 --- a/data.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "cis_1_2_1": true - } -} \ No newline at end of file diff --git a/data.yaml b/data.yaml new file mode 100644 index 00000000..c0bca9f3 --- /dev/null +++ b/data.yaml @@ -0,0 +1,3 @@ +activated_rules: + cis_1_1_1: true + cis_1_1_2: true \ No newline at end of file diff --git a/input.json b/input.json index f2ca1e8b..5744ef8a 100644 --- a/input.json +++ b/input.json @@ -1,65 +1,9 @@ { - "agent": { - "hostname": "kind-1w-1c-control-plane", - "name": "kind-1w-1c-control-plane", - "id": "5997e578-56af-464a-af29-925d564724c4", - "ephemeral_id": "483a0204-fd4f-4fa6-9031-87676e3be5f1", - "type": "osquerybeat", - "version": "7.14.0" - }, "osquery": { - "gid": 0, - "atime": 1633537471, - "type": "regular", - "mtime": 1633278242, - "directory": "/hostfs/etc/kubernetes/manifests", - "inode": 2502045, - "mode": "0600", - "uid": 0, + "mode": "0700", "path": "/hostfs/etc/kubernetes/manifests/kube-apiserver.yaml", + "uid": "etc", "filename": "kube-apiserver.yaml", - "size": 3826, - "btime": 0, - "symlink": 0, - "ctime": 1633278242, - "block_size": 4096, - "device": 0, - "hard_links": 1 - }, - "elastic_agent": { - "id": "5997e578-56af-464a-af29-925d564724c4", - "version": "7.14.0", - "snapshot": false - }, - "type": "kind-1w-1c-control-plane", - "action_data": { - "query": "SELECT * FROM file WHERE path LIKE \"/hostfs/etc/kubernetes/manifests/%\";", - "id": "520f1027-4d26-4746-8b2b-efe6a84ff958" - }, - "@timestamp": "2021-10-07T11:54:50.409Z", - "ecs": { - "version": "1.10.0" - }, - "action_id": "fd14a9bd-f885-4e85-98a4-59b5a25cf81c", - "host": { - "hostname": "kind-1w-1c-control-plane", - "os": { - "kernel": "5.10.25-linuxkit", - "codename": "Core", - "name": "CentOS Linux", - "family": "redhat", - "type": "linux", - "version": "7 (Core)", - "platform": "centos" - }, - "containerized": true, - "ip": ["172.20.0.3", "fc00:f853:ccd:e793::3", "fe80::42:acff:fe14:3"], - "id": "bb43eb848699cf59adb70cc299cb4597", - "mac": ["02:42:ac:14:00:03"], - "architecture": "x86_64" - }, - "event": { - "agent_id_status": "verified", - "ingested": "2021-10-07T11:54:52.832230793Z" + "gid": "root" } } diff --git a/main.rego b/main.rego index 0e349905..9176ec5b 100644 --- a/main.rego +++ b/main.rego @@ -3,7 +3,7 @@ package main import data.compliance.cis # input is a resource -# data is configuration +# data is policy/configuration # output is findings resource = input From fed35dab914e0781b0151542cc6d7316194f05a9 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Thu, 4 Nov 2021 14:58:07 +0200 Subject: [PATCH 02/13] CIS 1.1.2 --- .gitignore | 2 -- compliance/lib/osquery.rego | 21 +++++++++++++-------- compliance/rules/cis_1_1_2/cis_1_1_2.rego | 22 ++++++++++++++++++++++ data.yaml | 2 +- 4 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 compliance/rules/cis_1_1_2/cis_1_1_2.rego diff --git a/.gitignore b/.gitignore index f5553c9d..325a5644 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -data.yaml -input.json output.json \ No newline at end of file diff --git a/compliance/lib/osquery.rego b/compliance/lib/osquery.rego index c69a8f55..c93a35b1 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/osquery.rego @@ -9,22 +9,27 @@ is_file { input.osquery.filename } -filename = x { +filename = name { is_file - x = input.osquery.filename + name = input.osquery.filename } -filemode = x { +filemode = mode { is_file - x = input.osquery.mode + mode = input.osquery.mode } -owner_user_id = x { +owner_user_id = uid { is_file - x = input.osquery.uid + uid = input.osquery.uid } -owner_group_id = x { +owner_group_id = gid { is_file - x = input.osquery.gid + gid = input.osquery.gid +} + +file_ownership_match(requierd_uid, requierd_gid) { + owner_user_id == requierd_uid + owner_group_id == requierd_gid } \ No newline at end of file diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2.rego b/compliance/rules/cis_1_1_2/cis_1_1_2.rego new file mode 100644 index 00000000..e494fad5 --- /dev/null +++ b/compliance/rules/cis_1_1_2/cis_1_1_2.rego @@ -0,0 +1,22 @@ +package compliance.cis.rules.cis_1_1_2 + +import data.compliance.lib.osquery +import data.compliance.lib.common + +# Ensure that the API server pod specification file ownership is set to root:root + + + +finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { + osquery.filename == "kube-apiserver.yaml" + rule_evaluation := osquery.file_ownership_match("root", "root") + + # set result + evaluation := common.calculate_result(rule_evaluation) + fields := [ + {"key": "uid", "value": osquery.owner_user_id}, + {"key": "gid", "value": osquery.owner_group_id} + ] + rule_name := "Ensure that the API server pod specification file ownership is set to root:root" + tags := ["cis", "cis 1.1.2", "kubernetes"] +} \ No newline at end of file diff --git a/data.yaml b/data.yaml index c0bca9f3..5e350240 100644 --- a/data.yaml +++ b/data.yaml @@ -1,3 +1,3 @@ activated_rules: - cis_1_1_1: true +# cis_1_1_1: true cis_1_1_2: true \ No newline at end of file From a89b9263506964f445a4196692c999c51cf04fa1 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Thu, 4 Nov 2021 15:22:25 +0200 Subject: [PATCH 03/13] file_ownership_match fail case --- compliance/lib/osquery.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compliance/lib/osquery.rego b/compliance/lib/osquery.rego index c93a35b1..37a73851 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/osquery.rego @@ -32,4 +32,4 @@ owner_group_id = gid { file_ownership_match(requierd_uid, requierd_gid) { owner_user_id == requierd_uid owner_group_id == requierd_gid -} \ No newline at end of file +} else = false \ No newline at end of file From 52a3dda1e16af4f4381da581bb390e449178bd4a Mon Sep 17 00:00:00 2001 From: orenzohar Date: Thu, 4 Nov 2021 15:31:09 +0200 Subject: [PATCH 04/13] edit .gitignore --- .gitignore | 4 +++- data.yaml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 325a5644..c4228841 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -output.json \ No newline at end of file +output.json +data.yaml +input.json \ No newline at end of file diff --git a/data.yaml b/data.yaml index 5e350240..c0bca9f3 100644 --- a/data.yaml +++ b/data.yaml @@ -1,3 +1,3 @@ activated_rules: -# cis_1_1_1: true + cis_1_1_1: true cis_1_1_2: true \ No newline at end of file From 3079f612bf2ed65519c1cd1aea96225c508d65fc Mon Sep 17 00:00:00 2001 From: orenzohar Date: Mon, 8 Nov 2021 11:16:55 +0200 Subject: [PATCH 05/13] add general tags to cis.rego --- compliance/cis.rego | 2 ++ compliance/lib/osquery.rego | 8 ++++---- compliance/rules/cis_1_1_1/cis_1_1_1.rego | 4 ++-- compliance/rules/cis_1_1_2/cis_1_1_2.rego | 7 +++---- data.yaml | 3 --- input.json | 9 --------- 6 files changed, 11 insertions(+), 22 deletions(-) delete mode 100644 data.yaml delete mode 100644 input.json diff --git a/compliance/cis.rego b/compliance/cis.rego index c99adb8b..00ec368f 100644 --- a/compliance/cis.rego +++ b/compliance/cis.rego @@ -2,6 +2,8 @@ package compliance.cis import data.compliance.cis.rules +tags := ["CIS", "CIS v1.6.0", "Kubernetes"] + # CIS 1.1.1 findings[finding] { data.activated_rules.cis_1_1_1 diff --git a/compliance/lib/osquery.rego b/compliance/lib/osquery.rego index 37a73851..dc0038f7 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/osquery.rego @@ -9,14 +9,14 @@ is_file { input.osquery.filename } -filename = name { +filename = file_name { is_file - name = input.osquery.filename + file_name = input.osquery.filename } -filemode = mode { +filemode = file_mode { is_file - mode = input.osquery.mode + file_mode = input.osquery.mode } owner_user_id = uid { diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1.rego b/compliance/rules/cis_1_1_1/cis_1_1_1.rego index 31421edd..f73aa781 100644 --- a/compliance/rules/cis_1_1_1/cis_1_1_1.rego +++ b/compliance/rules/cis_1_1_1/cis_1_1_1.rego @@ -2,9 +2,9 @@ package compliance.cis.rules.cis_1_1_1 import data.compliance.lib.osquery import data.compliance.lib.common +import data.compliance.cis # Ensure that the API server pod specification file permissions are set to 644 or more restrictive - finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { osquery.filename == "kube-apiserver.yaml" filemode := osquery.filemode @@ -15,5 +15,5 @@ finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, " evaluation := common.calculate_result(rule_evaluation) fields := [{ "key": "filemode", "value": filemode }] rule_name := "Ensure that the API server pod specification file permissions are set to 644 or more restrictive" - tags := ["cis", "cis 1.1.1", "kubernetes"] + tags := array.concat(cis.tags, ["CIS 1.1.1"]) } \ No newline at end of file diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2.rego b/compliance/rules/cis_1_1_2/cis_1_1_2.rego index e494fad5..8bc60418 100644 --- a/compliance/rules/cis_1_1_2/cis_1_1_2.rego +++ b/compliance/rules/cis_1_1_2/cis_1_1_2.rego @@ -2,11 +2,10 @@ package compliance.cis.rules.cis_1_1_2 import data.compliance.lib.osquery import data.compliance.lib.common - -# Ensure that the API server pod specification file ownership is set to root:root - +import data.compliance.cis +# Ensure that the API server pod specification file ownership is set to root:root finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { osquery.filename == "kube-apiserver.yaml" rule_evaluation := osquery.file_ownership_match("root", "root") @@ -18,5 +17,5 @@ finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, " {"key": "gid", "value": osquery.owner_group_id} ] rule_name := "Ensure that the API server pod specification file ownership is set to root:root" - tags := ["cis", "cis 1.1.2", "kubernetes"] + tags := array.concat(cis.tags, ["CIS 1.1.2"]) } \ No newline at end of file diff --git a/data.yaml b/data.yaml deleted file mode 100644 index c0bca9f3..00000000 --- a/data.yaml +++ /dev/null @@ -1,3 +0,0 @@ -activated_rules: - cis_1_1_1: true - cis_1_1_2: true \ No newline at end of file diff --git a/input.json b/input.json deleted file mode 100644 index 5744ef8a..00000000 --- a/input.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "osquery": { - "mode": "0700", - "path": "/hostfs/etc/kubernetes/manifests/kube-apiserver.yaml", - "uid": "etc", - "filename": "kube-apiserver.yaml", - "gid": "root" - } -} From 5a0aa58101d353d675be870282911ee84f859875 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 14:02:40 +0200 Subject: [PATCH 06/13] move common functions to common.rego fields -> evidence --- compliance/lib/common.rego | 12 +++++++++++- compliance/lib/osquery.rego | 5 ----- compliance/rules/cis_1_1_1/cis_1_1_1.rego | 7 +++---- compliance/rules/cis_1_1_2/cis_1_1_2.rego | 12 +++++++----- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/compliance/lib/common.rego b/compliance/lib/common.rego index b855cc2d..5e7a6a33 100644 --- a/compliance/lib/common.rego +++ b/compliance/lib/common.rego @@ -3,4 +3,14 @@ package compliance.lib.common # set the rule result calculate_result(evaluation) = "passed" { evaluation -} else = "violation" \ No newline at end of file +} else = "violation" + +file_ownership_match(uid, gid, requierd_uid, requierd_gid) { + uid == requierd_uid + gid == requierd_gid +} else = false + +file_permission_match(filemode, user, group, other) { + pattern = sprintf("0?[0-%d][0-%d][0-%d]", [user, group, other]) + regex.match(pattern, filemode) +} else = false \ No newline at end of file diff --git a/compliance/lib/osquery.rego b/compliance/lib/osquery.rego index dc0038f7..a17a3bef 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/osquery.rego @@ -28,8 +28,3 @@ owner_group_id = gid { is_file gid = input.osquery.gid } - -file_ownership_match(requierd_uid, requierd_gid) { - owner_user_id == requierd_uid - owner_group_id == requierd_gid -} else = false \ No newline at end of file diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1.rego b/compliance/rules/cis_1_1_1/cis_1_1_1.rego index f73aa781..b8b1d947 100644 --- a/compliance/rules/cis_1_1_1/cis_1_1_1.rego +++ b/compliance/rules/cis_1_1_1/cis_1_1_1.rego @@ -5,15 +5,14 @@ import data.compliance.lib.common import data.compliance.cis # Ensure that the API server pod specification file permissions are set to 644 or more restrictive -finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { +finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { osquery.filename == "kube-apiserver.yaml" filemode := osquery.filemode - pattern := "0?(0|1|2|3|4|5|6)(0|1|2|3|4)(0|1|2|3|4)" - rule_evaluation := regex.match(pattern, filemode) + rule_evaluation := common.file_permission_match(filemode, 6, 4, 4) # set result evaluation := common.calculate_result(rule_evaluation) - fields := [{ "key": "filemode", "value": filemode }] + evidence := [{ "key": "filemode", "value": filemode }] rule_name := "Ensure that the API server pod specification file permissions are set to 644 or more restrictive" tags := array.concat(cis.tags, ["CIS 1.1.1"]) } \ No newline at end of file diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2.rego b/compliance/rules/cis_1_1_2/cis_1_1_2.rego index 8bc60418..46802102 100644 --- a/compliance/rules/cis_1_1_2/cis_1_1_2.rego +++ b/compliance/rules/cis_1_1_2/cis_1_1_2.rego @@ -6,15 +6,17 @@ import data.compliance.cis # Ensure that the API server pod specification file ownership is set to root:root -finding = {"evaluation": evaluation, "rule_name": rule_name, "fields": fields, "tags": tags} { +finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { osquery.filename == "kube-apiserver.yaml" - rule_evaluation := osquery.file_ownership_match("root", "root") + uid = osquery.owner_user_id + gid = osquery.owner_group_id + rule_evaluation := common.file_ownership_match(uid, gid, "root", "root") # set result evaluation := common.calculate_result(rule_evaluation) - fields := [ - {"key": "uid", "value": osquery.owner_user_id}, - {"key": "gid", "value": osquery.owner_group_id} + evidence := [ + {"key": "uid", "value": uid}, + {"key": "gid", "value": gid} ] rule_name := "Ensure that the API server pod specification file ownership is set to root:root" tags := array.concat(cis.tags, ["CIS 1.1.2"]) From c4fd8e03d7fa15db81c0c70f781cb1b53e0b1916 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 15:27:19 +0200 Subject: [PATCH 07/13] test infra --- compliance/lib/test.rego | 9 ++++++++ .../rules/cis_1_1_1/cis_1_1_1_test.rego | 21 +++++++++++++++++ compliance/rules/cis_1_1_11/cis_1_1_11.rego | 19 +++++++++++++++ .../rules/cis_1_1_2/cis_1_1_2_test.rego | 23 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 compliance/lib/test.rego create mode 100644 compliance/rules/cis_1_1_1/cis_1_1_1_test.rego create mode 100644 compliance/rules/cis_1_1_11/cis_1_1_11.rego create mode 100644 compliance/rules/cis_1_1_2/cis_1_1_2_test.rego diff --git a/compliance/lib/test.rego b/compliance/lib/test.rego new file mode 100644 index 00000000..5fb73d30 --- /dev/null +++ b/compliance/lib/test.rego @@ -0,0 +1,9 @@ +package lib.test + +rule_pass(finding) { + finding.evaluation == "passed" +} + +rule_violation(finding) { + finding.evaluation == "violation" +} diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1_test.rego b/compliance/rules/cis_1_1_1/cis_1_1_1_test.rego new file mode 100644 index 00000000..54511b18 --- /dev/null +++ b/compliance/rules/cis_1_1_1/cis_1_1_1_test.rego @@ -0,0 +1,21 @@ +package compliance.cis.rules.cis_1_1_1 + +import data.lib.test + +test_violation { + test.rule_violation(finding) with input as rule_input("0700") +} + +test_pass { + test.rule_pass(finding) with input as rule_input("0644") +} + +rule_input(filemode) = { + "osquery": { + "mode": filemode, + "path": "/hostfs/etc/kubernetes/manifests/kube-apiserver.yaml", + "uid": "root", + "filename": "kube-apiserver.yaml", + "gid": "root" + } +} \ No newline at end of file diff --git a/compliance/rules/cis_1_1_11/cis_1_1_11.rego b/compliance/rules/cis_1_1_11/cis_1_1_11.rego new file mode 100644 index 00000000..74c4d2ef --- /dev/null +++ b/compliance/rules/cis_1_1_11/cis_1_1_11.rego @@ -0,0 +1,19 @@ +package compliance.cis.rules.cis_1_1_11 + +import data.compliance.lib.osquery +import data.compliance.lib.common +import data.compliance.cis + +# Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated) +finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { + osquery.filename == "etcd" + filemode := osquery.filemode + pattern := "0?(0|1|2|3|4|5|6|7)00" + rule_evaluation := regex.match(pattern, filemode) + + # set result + evaluation := common.calculate_result(rule_evaluation) + evidence := [{ "key": "filemode", "value": filemode }] + rule_name := "Ensure that the etcd data directory permissions are set to 700 or more restrictive" + tags := array.concat(cis.tags, ["CIS 1.1.11"]) +} \ No newline at end of file diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2_test.rego b/compliance/rules/cis_1_1_2/cis_1_1_2_test.rego new file mode 100644 index 00000000..dbd0d32b --- /dev/null +++ b/compliance/rules/cis_1_1_2/cis_1_1_2_test.rego @@ -0,0 +1,23 @@ +package compliance.cis.rules.cis_1_1_2 + +import data.lib.test + +test_violation { + test.rule_violation(finding) with input as rule_input("root", "etc") + test.rule_violation(finding) with input as rule_input("etc", "root") + test.rule_violation(finding) with input as rule_input("etc", "etc") +} + +test_pass { + test.rule_pass(finding) with input as rule_input("root", "root") +} + +rule_input(uid, gid) = { + "osquery": { + "mode": "0644", + "path": "/hostfs/etc/kubernetes/manifests/kube-apiserver.yaml", + "uid": uid, + "filename": "kube-apiserver.yaml", + "gid": gid + } +} \ No newline at end of file From 8e152eee39d27e4357acf92cc7cb7624603e84d2 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 15:27:57 +0200 Subject: [PATCH 08/13] remove 1.1.11 --- compliance/rules/cis_1_1_11/cis_1_1_11.rego | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 compliance/rules/cis_1_1_11/cis_1_1_11.rego diff --git a/compliance/rules/cis_1_1_11/cis_1_1_11.rego b/compliance/rules/cis_1_1_11/cis_1_1_11.rego deleted file mode 100644 index 74c4d2ef..00000000 --- a/compliance/rules/cis_1_1_11/cis_1_1_11.rego +++ /dev/null @@ -1,19 +0,0 @@ -package compliance.cis.rules.cis_1_1_11 - -import data.compliance.lib.osquery -import data.compliance.lib.common -import data.compliance.cis - -# Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated) -finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { - osquery.filename == "etcd" - filemode := osquery.filemode - pattern := "0?(0|1|2|3|4|5|6|7)00" - rule_evaluation := regex.match(pattern, filemode) - - # set result - evaluation := common.calculate_result(rule_evaluation) - evidence := [{ "key": "filemode", "value": filemode }] - rule_name := "Ensure that the etcd data directory permissions are set to 700 or more restrictive" - tags := array.concat(cis.tags, ["CIS 1.1.11"]) -} \ No newline at end of file From 49e001337c5263b1cc0e7c0125387fc146d24081 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 18:02:39 +0200 Subject: [PATCH 09/13] naming conventions --- compliance/cis.rego | 12 +++-------- compliance/lib/common.rego | 1 + .../lib/{osquery.rego => data_adapter.rego} | 2 +- compliance/rules/cis_1_1_1/cis_1_1_1.rego | 18 ----------------- compliance/rules/cis_1_1_1/rule.rego | 20 +++++++++++++++++++ .../{cis_1_1_1_test.rego => test.rego} | 0 .../cis_1_1_2/{cis_1_1_2.rego => rule.rego} | 8 ++++---- .../{cis_1_1_2_test.rego => test.rego} | 6 +++--- 8 files changed, 32 insertions(+), 35 deletions(-) rename compliance/lib/{osquery.rego => data_adapter.rego} (91%) delete mode 100644 compliance/rules/cis_1_1_1/cis_1_1_1.rego create mode 100644 compliance/rules/cis_1_1_1/rule.rego rename compliance/rules/cis_1_1_1/{cis_1_1_1_test.rego => test.rego} (100%) rename compliance/rules/cis_1_1_2/{cis_1_1_2.rego => rule.rego} (80%) rename compliance/rules/cis_1_1_2/{cis_1_1_2_test.rego => test.rego} (73%) diff --git a/compliance/cis.rego b/compliance/cis.rego index 00ec368f..c9ce70ea 100644 --- a/compliance/cis.rego +++ b/compliance/cis.rego @@ -4,14 +4,8 @@ import data.compliance.cis.rules tags := ["CIS", "CIS v1.6.0", "Kubernetes"] -# CIS 1.1.1 findings[finding] { - data.activated_rules.cis_1_1_1 - finding = rules.cis_1_1_1.finding + some rule_id + data.activated_rules[rule_id] + finding = rules[rule_id].finding } - -# CIS 1.1.2 -findings[finding] { - data.activated_rules.cis_1_1_2 - finding = rules.cis_1_1_2.finding -} \ No newline at end of file diff --git a/compliance/lib/common.rego b/compliance/lib/common.rego index 5e7a6a33..2a23408d 100644 --- a/compliance/lib/common.rego +++ b/compliance/lib/common.rego @@ -10,6 +10,7 @@ file_ownership_match(uid, gid, requierd_uid, requierd_gid) { gid == requierd_gid } else = false +# todo: check preformence of regex alternatives file_permission_match(filemode, user, group, other) { pattern = sprintf("0?[0-%d][0-%d][0-%d]", [user, group, other]) regex.match(pattern, filemode) diff --git a/compliance/lib/osquery.rego b/compliance/lib/data_adapter.rego similarity index 91% rename from compliance/lib/osquery.rego rename to compliance/lib/data_adapter.rego index a17a3bef..90c722d2 100644 --- a/compliance/lib/osquery.rego +++ b/compliance/lib/data_adapter.rego @@ -1,4 +1,4 @@ -package compliance.lib.osquery +package compliance.lib.data_adapter is_osquery { input.osquery diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1.rego b/compliance/rules/cis_1_1_1/cis_1_1_1.rego deleted file mode 100644 index b8b1d947..00000000 --- a/compliance/rules/cis_1_1_1/cis_1_1_1.rego +++ /dev/null @@ -1,18 +0,0 @@ -package compliance.cis.rules.cis_1_1_1 - -import data.compliance.lib.osquery -import data.compliance.lib.common -import data.compliance.cis - -# Ensure that the API server pod specification file permissions are set to 644 or more restrictive -finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { - osquery.filename == "kube-apiserver.yaml" - filemode := osquery.filemode - rule_evaluation := common.file_permission_match(filemode, 6, 4, 4) - - # set result - evaluation := common.calculate_result(rule_evaluation) - evidence := [{ "key": "filemode", "value": filemode }] - rule_name := "Ensure that the API server pod specification file permissions are set to 644 or more restrictive" - tags := array.concat(cis.tags, ["CIS 1.1.1"]) -} \ No newline at end of file diff --git a/compliance/rules/cis_1_1_1/rule.rego b/compliance/rules/cis_1_1_1/rule.rego new file mode 100644 index 00000000..1ae405fe --- /dev/null +++ b/compliance/rules/cis_1_1_1/rule.rego @@ -0,0 +1,20 @@ +package compliance.cis.rules.cis_1_1_1 + +import data.compliance.lib.data_adapter +import data.compliance.lib.common +import data.compliance.cis + +# Ensure that the API server pod specification file permissions are set to 644 or more restrictive +finding = result { + data_adapter.filename == "kube-apiserver.yaml" + filemode := data_adapter.filemode + rule_evaluation := common.file_permission_match(filemode, 6, 4, 4) + + # set result + result := { + "evaluation" : common.calculate_result(rule_evaluation), + "evidence" : [{ "key": "filemode", "value": filemode }], + "rule_name" : "Ensure that the API server pod specification file permissions are set to 644 or more restrictive", + "tags" : array.concat(cis.tags, ["CIS 1.1.1"]) + } +} \ No newline at end of file diff --git a/compliance/rules/cis_1_1_1/cis_1_1_1_test.rego b/compliance/rules/cis_1_1_1/test.rego similarity index 100% rename from compliance/rules/cis_1_1_1/cis_1_1_1_test.rego rename to compliance/rules/cis_1_1_1/test.rego diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2.rego b/compliance/rules/cis_1_1_2/rule.rego similarity index 80% rename from compliance/rules/cis_1_1_2/cis_1_1_2.rego rename to compliance/rules/cis_1_1_2/rule.rego index 46802102..23568a5e 100644 --- a/compliance/rules/cis_1_1_2/cis_1_1_2.rego +++ b/compliance/rules/cis_1_1_2/rule.rego @@ -1,15 +1,15 @@ package compliance.cis.rules.cis_1_1_2 -import data.compliance.lib.osquery +import data.compliance.lib.data_adapter import data.compliance.lib.common import data.compliance.cis # Ensure that the API server pod specification file ownership is set to root:root finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { - osquery.filename == "kube-apiserver.yaml" - uid = osquery.owner_user_id - gid = osquery.owner_group_id + data_adapter.filename == "kube-apiserver.yaml" + uid = data_adapter.owner_user_id + gid = data_adapter.owner_group_id rule_evaluation := common.file_ownership_match(uid, gid, "root", "root") # set result diff --git a/compliance/rules/cis_1_1_2/cis_1_1_2_test.rego b/compliance/rules/cis_1_1_2/test.rego similarity index 73% rename from compliance/rules/cis_1_1_2/cis_1_1_2_test.rego rename to compliance/rules/cis_1_1_2/test.rego index dbd0d32b..08cc835a 100644 --- a/compliance/rules/cis_1_1_2/cis_1_1_2_test.rego +++ b/compliance/rules/cis_1_1_2/test.rego @@ -3,9 +3,9 @@ package compliance.cis.rules.cis_1_1_2 import data.lib.test test_violation { - test.rule_violation(finding) with input as rule_input("root", "etc") - test.rule_violation(finding) with input as rule_input("etc", "root") - test.rule_violation(finding) with input as rule_input("etc", "etc") + test.rule_violation(finding) with input as rule_input("root", "user") + test.rule_violation(finding) with input as rule_input("user", "root") + test.rule_violation(finding) with input as rule_input("user", "user") } test_pass { From 7aedae842f42ff5c028794e343e37c494a083b59 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 18:11:36 +0200 Subject: [PATCH 10/13] evidence convention --- compliance/rules/cis_1_1_1/rule.rego | 2 +- compliance/rules/cis_1_1_2/rule.rego | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/compliance/rules/cis_1_1_1/rule.rego b/compliance/rules/cis_1_1_1/rule.rego index 1ae405fe..851c9680 100644 --- a/compliance/rules/cis_1_1_1/rule.rego +++ b/compliance/rules/cis_1_1_1/rule.rego @@ -13,7 +13,7 @@ finding = result { # set result result := { "evaluation" : common.calculate_result(rule_evaluation), - "evidence" : [{ "key": "filemode", "value": filemode }], + "evidence" : [{ "filemode" : filemode }], "rule_name" : "Ensure that the API server pod specification file permissions are set to 644 or more restrictive", "tags" : array.concat(cis.tags, ["CIS 1.1.1"]) } diff --git a/compliance/rules/cis_1_1_2/rule.rego b/compliance/rules/cis_1_1_2/rule.rego index 23568a5e..971b5dfd 100644 --- a/compliance/rules/cis_1_1_2/rule.rego +++ b/compliance/rules/cis_1_1_2/rule.rego @@ -14,10 +14,7 @@ finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidenc # set result evaluation := common.calculate_result(rule_evaluation) - evidence := [ - {"key": "uid", "value": uid}, - {"key": "gid", "value": gid} - ] + evidence := [{"uid" : uid}, {"gid" : gid}] rule_name := "Ensure that the API server pod specification file ownership is set to root:root" tags := array.concat(cis.tags, ["CIS 1.1.2"]) } \ No newline at end of file From 94a888a102a7d9c924a52bb7b449538fcd23f276 Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 18:12:05 +0200 Subject: [PATCH 11/13] evidence convention --- compliance/rules/cis_1_1_2/rule.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compliance/rules/cis_1_1_2/rule.rego b/compliance/rules/cis_1_1_2/rule.rego index 971b5dfd..9cadd7ce 100644 --- a/compliance/rules/cis_1_1_2/rule.rego +++ b/compliance/rules/cis_1_1_2/rule.rego @@ -14,7 +14,7 @@ finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidenc # set result evaluation := common.calculate_result(rule_evaluation) - evidence := [{"uid" : uid}, {"gid" : gid}] + evidence := [{"uid" : uid, "gid" : gid}] rule_name := "Ensure that the API server pod specification file ownership is set to root:root" tags := array.concat(cis.tags, ["CIS 1.1.2"]) } \ No newline at end of file From 00f9f6958637761fe3af2b1b0a1ddf9b11b09afc Mon Sep 17 00:00:00 2001 From: orenzohar Date: Tue, 9 Nov 2021 18:12:25 +0200 Subject: [PATCH 12/13] evidence convention --- compliance/rules/cis_1_1_1/rule.rego | 2 +- compliance/rules/cis_1_1_2/rule.rego | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compliance/rules/cis_1_1_1/rule.rego b/compliance/rules/cis_1_1_1/rule.rego index 851c9680..14f820db 100644 --- a/compliance/rules/cis_1_1_1/rule.rego +++ b/compliance/rules/cis_1_1_1/rule.rego @@ -13,7 +13,7 @@ finding = result { # set result result := { "evaluation" : common.calculate_result(rule_evaluation), - "evidence" : [{ "filemode" : filemode }], + "evidence" : { "filemode" : filemode }, "rule_name" : "Ensure that the API server pod specification file permissions are set to 644 or more restrictive", "tags" : array.concat(cis.tags, ["CIS 1.1.1"]) } diff --git a/compliance/rules/cis_1_1_2/rule.rego b/compliance/rules/cis_1_1_2/rule.rego index 9cadd7ce..392f5234 100644 --- a/compliance/rules/cis_1_1_2/rule.rego +++ b/compliance/rules/cis_1_1_2/rule.rego @@ -14,7 +14,7 @@ finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidenc # set result evaluation := common.calculate_result(rule_evaluation) - evidence := [{"uid" : uid, "gid" : gid}] + evidence := {"uid" : uid, "gid" : gid} rule_name := "Ensure that the API server pod specification file ownership is set to root:root" tags := array.concat(cis.tags, ["CIS 1.1.2"]) } \ No newline at end of file From e1532a5b335422bd9f247bab471be76e8bf1b8ab Mon Sep 17 00:00:00 2001 From: orenzohar Date: Wed, 10 Nov 2021 13:03:57 +0200 Subject: [PATCH 13/13] CR changes --- compliance/cis.rego | 11 ----------- compliance/cis_k8s.rego | 11 +++++++++++ compliance/lib/common.rego | 2 +- compliance/rules/cis_1_1_1/rule.rego | 4 ++-- compliance/rules/cis_1_1_2/rule.rego | 14 ++++++++------ main.rego | 4 ++-- 6 files changed, 24 insertions(+), 22 deletions(-) delete mode 100644 compliance/cis.rego create mode 100644 compliance/cis_k8s.rego diff --git a/compliance/cis.rego b/compliance/cis.rego deleted file mode 100644 index c9ce70ea..00000000 --- a/compliance/cis.rego +++ /dev/null @@ -1,11 +0,0 @@ -package compliance.cis - -import data.compliance.cis.rules - -tags := ["CIS", "CIS v1.6.0", "Kubernetes"] - -findings[finding] { - some rule_id - data.activated_rules[rule_id] - finding = rules[rule_id].finding -} diff --git a/compliance/cis_k8s.rego b/compliance/cis_k8s.rego new file mode 100644 index 00000000..e054d10d --- /dev/null +++ b/compliance/cis_k8s.rego @@ -0,0 +1,11 @@ +package compliance.cis_k8s + +import data.compliance.cis.rules + +default_tags := ["CIS", "CIS v1.6.0", "Kubernetes"] + +findings[finding] { + some rule_id + data.activated_rules.cis_k8s[rule_id] + finding = rules[rule_id].finding +} diff --git a/compliance/lib/common.rego b/compliance/lib/common.rego index 2a23408d..bd6d9a17 100644 --- a/compliance/lib/common.rego +++ b/compliance/lib/common.rego @@ -10,7 +10,7 @@ file_ownership_match(uid, gid, requierd_uid, requierd_gid) { gid == requierd_gid } else = false -# todo: check preformence of regex alternatives +# todo: compare performance of regex alternatives file_permission_match(filemode, user, group, other) { pattern = sprintf("0?[0-%d][0-%d][0-%d]", [user, group, other]) regex.match(pattern, filemode) diff --git a/compliance/rules/cis_1_1_1/rule.rego b/compliance/rules/cis_1_1_1/rule.rego index 14f820db..d9f98ac4 100644 --- a/compliance/rules/cis_1_1_1/rule.rego +++ b/compliance/rules/cis_1_1_1/rule.rego @@ -2,7 +2,7 @@ package compliance.cis.rules.cis_1_1_1 import data.compliance.lib.data_adapter import data.compliance.lib.common -import data.compliance.cis +import data.compliance.cis_k8s # Ensure that the API server pod specification file permissions are set to 644 or more restrictive finding = result { @@ -15,6 +15,6 @@ finding = result { "evaluation" : common.calculate_result(rule_evaluation), "evidence" : { "filemode" : filemode }, "rule_name" : "Ensure that the API server pod specification file permissions are set to 644 or more restrictive", - "tags" : array.concat(cis.tags, ["CIS 1.1.1"]) + "tags" : array.concat(cis_k8s.default_tags, ["CIS 1.1.1"]) } } \ No newline at end of file diff --git a/compliance/rules/cis_1_1_2/rule.rego b/compliance/rules/cis_1_1_2/rule.rego index 392f5234..692fe1d0 100644 --- a/compliance/rules/cis_1_1_2/rule.rego +++ b/compliance/rules/cis_1_1_2/rule.rego @@ -2,19 +2,21 @@ package compliance.cis.rules.cis_1_1_2 import data.compliance.lib.data_adapter import data.compliance.lib.common -import data.compliance.cis +import data.compliance.cis_k8s # Ensure that the API server pod specification file ownership is set to root:root -finding = {"evaluation": evaluation, "rule_name": rule_name, "evidence": evidence, "tags": tags} { +finding = result { data_adapter.filename == "kube-apiserver.yaml" uid = data_adapter.owner_user_id gid = data_adapter.owner_group_id rule_evaluation := common.file_ownership_match(uid, gid, "root", "root") # set result - evaluation := common.calculate_result(rule_evaluation) - evidence := {"uid" : uid, "gid" : gid} - rule_name := "Ensure that the API server pod specification file ownership is set to root:root" - tags := array.concat(cis.tags, ["CIS 1.1.2"]) + result := { + "evaluation" : common.calculate_result(rule_evaluation), + "evidence" : {"uid" : uid, "gid" : gid}, + "rule_name" : "Ensure that the API server pod specification file ownership is set to root:root", + "tags" : array.concat(cis_k8s.default_tags, ["CIS 1.1.2"]) + } } \ No newline at end of file diff --git a/main.rego b/main.rego index 9176ec5b..f446add0 100644 --- a/main.rego +++ b/main.rego @@ -1,11 +1,11 @@ package main -import data.compliance.cis +import data.compliance.cis_k8s # input is a resource # data is policy/configuration # output is findings resource = input -findings = cis.findings +findings = cis_k8s.findings