feat(apiserver): new 10 Kubernetes ApiServer checks (#3290)

This commit is contained in:
Sergio Garcia
2024-02-22 09:50:12 +00:00
committed by GitHub
parent 636892bc9a
commit 6a20e850bc
30 changed files with 694 additions and 0 deletions
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_no_always_admit_plugin",
"CheckTitle": "Ensure that the admission control plugin AlwaysAdmit is not set",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Admission Control",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check verifies that the Kubernetes API server is not configured with the AlwaysAdmit admission control plugin. The AlwaysAdmit plugin allows all requests without any filtering, which is a security risk and is deprecated.",
"Risk": "Enabling AlwaysAdmit permits all requests by default, bypassing other admission control checks, which can lead to unauthorized access.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to ensure that AlwaysAdmit is not included in the --enable-admission-plugins argument. Remove the plugin if it exists.",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Ensure the API server does not use the AlwaysAdmit admission control plugin to maintain proper security checks for all requests.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwaysadmit"
}
},
"Categories": [
"Access Control",
"Deprecated Features"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "AlwaysAdmit is deprecated and should not be used. Ensure it is removed from the API server configuration."
}
@@ -0,0 +1,32 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_no_always_admit_plugin(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"AlwaysAdmit admission control plugin is not set in pod {pod.name}."
)
always_admit_plugin = True
for container in pod.containers.values():
always_admit_plugin = True
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "AlwaysAdmit" in (command.split("=")[1]):
report.status = "FAIL"
report.status_extended = f"AlwaysAdmit admission control plugin is set in pod {pod.name}."
always_admit_plugin = False
break
if not always_admit_plugin:
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_no_token_auth_file",
"CheckTitle": "Ensure that the --token-auth-file parameter is not set",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Authentication",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the Kubernetes API server is not using static token-based authentication, which is less secure. Static tokens are stored in clear-text and lack features like revocation or rotation without restarting the API server.",
"Risk": "Using static token-based authentication exposes the cluster to security risks due to the static nature of the tokens, their clear-text storage, and the inability to revoke or rotate them easily.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/authentication/",
"Remediation": {
"Code": {
"CLI": "Remove the --token-auth-file parameter from the kube-apiserver configuration. Edit /etc/kubernetes/manifests/kube-apiserver.yaml on the master node and remove the --token-auth-file=<filename> parameter.",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Replace token-based authentication with more secure mechanisms like client certificate authentication. Ensure the --token-auth-file argument is not used in the API server configuration.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/authentication/#static-token-file"
}
},
"Categories": [
"Access Control",
"Security Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "By default, the --token-auth-file argument is not set in the kube-apiserver. Ensure it remains unset or is removed if currently in use."
}
@@ -0,0 +1,27 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_no_token_auth_file(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"API Server does not have token-auth-file enabled in pod {pod.name}."
)
for container in pod.containers.values():
if "--token-auth-file" in str(container.command):
report.status = "FAIL"
report.status_extended = (
f"API Server has token-auth-file enabled in pod {pod.name}."
)
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_node_restriction_plugin",
"CheckTitle": "Ensure that the admission control plugin NodeRestriction is set",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Admission Control",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the NodeRestriction admission control plugin is enabled in the Kubernetes API server. NodeRestriction limits the Node and Pod objects that a kubelet can modify, enhancing security by ensuring kubelets are restricted to manage their own node and pods.",
"Risk": "Without NodeRestriction, kubelets may have broader access to Node and Pod objects, potentially leading to unauthorized modifications and security risks.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to include NodeRestriction in the --enable-admission-plugins argument. Example: --enable-admission-plugins=...,NodeRestriction,...",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Enable the NodeRestriction admission control plugin in the API server for enhanced node and pod security.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction"
}
},
"Categories": [
"Node Security",
"Admission Control"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "NodeRestriction is critical in clusters where kubelets need restricted access to Node and Pod objects they manage."
}
@@ -0,0 +1,35 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_node_restriction_plugin(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"NodeRestriction admission control plugin is set in pod {pod.name}."
)
node_restriction_plugin_set = False
for container in pod.containers.values():
node_restriction_plugin_set = False
# Check if "--enable-admission-plugins" includes "NodeRestriction"
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "NodeRestriction" in (command.split("=")[1]):
node_restriction_plugin_set = True
if not node_restriction_plugin_set:
break
if not node_restriction_plugin_set:
report.status = "FAIL"
report.status_extended = f"NodeRestriction admission control plugin is not set in pod {pod.name}."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_request_timeout_set",
"CheckTitle": "Ensure that the --request-timeout argument is set as appropriate",
"CheckType": [
"Performance",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Request Handling",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "KubernetesAPIServer",
"Description": "This check verifies that the Kubernetes API server is configured with an appropriate global request timeout. Setting a suitable --request-timeout value ensures the API server can handle requests efficiently without exhausting resources, especially in cases of slower connections or high-volume data requests.",
"Risk": "An inadequately set request timeout may lead to inefficient handling of API requests, either by timing out too quickly on slow connections or by allowing requests to consume excessive resources, leading to potential Denial-of-Service attacks.",
"RelatedUrl": "https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to set the --request-timeout argument to an appropriate value based on your environment. Example: --request-timeout=300s",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Set the API server request timeout to a value that balances resource usage efficiency and the needs of your environment, considering connection speeds and data volumes.",
"Url": "https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/#options"
}
},
"Categories": [
"Resource Management",
"Configuration Optimization"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "The default timeout is set to 60 seconds. Adjust according to the specific requirements and constraints of your Kubernetes environment."
}
@@ -0,0 +1,28 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_request_timeout_set(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Request timeout is set appropriately in pod {pod.name}."
)
for container in pod.containers.values():
# Check if "--request-timeout" is set to an appropriate value
if "--request-timeout" not in str(container.command):
# Assuming the value is valid, e.g., '300s' or '1m'
report.status = "FAIL"
report.status_extended = f"Request timeout is not set or not set appropriately in pod {pod.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_security_context_deny_plugin",
"CheckTitle": "Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Admission Control",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "KubernetesAPIServer",
"Description": "This check verifies that the SecurityContextDeny admission control plugin is enabled in the Kubernetes API server if PodSecurityPolicy is not used. The SecurityContextDeny plugin denies pods that make use of certain SecurityContext fields which could allow privilege escalation.",
"Risk": "Without SecurityContextDeny, pods may be able to escalate privileges if PodSecurityPolicy is not used, potentially leading to security vulnerabilities.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to include SecurityContextDeny in the --enable-admission-plugins argument, unless PodSecurityPolicy is already in use. Example: --enable-admission-plugins=...,SecurityContextDeny,...",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Use SecurityContextDeny as an admission control plugin in the API server to enhance security, especially in the absence of PodSecurityPolicy.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#securitycontextdeny"
}
},
"Categories": [
"Pod Security",
"Security Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "SecurityContextDeny is recommended in environments where PodSecurityPolicy is not implemented to prevent potential privilege escalations."
}
@@ -0,0 +1,42 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_security_context_deny_plugin(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
security_context_deny_set = False
pod_security_policy_set = False
for container in pod.containers.values():
pod_security_policy_set = False
security_context_deny_set = False
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "SecurityContextDeny" in (command.split("=")[1]):
security_context_deny_set = True
if "PodSecurityPolicy" in (command.split("=")[1]):
pod_security_policy_set = True
if not pod_security_policy_set or not security_context_deny_set:
break
if pod_security_policy_set:
report.status = "PASS"
report.status_extended = (
f"PodSecurityPolicy is in use in pod {pod.name}."
)
elif security_context_deny_set:
report.status = "PASS"
report.status_extended = f"SecurityContextDeny admission control plugin is set in pod {pod.name}."
else:
report.status = "FAIL"
report.status_extended = f"Neither SecurityContextDeny nor PodSecurityPolicy admission control plugins are set in pod {pod.name}."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_service_account_key_file_set",
"CheckTitle": "Ensure that the --service-account-key-file argument is set as appropriate",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Authentication",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the Kubernetes API server is configured with a --service-account-key-file argument, specifying the public key file for service account verification. A separate key pair for service accounts enhances security by enabling key rotation and ensuring service account tokens are verified with a specific public key.",
"Risk": "Without a specified service account public key file, the API server may use the private key from its TLS serving certificate, hindering the ability to rotate keys and increasing security risks.",
"RelatedUrl": "https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to set --service-account-key-file to a valid public key file. Example: --service-account-key-file=<path/to/key-file>",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Specify a separate public key file for verifying service account tokens in pod {pod.name}.",
"Url": "https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection"
}
},
"Categories": [
"Authentication",
"Key Management"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Ensure the public key used is securely managed and rotated in accordance with your organization's security policy."
}
@@ -0,0 +1,30 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_service_account_key_file_set(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Service account key file is set appropriately in pod {pod.name}."
)
for container in pod.containers.values():
# Check if "--service-account-key-file" is set
if "--service-account-key-file" not in str(container.command):
report.status = "FAIL"
report.status_extended = (
f"Service account key file is not set in pod {pod.name}."
)
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_service_account_lookup_true",
"CheckTitle": "Ensure that the --service-account-lookup argument is set to true",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Authentication",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the Kubernetes API server is configured with --service-account-lookup set to true. This setting validates the service account associated with each request, ensuring that the service account token is not only valid but also currently exists.",
"Risk": "If --service-account-lookup is disabled, deleted service accounts might still be used, posing a security risk.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/authentication/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to set --service-account-lookup to true. Example: --service-account-lookup=true",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Enable service account lookup in the API server to ensure that only existing service accounts are used for authentication.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens"
}
},
"Categories": [
"Access Control",
"Security Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "By default, this argument is set to true. It's critical to maintain this setting for security."
}
@@ -0,0 +1,30 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_service_account_lookup_true(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Service account lookup is set to true in pod {pod.name}."
)
for container in pod.containers.values():
# Check if "--service-account-lookup" is set to true
if "--service-account-lookup=true" not in str(container.command):
report.status = "FAIL"
report.status_extended = (
f"Service account lookup is not set to true in pod {pod.name}."
)
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_service_account_plugin",
"CheckTitle": "Ensure that the admission control plugin ServiceAccount is set",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "Admission Control",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "KubernetesAPIServer",
"Description": "This check verifies that the ServiceAccount admission control plugin is enabled in the Kubernetes API server. This plugin automates the creation and assignment of service accounts to pods, enhancing security by managing service account tokens.",
"Risk": "If the ServiceAccount admission plugin is disabled, pods might be assigned the default service account without proper token management, leading to potential security risks.",
"RelatedUrl": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to ensure that ServiceAccount is included in the --enable-admission-plugins argument. Remove the plugin from --disable-admission-plugins if present.",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Enable the ServiceAccount admission control plugin in the API server to manage service accounts and tokens securely.",
"Url": "https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#serviceaccount"
}
},
"Categories": [
"Access Control",
"Service Accounts"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "ServiceAccount plugin is usually enabled by default, ensuring automated management of service accounts and their associated tokens."
}
@@ -0,0 +1,40 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_service_account_plugin(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"ServiceAccount admission control plugin is set in pod {pod.name}."
)
service_account_plugin_set = False
for container in pod.containers.values():
service_account_plugin_set = False
# Check if "--enable-admission-plugins" includes "ServiceAccount"
# and "--disable-admission-plugins" does not include "ServiceAccount"
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "ServiceAccount" in (command.split("=")[1]):
service_account_plugin_set = True
elif command.startswith("--disable-admission-plugins"):
if "ServiceAccount" in (command.split("=")[1]):
service_account_plugin_set = False
if not service_account_plugin_set:
break
if not service_account_plugin_set:
report.status = "FAIL"
report.status_extended = f"ServiceAccount admission control plugin is not set in pod {pod.name}."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_strong_ciphers_only",
"CheckTitle": "Ensure that the API Server only makes use of Strong Cryptographic Ciphers",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "TLS Cipher Configuration",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the Kubernetes API server is configured to only use strong cryptographic ciphers, minimizing the risk of vulnerabilities associated with weaker ciphers. Strong ciphers enhance the security of TLS connections to the API server.",
"Risk": "Using weak ciphers can leave the API server vulnerable to cryptographic attacks, compromising the security of data in transit.",
"RelatedUrl": "https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to include only strong cryptographic ciphers in the --tls-cipher-suites parameter. Example: --tls-cipher-suites=TLS_AES_128_GCM_SHA256,...",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the API server to only use strong cryptographic ciphers for enhanced security.",
"Url": "https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/#options"
}
},
"Categories": [
"Data Security",
"Network Security"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "The choice of ciphers may need to be updated based on evolving security standards and client compatibility."
}
@@ -0,0 +1,39 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_strong_ciphers_only(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = f"API Server is configured with strong cryptographic ciphers in pod {pod.name}."
strong_ciphers_set = True
for container in pod.containers.values():
strong_ciphers_set = True
# Check if strong ciphers are set in "--tls-cipher-suites"
for command in container.command:
if command.startswith("--tls-cipher-suites"):
for cipher in command.split("=")[1].split(","):
if cipher not in [
"TLS_AES_128_GCM_SHA256",
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256",
]:
strong_ciphers_set = False
break
if not strong_ciphers_set:
break
if not strong_ciphers_set:
report.status = "FAIL"
report.status_extended = f"API Server is not using only strong cryptographic ciphers in pod {pod.name}."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "apiserver_tls_config",
"CheckTitle": "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "apiserver",
"SubServiceName": "TLS Configuration",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesAPIServer",
"Description": "This check ensures that the Kubernetes API server is configured with TLS for secure communication. The --tls-cert-file and --tls-private-key-file arguments should be set to enable TLS encryption, thereby securing sensitive data transmitted to and from the API server.",
"Risk": "If TLS is not properly configured, the API server communication could be unencrypted, leading to potential data breaches.",
"RelatedUrl": "https://kubernetes.io/docs/setup/best-practices/certificates/",
"Remediation": {
"Code": {
"CLI": "Edit the kube-apiserver configuration to include TLS parameters. Example: --tls-cert-file=<path/to/tls-certificate-file> --tls-private-key-file=<path/to/tls-key-file>",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Ensure TLS is enabled and properly configured for the API server to secure communications.",
"Url": "https://kubernetes.io/docs/setup/best-practices/certificates/#certificate-paths"
}
},
"Categories": [
"Data Security",
"Configuration Optimization"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "TLS should be a standard security measure for all Kubernetes deployments to protect sensitive data."
}
@@ -0,0 +1,31 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_tls_config(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"TLS certificate and key are set appropriately in pod {pod.name}."
)
for container in pod.containers.values():
# Check if both "--tls-cert-file" and "--tls-private-key-file" are set
if "--tls-cert-file" not in str(
container.command
) or "--tls-private-key-file" not in str(container.command):
report.status = "FAIL"
report.status_extended = (
f"TLS certificate and/or key are not set in pod {pod.name}."
)
break
findings.append(report)
return findings