From b0f2f34d3b7a464f851bbf520d49bfa6c985c0d1 Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Wed, 28 Feb 2024 19:33:29 +0100 Subject: [PATCH] feat(namespace): add `--namespaces` argument and solve bugs (#3431) --- prowler/providers/common/audit_info.py | 8 +- prowler/providers/common/outputs.py | 4 +- .../kubernetes/kubernetes_provider.py | 72 ++++++++++++-- .../kubernetes/kubernetes_provider_new.py | 89 ++++++++++++++--- .../kubernetes/lib/arguments/arguments.py | 6 ++ ...ermanager_garbage_collection.metadata.json | 2 +- ...dmission_hostport_containers.metadata.json | 2 +- ...ndows_hostprocess_containers.metadata.json | 2 +- ...ivilegeEscalation_containers.metadata.json | 2 +- ...ontainers_added_capabilities.metadata.json | 2 +- ...ainers_capabilities_assigned.metadata.json | 2 +- ..._minimize_hostIPC_containers.metadata.json | 2 +- ...imize_hostNetwork_containers.metadata.json | 2 +- ..._minimize_hostPID_containers.metadata.json | 2 +- ...net_raw_capability_admission.metadata.json | 2 +- ...nimize_privileged_containers.metadata.json | 2 +- ...ze_root_containers_admission.metadata.json | 2 +- .../core_no_secrets_envs.metadata.json | 2 +- ...ccomp_profile_docker_default.metadata.json | 2 +- .../kubernetes/services/core/core_service.py | 99 ++++++++++--------- .../rbac_minimize_secret_access.metadata.json | 2 +- .../scheduler_profiling.metadata.json | 2 +- tests/lib/cli/parser_test.py | 8 ++ 23 files changed, 227 insertions(+), 91 deletions(-) diff --git a/prowler/providers/common/audit_info.py b/prowler/providers/common/audit_info.py index 52c31f97c97..8a00b76695d 100644 --- a/prowler/providers/common/audit_info.py +++ b/prowler/providers/common/audit_info.py @@ -63,14 +63,13 @@ def print_kubernetes_credentials(self, audit_info: Kubernetes_Audit_Info): # Get the current context cluster_name = self.context.get("context").get("cluster") user_name = self.context.get("context").get("user") - namespace = self.context.get("namespace", "default") roles = self.get_context_user_roles() roles_str = ", ".join(roles) if roles else "No associated Roles" report = f""" This report is being generated using the Kubernetes configuration below: -Kubernetes Cluster: {Fore.YELLOW}[{cluster_name}]{Style.RESET_ALL} User: {Fore.YELLOW}[{user_name}]{Style.RESET_ALL} Namespace: {Fore.YELLOW}[{namespace}]{Style.RESET_ALL} Roles: {Fore.YELLOW}[{roles_str}]{Style.RESET_ALL} +Kubernetes Cluster: {Fore.YELLOW}[{cluster_name}]{Style.RESET_ALL} User: {Fore.YELLOW}[{user_name}]{Style.RESET_ALL} Namespaces: {Fore.YELLOW}[{', '.join(self.namespaces)}]{Style.RESET_ALL} Roles: {Fore.YELLOW}[{roles_str}]{Style.RESET_ALL} """ print(report) @@ -370,7 +369,10 @@ def set_kubernetes_audit_info(self, arguments) -> Kubernetes_Audit_Info: logger.info("Checking if any context is set ...") context = arguments.get("context") - kubernetes_provider = Kubernetes_Provider(kubeconfig_file, context) + logger.info("Checking if any namespace is set ...") + namespaces = arguments.get("namespaces") + + kubernetes_provider = Kubernetes_Provider(kubeconfig_file, context, namespaces) ( kubernetes_audit_info.api_client, diff --git a/prowler/providers/common/outputs.py b/prowler/providers/common/outputs.py index 0b1a4c6f8cc..49d9dba0552 100644 --- a/prowler/providers/common/outputs.py +++ b/prowler/providers/common/outputs.py @@ -121,9 +121,7 @@ def __init__(self, arguments, audit_info, mutelist_file, bulk_checks_metadata): not hasattr(arguments, "output_filename") or arguments.output_filename is None ): - self.output_filename = ( - f"prowler-output-{audit_info.context['name']}-{output_file_timestamp}" - ) + self.output_filename = f"prowler-output-{audit_info.context['name'].replace(':', '_').replace('/', '_')}-{output_file_timestamp}" else: self.output_filename = arguments.output_filename diff --git a/prowler/providers/kubernetes/kubernetes_provider.py b/prowler/providers/kubernetes/kubernetes_provider.py index 0624d1ce488..7dd7648711d 100644 --- a/prowler/providers/kubernetes/kubernetes_provider.py +++ b/prowler/providers/kubernetes/kubernetes_provider.py @@ -7,11 +7,7 @@ class Kubernetes_Provider: - def __init__( - self, - kubeconfig_file: str, - context: str, - ): + def __init__(self, kubeconfig_file: str, context: str, namespaces: str): logger.info("Instantiating Kubernetes Provider ...") self.api_client, self.context = self.__set_credentials__( kubeconfig_file, context @@ -19,17 +15,39 @@ def __init__( if not self.api_client: logger.critical("Failed to set up a Kubernetes session.") sys.exit(1) + if not namespaces: + logger.info("Retrieving all namespaces ...") + self.namespaces = self.get_all_namespaces() + else: + self.namespaces = namespaces + + def __set_credentials__(self, kubeconfig_file, input_context): + """ + Set up credentials for Kubernetes provider. - def __set_credentials__(self, kubeconfig_file, context): + :param kubeconfig_file: Path to kubeconfig file. + :param input_context: Context to be used for Kubernetes session. + :return: Tuple containing ApiClient and context information. + """ try: if kubeconfig_file: # Use kubeconfig file if provided + logger.info(f"Loading kubeconfig from file: {kubeconfig_file} ...") config.load_kube_config( - config_file=os.path.abspath(kubeconfig_file), context=context + config_file=os.path.abspath(kubeconfig_file), context=input_context ) - context = config.list_kube_config_contexts()[0][0] + # Set context if input in argument + if input_context: + contexts = config.list_kube_config_contexts()[0] + for context_item in contexts: + if context_item["name"] == input_context: + context = context_item + else: + # Get active context + context = config.list_kube_config_contexts()[1] else: # Otherwise try to load in-cluster config + logger.info("Loading in-cluster config ...") config.load_incluster_config() context = { "name": "In-Cluster", @@ -46,11 +64,43 @@ def __set_credentials__(self, kubeconfig_file, context): sys.exit(1) def get_credentials(self): + """ + Get Kubernetes API client and context. + + :return: Tuple containing ApiClient and context information. + """ return self.api_client, self.context + def get_all_namespaces(self): + """ + Retrieve a list of all namespaces from a Kubernetes cluster. + + :return: List of namespaces. + """ + try: + v1 = client.CoreV1Api() + namespace_list = v1.list_namespace(timeout_seconds=2, _request_timeout=2) + namespaces = [item.metadata.name for item in namespace_list.items] + logger.info("All namespaces retrieved successfully.") + return namespaces + except Exception as error: + logger.critical( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + sys.exit() + def search_and_save_roles( self, roles: list, role_bindings, context_user: str, role_binding_type: str ): + """ + Search and save roles based on role bindings and context user. + + :param roles: List of roles to save. + :param role_bindings: List of role bindings to search. + :param context_user: Context user to match. + :param role_binding_type: Type of role binding. + :return: Updated list of roles. + """ try: for rb in role_bindings: if rb.subjects: @@ -70,6 +120,11 @@ def search_and_save_roles( sys.exit(1) def get_context_user_roles(self): + """ + Get roles assigned to the context user. + + :return: List of roles assigned to the context user. + """ try: rbac_api = client.RbacAuthorizationV1Api() context_user = self.context.get("context", {}).get("user", "") @@ -89,6 +144,7 @@ def get_context_user_roles(self): context_user, "Role", ) + logger.info("Context user roles retrieved successfully.") return roles except Exception as error: logger.critical( diff --git a/prowler/providers/kubernetes/kubernetes_provider_new.py b/prowler/providers/kubernetes/kubernetes_provider_new.py index 302a9e54b06..a2061a8d860 100644 --- a/prowler/providers/kubernetes/kubernetes_provider_new.py +++ b/prowler/providers/kubernetes/kubernetes_provider_new.py @@ -11,18 +11,28 @@ class KubernetesProvider(Provider): - # TODO change class name from Provider to Provider api_client: Any context: dict + namespaces: list audit_resources: Optional[Any] audit_metadata: Optional[Any] audit_config: Optional[dict] def __init__(self, arguments: Namespace): + """ + Initializes the KubernetesProvider instance. + Args: + arguments (dict): A dictionary containing configuration arguments. + """ logger.info("Instantiating Kubernetes Provider ...") self.api_client, self.context = self.setup_session( arguments.kubeconfig_file, arguments.context ) + if not arguments.namespaces: + logger.info("Retrieving all namespaces ...") + self.namespaces = self.get_all_namespaces() + else: + self.namespaces = arguments.namespaces if not self.api_client: logger.critical("Failed to set up a Kubernetes session.") @@ -30,16 +40,32 @@ def __init__(self, arguments: Namespace): if not arguments.only_logs: self.print_credentials() - def setup_session(self, kubeconfig_file, context): + def setup_session(self, kubeconfig_file, input_context): + """ + Sets up the Kubernetes session. + + Args: + kubeconfig_file (str): Path to the kubeconfig file. + input_context (str): Context name. + + Returns: + Tuple: A tuple containing the API client and the context. + """ try: if kubeconfig_file: - # Use kubeconfig file if provided + logger.info(f"Using kubeconfig file: {kubeconfig_file}") config.load_kube_config( - config_file=os.path.abspath(kubeconfig_file), context=context + config_file=os.path.abspath(kubeconfig_file), context=input_context ) - context = config.list_kube_config_contexts()[0][0] + if input_context: + contexts = config.list_kube_config_contexts()[0] + for context_item in contexts: + if context_item["name"] == input_context: + context = context_item + else: + context = config.list_kube_config_contexts()[1] else: - # Otherwise try to load in-cluster config + logger.info("Using in-cluster config") config.load_incluster_config() context = { "name": "In-Cluster", @@ -58,6 +84,18 @@ def setup_session(self, kubeconfig_file, context): def search_and_save_roles( self, roles: list, role_bindings, context_user: str, role_binding_type: str ): + """ + Searches for and saves roles. + + Args: + roles (list): A list to save the roles. + role_bindings: Role bindings. + context_user (str): Context user. + role_binding_type (str): Role binding type. + + Returns: + list: A list containing the roles. + """ try: for rb in role_bindings: if rb.subjects: @@ -77,11 +115,16 @@ def search_and_save_roles( sys.exit(1) def get_context_user_roles(self): + """ + Retrieves the context user roles. + + Returns: + list: A list containing the context user roles. + """ try: rbac_api = client.RbacAuthorizationV1Api() context_user = self.context.get("context", {}).get("user", "") roles = [] - # Search in ClusterRoleBindings roles = self.search_and_save_roles( roles, rbac_api.list_cluster_role_binding().items, @@ -89,7 +132,6 @@ def get_context_user_roles(self): "ClusterRole", ) - # Search in RoleBindings for all namespaces roles = self.search_and_save_roles( roles, rbac_api.list_role_binding_for_all_namespaces().items, @@ -103,8 +145,30 @@ def get_context_user_roles(self): ) sys.exit(1) + def get_all_namespaces(self): + """ + Retrieves all namespaces. + Returns: + list: A list containing all namespace names. + """ + try: + v1 = client.CoreV1Api() + namespace_list = v1.list_namespace(timeout_seconds=2, _request_timeout=2) + namespaces = [item.metadata.name for item in namespace_list.items] + logger.info("All namespaces retrieved successfully.") + return namespaces + except Exception as error: + logger.critical( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + sys.exit() + def get_pod_current_namespace(self): - """Retrieve the current namespace from the pod's mounted service account info.""" + """ + Retrieves the current namespace from the pod's mounted service account info. + Returns: + str: The current namespace. + """ try: with open( "/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r" @@ -117,7 +181,9 @@ def get_pod_current_namespace(self): return "default" def print_credentials(self): - # Get the current context + """ + Prints the Kubernetes credentials. + """ if self.context.get("name") == "In-Cluster": report = f""" This report is being generated using the Kubernetes configuration below: @@ -128,13 +194,12 @@ def print_credentials(self): else: cluster_name = self.context.get("context").get("cluster") user_name = self.context.get("context").get("user") - namespace = self.context.get("namespace", "default") roles = self.get_context_user_roles() roles_str = ", ".join(roles) if roles else "No associated Roles" report = f""" This report is being generated using the Kubernetes configuration below: -Kubernetes Cluster: {Fore.YELLOW}[{cluster_name}]{Style.RESET_ALL} User: {Fore.YELLOW}[{user_name}]{Style.RESET_ALL} Namespace: {Fore.YELLOW}[{namespace}]{Style.RESET_ALL} Roles: {Fore.YELLOW}[{roles_str}]{Style.RESET_ALL} +Kubernetes Cluster: {Fore.YELLOW}[{cluster_name}]{Style.RESET_ALL} User: {Fore.YELLOW}[{user_name}]{Style.RESET_ALL} Namespaces: {Fore.YELLOW}[{', '.join(self.namespaces)}]{Style.RESET_ALL} Roles: {Fore.YELLOW}[{roles_str}]{Style.RESET_ALL} """ print(report) diff --git a/prowler/providers/kubernetes/lib/arguments/arguments.py b/prowler/providers/kubernetes/lib/arguments/arguments.py index 6ad0b09e132..dad68041fb8 100644 --- a/prowler/providers/kubernetes/lib/arguments/arguments.py +++ b/prowler/providers/kubernetes/lib/arguments/arguments.py @@ -19,3 +19,9 @@ def init_parser(self): metavar="CONTEXT_NAME", help="The name of the kubeconfig context to use. By default, current_context from config file will be used.", ) + k8s_auth_subparser.add_argument( + "--namespaces", + nargs="+", + metavar="NAMESPACES", + help="The namespaces where to scan for the Kubernetes resources. By default, Prowler will scan all namespaces available.", + ) diff --git a/prowler/providers/kubernetes/services/controllermanager/controllermanager_garbage_collection/controllermanager_garbage_collection.metadata.json b/prowler/providers/kubernetes/services/controllermanager/controllermanager_garbage_collection/controllermanager_garbage_collection.metadata.json index 1d9a6d58e12..d10885cb2f2 100644 --- a/prowler/providers/kubernetes/services/controllermanager/controllermanager_garbage_collection/controllermanager_garbage_collection.metadata.json +++ b/prowler/providers/kubernetes/services/controllermanager/controllermanager_garbage_collection/controllermanager_garbage_collection.metadata.json @@ -6,7 +6,7 @@ "Resource Management", "Performance Optimization" ], - "ServiceName": "kube-controller-manager", + "ServiceName": "controller-manager", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "medium", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_admission_hostport_containers/core_minimize_admission_hostport_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_admission_hostport_containers/core_minimize_admission_hostport_containers.metadata.json index 0663f6b354d..ab58a25f1fc 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_admission_hostport_containers/core_minimize_admission_hostport_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_admission_hostport_containers/core_minimize_admission_hostport_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "HostPorts", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_admission_windows_hostprocess_containers/core_minimize_admission_windows_hostprocess_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_admission_windows_hostprocess_containers/core_minimize_admission_windows_hostprocess_containers.metadata.json index 14a632d543b..de2a47d0942 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_admission_windows_hostprocess_containers/core_minimize_admission_windows_hostprocess_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_admission_windows_hostprocess_containers/core_minimize_admission_windows_hostprocess_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Windows HostProcess Containers", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_allowPrivilegeEscalation_containers/core_minimize_allowPrivilegeEscalation_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_allowPrivilegeEscalation_containers/core_minimize_allowPrivilegeEscalation_containers.metadata.json index a898a7340f3..c7605797e3e 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_allowPrivilegeEscalation_containers/core_minimize_allowPrivilegeEscalation_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_allowPrivilegeEscalation_containers/core_minimize_allowPrivilegeEscalation_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Privilege Escalation Control", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_containers_added_capabilities/core_minimize_containers_added_capabilities.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_containers_added_capabilities/core_minimize_containers_added_capabilities.metadata.json index 63c7aed4da2..e772750ce06 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_containers_added_capabilities/core_minimize_containers_added_capabilities.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_containers_added_capabilities/core_minimize_containers_added_capabilities.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Capability Management", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_containers_capabilities_assigned/core_minimize_containers_capabilities_assigned.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_containers_capabilities_assigned/core_minimize_containers_capabilities_assigned.metadata.json index 106dc695f94..caed5424d03 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_containers_capabilities_assigned/core_minimize_containers_capabilities_assigned.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_containers_capabilities_assigned/core_minimize_containers_capabilities_assigned.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Capability Assignment", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_hostIPC_containers/core_minimize_hostIPC_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_hostIPC_containers/core_minimize_hostIPC_containers.metadata.json index a71c109e173..024dea46b94 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_hostIPC_containers/core_minimize_hostIPC_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_hostIPC_containers/core_minimize_hostIPC_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Host IPC Namespace", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_hostNetwork_containers/core_minimize_hostNetwork_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_hostNetwork_containers/core_minimize_hostNetwork_containers.metadata.json index f8125eac6f1..0d0a3dbc6c4 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_hostNetwork_containers/core_minimize_hostNetwork_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_hostNetwork_containers/core_minimize_hostNetwork_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Host Network Namespace", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_hostPID_containers/core_minimize_hostPID_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_hostPID_containers/core_minimize_hostPID_containers.metadata.json index e8da5c94c30..e0ef50bc3bf 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_hostPID_containers/core_minimize_hostPID_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_hostPID_containers/core_minimize_hostPID_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Host PID Namespace", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_net_raw_capability_admission/core_minimize_net_raw_capability_admission.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_net_raw_capability_admission/core_minimize_net_raw_capability_admission.metadata.json index aaab1007a4a..1bf45e3d2b1 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_net_raw_capability_admission/core_minimize_net_raw_capability_admission.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_net_raw_capability_admission/core_minimize_net_raw_capability_admission.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Capability Control", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_privileged_containers/core_minimize_privileged_containers.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_privileged_containers/core_minimize_privileged_containers.metadata.json index b7871df2c9a..26045f7fe47 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_privileged_containers/core_minimize_privileged_containers.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_privileged_containers/core_minimize_privileged_containers.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Privileged Containers", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_minimize_root_containers_admission/core_minimize_root_containers_admission.metadata.json b/prowler/providers/kubernetes/services/core/core_minimize_root_containers_admission/core_minimize_root_containers_admission.metadata.json index fd332f4bb41..4e55018ce0e 100644 --- a/prowler/providers/kubernetes/services/core/core_minimize_root_containers_admission/core_minimize_root_containers_admission.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_minimize_root_containers_admission/core_minimize_root_containers_admission.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Root User Control", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_no_secrets_envs/core_no_secrets_envs.metadata.json b/prowler/providers/kubernetes/services/core/core_no_secrets_envs/core_no_secrets_envs.metadata.json index d5c5ea8d902..22bb99c2da7 100644 --- a/prowler/providers/kubernetes/services/core/core_no_secrets_envs/core_no_secrets_envs.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_no_secrets_envs/core_no_secrets_envs.metadata.json @@ -6,7 +6,7 @@ "Best Practice", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Secrets Management", "ResourceIdTemplate": "", "Severity": "medium", diff --git a/prowler/providers/kubernetes/services/core/core_seccomp_profile_docker_default/core_seccomp_profile_docker_default.metadata.json b/prowler/providers/kubernetes/services/core/core_seccomp_profile_docker_default/core_seccomp_profile_docker_default.metadata.json index ad1b327bc3d..fb5e2a6196c 100644 --- a/prowler/providers/kubernetes/services/core/core_seccomp_profile_docker_default/core_seccomp_profile_docker_default.metadata.json +++ b/prowler/providers/kubernetes/services/core/core_seccomp_profile_docker_default/core_seccomp_profile_docker_default.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Core", + "ServiceName": "core", "SubServiceName": "Seccomp Profile", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/core/core_service.py b/prowler/providers/kubernetes/services/core/core_service.py index 78561163ce8..60a9a6f36de 100644 --- a/prowler/providers/kubernetes/services/core/core_service.py +++ b/prowler/providers/kubernetes/services/core/core_service.py @@ -15,7 +15,7 @@ class Core(KubernetesService): def __init__(self, audit_info): super().__init__(audit_info) self.client = client.CoreV1Api(self.api_client) - + self.namespaces = audit_info.namespaces self.pods = {} self.__get_pods__() self.config_maps = {} @@ -26,55 +26,56 @@ def __init__(self, audit_info): def __get_pods__(self): try: - pods = self.client.list_pod_for_all_namespaces() - for pod in pods.items: - pod_containers = {} - containers = pod.spec.containers if pod.spec.containers else [] - init_containers = ( - pod.spec.init_containers if pod.spec.init_containers else [] - ) - ephemeral_containers = ( - pod.spec.ephemeral_containers - if pod.spec.ephemeral_containers - else [] - ) - - for container in containers + init_containers + ephemeral_containers: - pod_containers[container.name] = Container( - name=container.name, - image=container.image, - command=container.command if container.command else None, - ports=[ - {"containerPort": port.container_port} - for port in container.ports - ] - if container.ports - else None, - env=[ - {"name": env.name, "value": env.value} - for env in container.env - ] - if container.env - else None, - security_context=container.security_context, + for namespace in self.namespaces: + pods = self.client.list_namespaced_pod(namespace) + for pod in pods.items: + pod_containers = {} + containers = pod.spec.containers if pod.spec.containers else [] + init_containers = ( + pod.spec.init_containers if pod.spec.init_containers else [] + ) + ephemeral_containers = ( + pod.spec.ephemeral_containers + if pod.spec.ephemeral_containers + else [] + ) + + for container in containers + init_containers + ephemeral_containers: + pod_containers[container.name] = Container( + name=container.name, + image=container.image, + command=container.command if container.command else None, + ports=[ + {"containerPort": port.container_port} + for port in container.ports + ] + if container.ports + else None, + env=[ + {"name": env.name, "value": env.value} + for env in container.env + ] + if container.env + else None, + security_context=container.security_context, + ) + self.pods[pod.metadata.uid] = Pod( + name=pod.metadata.name, + uid=pod.metadata.uid, + namespace=pod.metadata.namespace, + labels=pod.metadata.labels, + annotations=pod.metadata.annotations, + node_name=pod.spec.node_name, + service_account=pod.spec.service_account_name, + status_phase=pod.status.phase, + pod_ip=pod.status.pod_ip, + host_ip=pod.status.host_ip, + host_pid=pod.spec.host_pid, + host_ipc=pod.spec.host_ipc, + host_network=pod.spec.host_network, + security_context=pod.spec.security_context, + containers=pod_containers, ) - self.pods[pod.metadata.uid] = Pod( - name=pod.metadata.name, - uid=pod.metadata.uid, - namespace=pod.metadata.namespace, - labels=pod.metadata.labels, - annotations=pod.metadata.annotations, - node_name=pod.spec.node_name, - service_account=pod.spec.service_account_name, - status_phase=pod.status.phase, - pod_ip=pod.status.pod_ip, - host_ip=pod.status.host_ip, - host_pid=pod.spec.host_pid, - host_ipc=pod.spec.host_ipc, - host_network=pod.spec.host_network, - security_context=pod.spec.security_context, - containers=pod_containers, - ) except Exception as error: logger.error( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/kubernetes/services/rbac/rbac_minimize_secret_access/rbac_minimize_secret_access.metadata.json b/prowler/providers/kubernetes/services/rbac/rbac_minimize_secret_access/rbac_minimize_secret_access.metadata.json index cb92b124da3..dd8510fe2a7 100644 --- a/prowler/providers/kubernetes/services/rbac/rbac_minimize_secret_access/rbac_minimize_secret_access.metadata.json +++ b/prowler/providers/kubernetes/services/rbac/rbac_minimize_secret_access/rbac_minimize_secret_access.metadata.json @@ -6,7 +6,7 @@ "Security", "Configuration" ], - "ServiceName": "Kubernetes API", + "ServiceName": "RBAC", "SubServiceName": "Secrets Management", "ResourceIdTemplate": "", "Severity": "high", diff --git a/prowler/providers/kubernetes/services/scheduler/scheduler_profiling/scheduler_profiling.metadata.json b/prowler/providers/kubernetes/services/scheduler/scheduler_profiling/scheduler_profiling.metadata.json index a692c50e117..bf9943f24bd 100644 --- a/prowler/providers/kubernetes/services/scheduler/scheduler_profiling/scheduler_profiling.metadata.json +++ b/prowler/providers/kubernetes/services/scheduler/scheduler_profiling/scheduler_profiling.metadata.json @@ -6,7 +6,7 @@ "Cluster Performance", "Cluster Security" ], - "ServiceName": "kube-scheduler", + "ServiceName": "scheduler", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "medium", diff --git a/tests/lib/cli/parser_test.py b/tests/lib/cli/parser_test.py index 77364501fdc..27e77962d1c 100644 --- a/tests/lib/cli/parser_test.py +++ b/tests/lib/cli/parser_test.py @@ -1145,6 +1145,14 @@ def test_parser_kubernetes_auth_context(self): assert parsed.provider == "kubernetes" assert parsed.context == context + def test_parser_kubernetes_auth_namespace(self): + argument = "--namespaces" + namespaces = ["default", "kube-system"] + command = [prowler_command, "kubernetes", argument, namespaces] + parsed = self.parser.parse(command) + assert parsed.provider == "kubernetes" + assert parsed.namespaces == namespaces + def test_validate_azure_region_valid_regions(self): expected_regions = [ "AzureChinaCloud",