From c45404187ebc119d835a0d16cbd10b00f496053c Mon Sep 17 00:00:00 2001 From: chenk Date: Sun, 14 Apr 2024 16:16:05 +0300 Subject: [PATCH] fix: cis checks validate api-server args Signed-off-by: chenk --- .../apiserver/event_rate_limit_plugin.rego | 23 +++++++++++-------- .../event_rate_limit_plugin_test.rego | 22 ++++++++++++++++++ .../kubelet_certificate_authority.rego | 16 ++++++++----- .../kubelet_certificate_authority_test.rego | 22 ++++++++++++++++++ .../kubelet_client_certificate_and_key.rego | 20 ++++++++-------- ...belet_client_certificate_and_key_test.rego | 22 ++++++++++++++++++ .../apiserver/kubelet_https.rego | 14 +++++++---- .../apiserver/kubelet_https_test.rego | 22 ++++++++++++++++++ .../apiserver/namespace_lifecycle_plugin.rego | 16 +++++++++---- .../namespace_lifecycle_plugin_test.rego | 22 ++++++++++++++++++ .../apiserver/node_restriction_plugin.rego | 23 +++++++++++-------- .../node_restriction_plugin_test.rego | 22 ++++++++++++++++++ .../cisbenchmarks/apiserver/profiling.rego | 16 ++++++++----- .../apiserver/profiling_test.rego | 22 ++++++++++++++++++ .../cisbenchmarks/apiserver/secure_port.rego | 14 +++++++---- .../apiserver/secure_port_test.rego | 22 ++++++++++++++++++ .../security_context_deny_plugin.rego | 17 ++++++++++---- .../security_context_deny_plugin_test.rego | 22 ++++++++++++++++++ .../apiserver/service_account_key_file.rego | 16 ++++++++----- .../service_account_key_file_test.rego | 22 ++++++++++++++++++ .../apiserver/service_account_lookup.rego | 14 +++++++---- .../service_account_lookup_test.rego | 22 ++++++++++++++++++ .../apiserver/service_account_plugin.rego | 16 +++++++++---- .../service_account_plugin_test.rego | 22 ++++++++++++++++++ .../tls_cert_file_and_private_key_file.rego | 20 ++++++++-------- ...s_cert_file_and_private_key_file_test.rego | 22 ++++++++++++++++++ .../apiserver/token_auth_file.rego | 15 ++++++++---- .../apiserver/token_auth_file_test.rego | 22 ++++++++++++++++++ 28 files changed, 455 insertions(+), 93 deletions(-) diff --git a/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin.rego b/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin.rego index e24a07d9..84efe6bb 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin.rego @@ -19,21 +19,24 @@ package builtin.kubernetes.KCV0010 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--enable-admission-plugins") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--enable-admission-plugins") + some i + output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.command[i], -1) + regex.match("EventRateLimit", output[0][1]) } -check_flag[container] { - container := kubernetes.containers[_] +check_flag(container) { + kubernetes.command_has_flag(container.args, "--enable-admission-plugins") some i - output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.command[i], -1) - not regex.match("EventRateLimit", output[0][1]) + output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.args[i], -1) + regex.match("EventRateLimit", output[0][1]) } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the admission control plugin EventRateLimit is set" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin_test.rego index 34783ed8..2cba6f26 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/event_rate_limit_plugin_test.rego @@ -85,3 +85,25 @@ test_event_rate_limit_plugin_is_enabled_with_others { count(r) == 0 } + +test_event_rate_limit_plugin_is_enabled_with_others_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--enable-admission-plugins=NamespaceLifecycle,EventRateLimit,ServiceAccount"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority.rego index 09b65d3a..25eb3d14 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0006 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--kubelet-certificate-authority") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--kubelet-certificate-authority") +} + +check_flag(container) { + kubernetes.command_has_flag(container.args, "--kubelet-certificate-authority") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the --kubelet-certificate-authority argument is set as appropriate" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority_test.rego index e697d70d..71772d5f 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_certificate_authority_test.rego @@ -21,6 +21,28 @@ test_kubelet_certificate_authority_is_set { count(r) == 0 } +test_kubelet_certificate_authority_is_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--kubelet-certificate-authority="], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_kubelet_certificate_authority_is_not_set { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key.rego index c494c558..77edcf2f 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key.rego @@ -19,20 +19,20 @@ package builtin.kubernetes.KCV0005 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--kubelet-client-certificate") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--kubelet-client-certificate") + kubernetes.command_has_flag(container.command, "--kubelet-client-key") } -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--kubelet-client-key") +check_flag(container) { + kubernetes.command_has_flag(container.args, "--kubelet-client-certificate") + kubernetes.command_has_flag(container.args, "--kubelet-client-key") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key_test.rego index 89ba80c1..20b403b1 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_client_certificate_and_key_test.rego @@ -65,6 +65,28 @@ test_kubelet_client_key_and_certificate_are_set { count(r) == 0 } +test_kubelet_client_key_and_certificate_are_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--kubelet-client-certificate=", "--kubelet-client-key="], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_kubelet_client_key_and_certificate_are_not_set { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https.rego index 53a69f4b..8e307a44 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0004 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { + kubernetes.command_has_flag(container.command, "--kubelet-https=false") +} + +check_flag(container) { kubernetes.command_has_flag(container.command, "--kubelet-https=false") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the --kubelet-https argument is set to true" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https_test.rego index a747bf75..85a35942 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/kubelet_https_test.rego @@ -43,6 +43,28 @@ test_kubelet_https_is_true { count(r) == 0 } +test_kubelet_https_is_true_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--authorization-mode=AlwaysAllow", "--kubelet-https=true", "--anonymous-auth=false"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_kubelet_https_is_not_configured { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin.rego b/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin.rego index 10dd9c99..d9a78daa 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin.rego @@ -19,16 +19,22 @@ package builtin.kubernetes.KCV0015 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { some i output := regex.find_all_string_submatch_n(`--disable-admission-plugins=([^\s]+)`, container.command[i], -1) regex.match("NamespaceLifecycle", output[0][1]) } +check_flag(container) { + some i + output := regex.find_all_string_submatch_n(`--disable-admission-plugins=([^\s]+)`, container.args[i], -1) + regex.match("NamespaceLifecycle", output[0][1]) +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the admission control plugin NamespaceLifecycle is set" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin_test.rego index 28e81058..08228391 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/namespace_lifecycle_plugin_test.rego @@ -42,3 +42,25 @@ test_namespace_lifecycle_plugin_is_not_disabled { count(r) == 0 } + +test_namespace_lifecycle_plugin_is_not_disabled_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--disable-admission-plugins=AlwaysAdmit"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} diff --git a/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin.rego b/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin.rego index 5479d70f..28dba798 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin.rego @@ -19,21 +19,24 @@ package builtin.kubernetes.KCV0016 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--enable-admission-plugins") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--enable-admission-plugins") + some i + output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.command[i], -1) + regex.match("NodeRestriction", output[0][1]) } -check_flag[container] { - container := kubernetes.containers[_] +check_flag(container) { + kubernetes.command_has_flag(container.args, "--enable-admission-plugins") some i - output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.command[i], -1) - not regex.match("NodeRestriction", output[0][1]) + output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.args[i], -1) + regex.match("NodeRestriction", output[0][1]) } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the admission control plugin NodeRestriction is set" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin_test.rego index 2e3d570a..44534573 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/node_restriction_plugin_test.rego @@ -85,3 +85,25 @@ test_node_restriction_plugin_is_enabled_with_others { count(r) == 0 } + +test_node_restriction_plugin_is_enabled_with_others_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,ServiceAccount"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} diff --git a/checks/kubernetes/cisbenchmarks/apiserver/profiling.rego b/checks/kubernetes/cisbenchmarks/apiserver/profiling.rego index 87f8986d..02d52765 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/profiling.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/profiling.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0018 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--profiling=false") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--profiling=false") +} + +check_flag(container) { + kubernetes.command_has_flag(container.args, "--profiling=false") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the --profiling argument is set to false" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/profiling_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/profiling_test.rego index 0ff7e087..5aaf1502 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/profiling_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/profiling_test.rego @@ -21,6 +21,28 @@ test_profiling_is_set_to_false { count(r) == 0 } +test_profiling_is_set_to_false_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--profiling=false", "--secure-port=0"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_profiling_is_set_to_true { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/secure_port.rego b/checks/kubernetes/cisbenchmarks/apiserver/secure_port.rego index 3a93d2fb..2ae5db68 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/secure_port.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/secure_port.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0017 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { kubernetes.command_has_flag(container.command, "--secure-port=0") } +check_flag(container) { + kubernetes.command_has_flag(container.args, "--secure-port=0") +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the --secure-port argument is not set to 0" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/secure_port_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/secure_port_test.rego index c6d465c0..328242e2 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/secure_port_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/secure_port_test.rego @@ -43,6 +43,28 @@ test_secure_port_is_not_set_to_zero { count(r) == 0 } +test_secure_port_is_not_set_to_zero_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--secure-port=2", "--anonymous-auth=false"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_secure_port_is_not_configured { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin.rego b/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin.rego index 3dcb757e..3749090b 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin.rego @@ -19,17 +19,24 @@ package builtin.kubernetes.KCV0013 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { some i output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.command[i], -1) not regex.match("PodSecurityPolicy", output[0][1]) not regex.match("SecurityContextDeny", output[0][1]) } +check_flag(container) { + some i + output := regex.find_all_string_submatch_n(`--enable-admission-plugins=([^\s]+)`, container.args[i], -1) + not regex.match("PodSecurityPolicy", output[0][1]) + not regex.match("SecurityContextDeny", output[0][1]) +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin_test.rego index ef2be47e..3c0241c0 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/security_context_deny_plugin_test.rego @@ -21,6 +21,28 @@ test_pod_security_policy_is_set { count(r) == 0 } +test_pod_security_policy_is_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--enable-admission-plugins=AlwaysPullImages,PodSecurityPolicy"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_pod_security_policy_is_not_set { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file.rego index 32cf1e08..d69b33fe 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0025 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--service-account-key-file") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--service-account-key-file") +} + +check_flag(container) { + kubernetes.command_has_flag(container.args, "--service-account-key-file") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the --service-account-key-file argument is set as appropriate" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file_test.rego index 2c120e09..5145c3e0 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_key_file_test.rego @@ -21,6 +21,28 @@ test_service_account_key_file_is_set { count(r) == 0 } +test_service_account_key_file_is_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--authorization-mode=AlwaysAllow", "--service-account-key-file=", "--anonymous-auth=false"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_service_account_key_file_is_not_set { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup.rego index 4096c926..cb6dfb76 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup.rego @@ -19,14 +19,18 @@ package builtin.kubernetes.KCV0024 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { kubernetes.command_has_flag(container.command, "--service-account-lookup=false") } +check_flag(container) { + kubernetes.command_has_flag(container.args, "--service-account-lookup=false") +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the --service-account-lookup argument is set to true" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup_test.rego index e43c8fee..32a88494 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_lookup_test.rego @@ -43,6 +43,28 @@ test_service_account_lookup_is_true { count(r) == 0 } +test_service_account_lookup_is_true_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--authorization-mode=AlwaysAllow", "--service-account-lookup=true", "--anonymous-auth=false"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_service_account_lookup_is_not_configured { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin.rego index ba50d2e2..539138c2 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin.rego @@ -19,16 +19,22 @@ package builtin.kubernetes.KCV0014 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { some i output := regex.find_all_string_submatch_n(`--disable-admission-plugins=([^\s]+)`, container.command[i], -1) regex.match("ServiceAccount", output[0][1]) } +check_flag(container) { + some i + output := regex.find_all_string_submatch_n(`--disable-admission-plugins=([^\s]+)`, container.args[i], -1) + regex.match("ServiceAccount", output[0][1]) +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the admission control plugin ServiceAccount is set" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin_test.rego index e7c020ad..08266ebb 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/service_account_plugin_test.rego @@ -42,3 +42,25 @@ test_service_account_plugin_is_not_disabled { count(r) == 0 } + +test_service_account_plugin_is_not_disabled_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--disable-admission-plugins=AlwaysAdmit"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} diff --git a/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file.rego b/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file.rego index 164092d8..a79adfa3 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file.rego @@ -19,20 +19,20 @@ package builtin.kubernetes.KCV0027 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--tls-cert-file") +check_flag(container) { + kubernetes.command_has_flag(container.command, "--tls-cert-file") + kubernetes.command_has_flag(container.command, "--tls-private-key-file") } -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) - not kubernetes.command_has_flag(container.command, "--tls-private-key-file") +check_flag(container) { + kubernetes.command_has_flag(container.args, "--tls-cert-file") + kubernetes.command_has_flag(container.args, "--tls-private-key-file") } deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + not check_flag(container) msg := "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file_test.rego index 21560cb2..a245b176 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/tls_cert_file_and_private_key_file_test.rego @@ -65,6 +65,28 @@ test_tls_cert_file_and_private_key_file_are_set { count(r) == 0 } +test_tls_cert_file_and_private_key_file_are_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--tls-cert-file=", "--tls-private-key-file="], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +} + test_tls_cert_file_and_private_key_file_are_not_set { r := deny with input as { "apiVersion": "v1", diff --git a/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file.rego b/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file.rego index 56e4b7b3..ea8e551b 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file.rego @@ -19,15 +19,20 @@ package builtin.kubernetes.KCV0002 import data.lib.kubernetes -check_flag[container] { - container := kubernetes.containers[_] - kubernetes.is_apiserver(container) +check_flag(container) { some i regex.match("--token-auth-file", container.command[i]) } +check_flag(container) { + some i + regex.match("--token-auth-file", container.args[i]) +} + deny[res] { - output := check_flag[_] + container := kubernetes.containers[_] + kubernetes.is_apiserver(container) + check_flag(container) msg := "Ensure that the --token-auth-file parameter is not set" - res := result.new(msg, output) + res := result.new(msg, container) } diff --git a/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file_test.rego b/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file_test.rego index 57c2dd2e..c87d4b83 100644 --- a/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file_test.rego +++ b/checks/kubernetes/cisbenchmarks/apiserver/token_auth_file_test.rego @@ -42,3 +42,25 @@ test_token_auth_file_is_not_set { count(r) == 0 } + +test_token_auth_file_is_not_set_args { + r := deny with input as { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "apiserver", + "labels": { + "component": "kube-apiserver", + "tier": "control-plane", + }, + }, + "spec": {"containers": [{ + "command": ["kube-apiserver"], + "args": ["--advertise-address=192.168.49.2", "--anonymous-auth=false"], + "image": "busybox", + "name": "hello", + }]}, + } + + count(r) == 0 +}