diff --git a/.gitignore b/.gitignore index 50bc8919..d886a4db 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ coverage.txt *.swp /vendor /.vscode +.go-version diff --git a/README.md b/README.md index 274b89a2..6c0e2e6e 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Auditors can also be run individually. | `hostns` | Finds containers that have HostPID, HostIPC or HostNetwork enabled. | [docs](docs/auditors/hostns.md) | | `image` | Finds containers which do not use the desired version of an image (via the tag) or use an image without a tag. | [docs](docs/auditors/image.md) | | `limits` | Finds containers which exceed the specified CPU and memory limits or do not specify any. | [docs](docs/auditors/limits.md) | -| `mounts` | Finds containers that have sensitive host paths mounted. | [docs](docs/auditors/mounts.md) | +| `mounts` | Finds containers that have sensitive host paths mounted. | [docs](docs/auditors/mounts.md) | | `netpols` | Finds namespaces that do not have a default-deny network policy. | [docs](docs/auditors/netpols.md) | | `nonroot` | Finds containers running as root. | [docs](docs/auditors/nonroot.md) | | `privesc` | Finds containers that allow privilege escalation. | [docs](docs/auditors/privesc.md) | @@ -208,14 +208,15 @@ Auditors can also be run individually. ### Global Flags -| Short | Long | Description | -| :---- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------- | -| | --format | The output format to use (one of "pretty", "logrus", "json") (default is "pretty") | -| -c | --kubeconfig | Path to local Kubernetes config file. Only used in local mode (default is `$HOME/.kube/config`) | -| -f | --manifest | Path to the yaml configuration to audit. Only used in manifest mode. | -| -n | --namespace | Only audit resources in the specified namespace. Not currently supported in manifest mode. | -| -m | --minseverity | Set the lowest severity level to report (one of "error", "warning", "info") (default "info") | -| -e | --exitcode | Exit code to use if there are results with severity of "error". Conventionally, 0 is used for success and all non-zero codes for an error. (default 2) | +| Short | Long | Description | +| :---- | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | +| | --format | The output format to use (one of "pretty", "logrus", "json") (default is "pretty") | +| -c | --kubeconfig | Path to local Kubernetes config file. Only used in local mode (default is `$HOME/.kube/config`) | +| -f | --manifest | Path to the yaml configuration to audit. Only used in manifest mode. | +| -n | --namespace | Only audit resources in the specified namespace. Not currently supported in manifest mode. | +| -g | --includegenerated | Include generated resources in scan (such as Pods generated by deployments). If you would like kubeaudit to produce results for generated resources (for example if you have custom resources or want to catch orphaned resources where the owner resource no longer exists) you can use this flag. | +| -m | --minseverity | Set the lowest severity level to report (one of "error", "warning", "info") (default "info") | +| -e | --exitcode | Exit code to use if there are results with severity of "error". Conventionally, 0 is used for success and all non-zero codes for an error. (default 2) | ## Configuration File diff --git a/cmd/commands/root.go b/cmd/commands/root.go index ec133d4f..6054809d 100644 --- a/cmd/commands/root.go +++ b/cmd/commands/root.go @@ -23,6 +23,7 @@ type rootFlags struct { namespace string minSeverity string exitCode int + includeGenerated bool } // RootCmd defines the shell command usage for kubeaudit. @@ -50,6 +51,7 @@ func init() { RootCmd.PersistentFlags().StringVarP(&rootConfig.minSeverity, "minseverity", "m", "info", "Set the lowest severity level to report (one of \"error\", \"warning\", \"info\")") RootCmd.PersistentFlags().StringVarP(&rootConfig.format, "format", "p", "pretty", "The output format to use (one of \"pretty\", \"logrus\", \"json\")") RootCmd.PersistentFlags().StringVarP(&rootConfig.namespace, "namespace", "n", apiv1.NamespaceAll, "Only audit resources in the specified namespace. Not currently supported in manifest mode.") + RootCmd.PersistentFlags().BoolVarP(&rootConfig.includeGenerated, "includegenerated", "g", false, "Include generated resources in scan (eg. pods generated by deployments).") RootCmd.PersistentFlags().StringVarP(&rootConfig.manifest, "manifest", "f", "", "Path to the yaml configuration to audit. Only used in manifest mode.") RootCmd.PersistentFlags().IntVarP(&rootConfig.exitCode, "exitcode", "e", 2, "Exit code to use if there are results with severity of \"error\". Conventionally, 0 is used for success and all non-zero codes for an error.") } @@ -101,14 +103,14 @@ func getReport(auditors ...kubeaudit.Auditable) *kubeaudit.Report { } if k8sinternal.IsRunningInCluster(k8sinternal.DefaultClient) && rootConfig.kubeConfig == "" { - report, err := auditor.AuditCluster(k8sinternal.ClientOptions{Namespace: rootConfig.namespace}) + report, err := auditor.AuditCluster(k8sinternal.ClientOptions{Namespace: rootConfig.namespace, IncludeGenerated: rootConfig.includeGenerated}) if err != nil { log.WithError(err).Fatal("Error auditing cluster") } return report } - report, err := auditor.AuditLocal(rootConfig.kubeConfig, kubeaudit.AuditOptions{Namespace: rootConfig.namespace}) + report, err := auditor.AuditLocal(rootConfig.kubeConfig, kubeaudit.AuditOptions{Namespace: rootConfig.namespace, IncludeGenerated: rootConfig.includeGenerated}) if err != nil { log.WithError(err).Fatal("Error auditing cluster in local mode") } diff --git a/internal/k8sinternal/client.go b/internal/k8sinternal/client.go index e183f4e1..722468d1 100644 --- a/internal/k8sinternal/client.go +++ b/internal/k8sinternal/client.go @@ -85,6 +85,8 @@ func IsRunningInCluster(client Client) bool { type ClientOptions struct { // Namespace filters resources by namespace. Defaults to all namespaces. Namespace string + // IncludeGenerated is a boolean option to include generated resources. + IncludeGenerated bool } // GetAllResources gets all supported resources from the cluster @@ -103,8 +105,9 @@ func GetAllResources(clientset kubernetes.Interface, options ClientOptions) []k8 resources = append(resources, GetNamespaces(clientset, options)...) resources = append(resources, GetServices(clientset, options)...) resources = append(resources, GetJobs(clientset, options)...) - - resources = excludeGenerated(resources) + if options.IncludeGenerated == false { + resources = excludeGenerated(resources) + } return resources }