diff --git a/job.yaml b/job.yaml new file mode 100644 index 0000000000..528e299e6a --- /dev/null +++ b/job.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: prowler +spec: + containers: + - name: prowler + image: docker.io/prowler/kubernetes + command: ["prowler"] + args: ["kubernetes"] + imagePullPolicy: Never diff --git a/prowler-role.yaml b/prowler-role.yaml new file mode 100644 index 0000000000..7acb69e0b8 --- /dev/null +++ b/prowler-role.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: prowler-read-cluster +rules: +- apiGroups: [""] + resources: ["pods", "configmaps", "nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterrolebindings", "rolebindings", "clusterroles", "roles"] + verbs: ["get", "list", "watch"] diff --git a/prowler-rolebinding.yaml b/prowler-rolebinding.yaml new file mode 100644 index 0000000000..dde2837c11 --- /dev/null +++ b/prowler-rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: prowler-read-cluster-default-sa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prowler-read-cluster +subjects: +- kind: ServiceAccount + name: default + namespace: default diff --git a/prowler/providers/kubernetes/kubernetes_provider.py b/prowler/providers/kubernetes/kubernetes_provider.py index 10400b4585..0624d1ce48 100644 --- a/prowler/providers/kubernetes/kubernetes_provider.py +++ b/prowler/providers/kubernetes/kubernetes_provider.py @@ -27,10 +27,17 @@ class Kubernetes_Provider: config.load_kube_config( config_file=os.path.abspath(kubeconfig_file), context=context ) + context = config.list_kube_config_contexts()[0][0] else: # Otherwise try to load in-cluster config config.load_incluster_config() - context = config.list_kube_config_contexts()[0][0] + context = { + "name": "In-Cluster", + "context": { + "cluster": "in-cluster", # Placeholder, as the real cluster name is not available + "user": "service-account-name", # Also a placeholder + }, + } return client.ApiClient(), context 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 55f43645c7..302a9e54b0 100644 --- a/prowler/providers/kubernetes/kubernetes_provider_new.py +++ b/prowler/providers/kubernetes/kubernetes_provider_new.py @@ -37,10 +37,17 @@ class KubernetesProvider(Provider): config.load_kube_config( config_file=os.path.abspath(kubeconfig_file), context=context ) + context = config.list_kube_config_contexts()[0][0] else: # Otherwise try to load in-cluster config config.load_incluster_config() - context = config.list_kube_config_contexts()[0][0] + context = { + "name": "In-Cluster", + "context": { + "cluster": "in-cluster", # Placeholder, as the real cluster name is not available + "user": "service-account-name", # Also a placeholder + }, + } return client.ApiClient(), context except Exception as error: logger.critical( @@ -96,18 +103,38 @@ class KubernetesProvider(Provider): ) sys.exit(1) + def get_pod_current_namespace(self): + """Retrieve the current namespace from the pod's mounted service account info.""" + try: + with open( + "/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r" + ) as f: + return f.read().strip() + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return "default" + def print_credentials(self): - # 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" + if self.context.get("name") == "In-Cluster": + report = f""" +This report is being generated using the Kubernetes configuration below: - report = f""" +Kubernetes Pod: {Fore.YELLOW}[prowler]{Style.RESET_ALL} Namespace: {Fore.YELLOW}[{self.get_pod_current_namespace()}]{Style.RESET_ALL} +""" + print(report) + 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} """ - print(report) + print(report)