Repository: aquasecurity/kube-bench
Pull request #817 (2021-02-07 16:04:50)

Add version logging
issue #816  add more logging for better debug and information about version auto-detection and fix typo

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=h1) Report
> Merging [#817](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=desc) (bbee601) into [main](https://codecov.io/gh/aquasecurity/kube-bench/commit/5ae42ebd82d58881799c630042648d1517fc4ae8?el=desc) (5ae42eb) will **decrease** coverage by `0.13%`.
> The diff coverage is `53.84%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/kube-bench/pull/817/graphs/tree.svg?width=650&height=150&src=pr&token=MVaDEmdgi9)](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##             main     #817      +/-   ##
==========================================
- Coverage   66.58%   66.45%   -0.14%     
==========================================
  Files          14       14              
  Lines        1257     1267      +10     
==========================================
+ Hits          837      842       +5     
- Misses        364      369       +5     
  Partials       56       56              
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/util.go](https://codecov.io/gh/aquasecurity/kube-bench/pull/817/diff?src=pr&el=tree#diff-Y21kL3V0aWwuZ28=) | `74.27% <50.00%> (-0.73%)` | :arrow_down: |
| [cmd/kubernetes\_version.go](https://codecov.io/gh/aquasecurity/kube-bench/pull/817/diff?src=pr&el=tree#diff-Y21kL2t1YmVybmV0ZXNfdmVyc2lvbi5nbw==) | `78.16% <60.00%> (-1.36%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=footer). Last update [95905fb...6c3e31e](https://codecov.io/gh/aquasecurity/kube-bench/pull/817?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index e0f4ae5..724864e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -3,15 +3,35 @@ name: Bug report
 about: Tell us about a problem you are experiencing
 ---
 
-**What steps did you take and what happened:**
+**Overview**
 
-[A clear and concise description of what the bug is, and what commands you ran. If possible please supply logs generated with the `-v 3` parameter.)
+[A clear and concise description of what the bug is] 
+
+**How did you run kube-bench?**
+
+[Please specify exactly how you ran kube-bench, including details of command parameters and/or job file that you used to run it]
+
+**What happened?**
+
+[Please include output from the report to illustrate the problem. If possible please supply logs generated with the `-v 3` parameter.]
 
 **What did you expect to happen:**
 
+[Please describe what you expected to happen differently.]
+
 **Environment** 
 
-[Please specify the version of kube-bench and Kubernetes]
+[What is your version of kube-bench? (run `kube-bench version`)]
+
+[What is your version of Kubernetes? (run `kubectl version` or `oc version` on OpenShift.)]
+
+**Running processes**
+
+[Please include the output from running `ps -eaf | grep kube` on the affected node. This will allow us to check what Kubernetes processes are running, and how this compares to what kube-bench detected.]
+
+**Configuration files**
+
+[If kube-bench is reporting an issue related to the settings defined in a config file, please attach the file, or include an extract showing the settings that are being detected incorrectly.]
 
 **Anything else you would like to add:**
 
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index cbd93dc..7609d6e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,3 +1,4 @@
+---
 name: Build
 on:
   push:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 33cf5f6..77ccdeb 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,3 +1,4 @@
+---
 name: Release
 on:
   push:
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 842b682..0634baf 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -24,6 +24,7 @@ archives:
     name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{.Arm }}{{ end }}'
     files:
       - "cfg/**/*"
+      - "cfg/config.yaml"
 nfpms:
   -
     vendor: Aqua Security
@@ -32,6 +33,7 @@ nfpms:
     homepage: https://github.com/aquasecurity/kube-bench
     files:
       "cfg/**/*": "/etc/kube-bench/cfg"
+      "cfg/config.yaml": "/etc/kube-bench/cfg"
     formats:
       - deb
       - rpm
diff --git a/README.md b/README.md
index 83416bb..135e592 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,8 @@ Table of Contents
   - [CIS Kubernetes Benchmark support](#cis-kubernetes-benchmark-support)
   - [Installation](#installation)
   - [Running kube-bench](#running-kube-bench)
+    - [Specifying the benchmark or Kubernetes version](#specifying-the-benchmark-or-kubernetes-version)
+    - [Specifying Benchmark sections](#specifying-benchmark-sections)
     - [Running inside a container](#running-inside-a-container)
     - [Running in a Kubernetes cluster](#running-in-a-kubernetes-cluster)
     - [Running in an AKS cluster](#running-in-an-aks-cluster)
@@ -76,6 +78,8 @@ kube-bench supports the tests for Kubernetes as defined in the [CIS Kubernetes B
 
 By default, kube-bench will determine the test set to run based on the Kubernetes version running on the machine, but please note that kube-bench does not automatically detect OpenShift and GKE - see the section below on [Running kube-bench](https://github.com/aquasecurity/kube-bench#running-kube-bench).
 
+The test files for the various versions of CIS Benchmark can be found in directories
+with same name as the CIS Benchmark versions under `cfg/`, for example `cfg/cis-1.5`.
 ## Installation
 
 You can choose to
@@ -88,45 +92,48 @@ You can choose to
 
 If you run kube-bench directly from the command line you may need to be root / sudo to have access to all the config files.
 
-kube-bench automatically selects which `controls` to use based on the detected
-node type and the version of Kubernetes a cluster is running. This behavior
-can be overridden by specifying the `master` or `node` subcommand and the
-`--version` flag on the command line.
+By default kube-bench attempts to auto-detect the running version of Kubernetes, and map this to the corresponding CIS Benchmark version. For example, Kubernetes version 1.15 is mapped to CIS Benchmark version `cis-1.15` which is the benchmark version valid for Kubernetes 1.15.
 
+kube-bench also attempts to identify the components running on the node, and uses this to determine which tests to run (for example, only running the master node tests if the node is running an API server). 
 
-The Kubernetes version can also be set with the `KUBE_BENCH_VERSION` environment variable.
-The value of `--version` takes precedence over the value of `KUBE_BENCH_VERSION`.
+### Specifying the benchmark or Kubernetes version
 
-For example, run kube-bench against a master with version auto-detection:
+kube-bench uses the Kubernetes API, or access to the `kubectl` or `kubelet` executables to try to determine the Kubernetes version, and hence which benchmark to run. If you wish to override this, or if none of these methods are available, you can specify either the Kubernetes version or CIS Benchmark as a command line parameter.  
 
-```
-kube-bench master
-```
+You can specify a particular version of Kubernetes by setting the `--version` flag or with the `KUBE_BENCH_VERSION` environment variable. The value of `--version` takes precedence over the value of `KUBE_BENCH_VERSION`.
 
-Or run kube-bench against a worker node using the tests for Kubernetes version 1.13:
+For example, run kube-bench using the tests for Kubernetes version 1.13:
 
 ```
-kube-bench node --version 1.13
+kube-bench --version 1.13
 ```
 
-`kube-bench` will map the `--version` to the corresponding CIS Benchmark version as indicated by the mapping table above. For example, if you specify `--version 1.15`, this is mapped to CIS Benchmark version `cis-1.15`.
 
-Alternatively, you can specify `--benchmark` to run a specific CIS Benchmark version:
+You can specify `--benchmark` to run a specific CIS Benchmark version:
 
 ```
-kube-bench node --benchmark cis-1.5
+kube-bench --benchmark cis-1.5
 ```
 
-If you want to target specific CIS Benchmark `target` (i.e master, node, etcd, etc...)
+**Note:**  It is an error to specify both `--version` and `--benchmark` flags together
+
+### Specifying Benchmark sections
+
+If you want to run specific CIS Benchmark sections (i.e master, node, etcd, etc...)
 you can use the `run --targets` subcommand.
+
 ```
-kube-bench --benchmark cis-1.5 run --targets master,node
+kube-bench run --targets master,node
 ```
+
 or
+
 ```
-kube-bench --benchmark cis-1.5 run --targets master,node,etcd,policies
+kube-bench run --targets master,node,etcd,policies
 ```
 
+Check the contents of the benchmark directory under `cfg` to see which targets are available for that benchmark. Each file except `config.yaml` represents a target (also known as a `control` in other parts of this documentation). 
+
 The following table shows the valid targets based on the CIS Benchmark version.
 | CIS Benchmark | Targets |
 |---|---|
@@ -135,40 +142,31 @@ The following table shows the valid targets based on the CIS Benchmark version.
 | gke-1.0| master, controlplane, node, etcd, policies, managedservices |
 | eks-1.0| controlplane, node, policies, managedservices |
 
-If no targets are specified, `kube-bench` will determine the appropriate targets based on the CIS Benchmark version.
-
-`controls` for the various versions of CIS Benchmark can be found in directories
-with same name as the CIS Benchmark versions under `cfg/`, for example `cfg/cis-1.5`.
-
-**Note:**  **`It is an error to specify both --version and --benchmark flags together`**
-
+If no targets are specified, `kube-bench` will determine the appropriate targets based on the CIS Benchmark version and the components detected on the node. The detection is done by verifying which components are running, as defined in the config files (see [Configuration](#configuration).
 ### Running inside a container
 
 You can avoid installing kube-bench on the host by running it inside a container using the host PID namespace and mounting the `/etc` and `/var` directories where the configuration and other files are located on the host so that kube-bench can check their existence and permissions.
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest [master|node] --version 1.13
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest --version 1.13
 ```
 
 > Note: the tests require either the kubelet or kubectl binary in the path in order to auto-detect the Kubernetes version. You can pass `-v $(which kubectl):/usr/local/mount-from-host/bin/kubectl` to resolve this. You will also need to pass in kubeconfig credentials. For example:
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config -t aquasec/kube-bench:latest [master|node]
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config -t aquasec/kube-bench:latest 
 ```
 
 You can use your own configs by mounting them over the default ones in `/opt/kube-bench/cfg/`
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yam -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config aquasec/kube-bench:latest [master|node]
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yam -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config aquasec/kube-bench:latest
 ```
 
 ### Running in a Kubernetes cluster
 
 You can run kube-bench inside a pod, but it will need access to the host's PID namespace in order to check the running processes, as well as access to some directories on the host where config files and other files are stored.
 
-Master nodes are automatically detected by kube-bench and will run master checks when possible.
-The detection is done by verifying that mandatory components for master, as defined in the config files, are running (see [Configuration](#configuration)).
-
 The supplied `job.yaml` file can be applied to run the tests as a job. For example:
 
 ```bash
@@ -191,18 +189,14 @@ kubectl logs kube-bench-j76s9
 ...
 ```
 
-You can still force to run specific master or node checks using respectively `job-master.yaml` and `job-node.yaml`.
-
-To run the tests on the master node, the pod needs to be scheduled on that node. This involves setting a nodeSelector and tolerations in the pod spec.
+To run tests on the master node, the pod needs to be scheduled on that node. This involves setting a nodeSelector and tolerations in the pod spec.
 
 The default labels applied to master nodes has changed since Kubernetes 1.11, so if you are using an older version you may need to modify the nodeSelector and tolerations to run the job on the master node.
-
-
 ### Running in an AKS cluster
 
 1. Create an AKS cluster(e.g. 1.13.7) with RBAC enabled, otherwise there would be 4 failures
 
-1. Use the [kubectl-enter plugin] (https://github.com/kvaps/kubectl-enter) to shell into a node
+1. Use the [kubectl-enter plugin](https://github.com/kvaps/kubectl-enter) to shell into a node
 `
 kubectl-enter {node-name}
 `
@@ -212,7 +206,7 @@ could open nsg 22 port and assign a public ip for one agent node (only for testi
 1. Run CIS benchmark to view results:
 ```
 docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
-./kube-bench node
+./kube-bench 
 ```
 kube-bench cannot be run on AKS master nodes
 
@@ -282,7 +276,7 @@ This command copies the kube-bench binary and configuration files to your host f
 docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
 ```
 
-You can then run `./kube-bench [master|node]`.
+You can then run `./kube-bench`.
 
 ### Download and Install binaries
 
@@ -318,12 +312,12 @@ tar -xvf kube-bench_0.3.1_linux_amd64.tar.gz
 
 You can then run kube-bench directly:
 ```
-kube-bench [master|node]
+kube-bench
 ```
 
 If you manually downloaded the kube-bench binary (using curl command above), you have to specify the location of configuration directory and file. For example:
 ```
-./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml [master|node]
+./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml 
 ```
 
 See previous section on [Running kube-bench](#running-kube-bench) for further details on using the kube-bench binary.
diff --git a/cfg/cis-1.6/master.yaml b/cfg/cis-1.6/master.yaml
index 989736b..e4f971a 100644
--- a/cfg/cis-1.6/master.yaml
+++ b/cfg/cis-1.6/master.yaml
@@ -819,8 +819,15 @@ groups:
 
       - id: 1.2.34
         text: "Ensure that encryption providers are appropriately configured (Manual)"
-        audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
-        type: "manual"
+        audit: |
+          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\([^ ]*\).*%\1%')
+          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o "[A-Za-z]*" | sed 's/^/provider=/'; fi
+        tests:
+          test_items:
+            - flag: "provider"
+              compare:
+                op: valid_elements
+                value: "aescbc,kms,secretbox"
         remediation: |
           Follow the Kubernetes documentation and configure a EncryptionConfig file.
           In this file, choose aescbc, kms or secretbox as the encryption provider.
diff --git a/cfg/config.yaml b/cfg/config.yaml
index 98ff0c4..0003cbb 100644
--- a/cfg/config.yaml
+++ b/cfg/config.yaml
@@ -121,11 +121,13 @@ node:
       - "/etc/kubernetes/kubelet.conf"
       - "/var/lib/kubelet/kubeconfig"
       - "/etc/kubernetes/kubelet-kubeconfig"
+      - "/etc/kubernetes/kubelet/kubeconfig"
       - "/var/snap/microk8s/current/credentials/kubelet.config"
     confs:
       - "/var/lib/kubelet/config.yaml"
       - "/var/lib/kubelet/config.yml"
       - "/etc/kubernetes/kubelet/kubelet-config.json"
+      - "/etc/kubernetes/kubelet/config"
       - "/home/kubernetes/kubelet-config.yaml"
       - "/home/kubernetes/kubelet-config.yml"
       - "/etc/default/kubelet"
@@ -160,8 +162,10 @@ node:
       - /etc/kubernetes/addons/kube-proxy-daemonset.yml
       - /var/snap/kube-proxy/current/args
       - /var/snap/microk8s/current/args/kube-proxy
+      - /var/lib/kube-proxy/config.conf
     kubeconfig:
       - "/etc/kubernetes/kubelet-kubeconfig"
+      - "/etc/kubernetes/kubelet/config"
       - "/var/lib/kubelet/kubeconfig"
       - "/var/snap/microk8s/current/credentials/proxy.config"
     svc:
diff --git a/cmd/kubernetes_version.go b/cmd/kubernetes_version.go
index de5cb9e..3f3f7e9 100644
--- a/cmd/kubernetes_version.go
+++ b/cmd/kubernetes_version.go
@@ -33,24 +33,28 @@ func (k *KubeVersion) BaseVersion() string {
 }
 
 func getKubeVersionFromRESTAPI() (*KubeVersion, error) {
+	glog.V(2).Info("Try to get version from Rest API")
 	k8sVersionURL := getKubernetesURL()
 	serviceaccount := "/var/run/secrets/kubernetes.io/serviceaccount"
 	cacertfile := fmt.Sprintf("%s/ca.crt", serviceaccount)
 	tokenfile := fmt.Sprintf("%s/token", serviceaccount)
 
-	tlsCert, err := loadCertficate(cacertfile)
+	tlsCert, err := loadCertificate(cacertfile)
 	if err != nil {
+		glog.V(2).Infof("Failed loading certificate Error: %s", err)
 		return nil, err
 	}
 
 	tb, err := ioutil.ReadFile(tokenfile)
 	if err != nil {
+		glog.V(2).Infof("Failed reading token file Error: %s", err)
 		return nil, err
 	}
 	token := strings.TrimSpace(string(tb))
 
 	data, err := getWebDataWithRetry(k8sVersionURL, token, tlsCert)
 	if err != nil {
+		glog.V(2).Infof("Failed to get data Error: %s", err)
 		return nil, err
 	}
 
@@ -143,7 +147,7 @@ func getWebData(srvURL, token string, cacert *tls.Certificate) ([]byte, error) {
 	return ioutil.ReadAll(resp.Body)
 }
 
-func loadCertficate(certFile string) (*tls.Certificate, error) {
+func loadCertificate(certFile string) (*tls.Certificate, error) {
 	cacert, err := ioutil.ReadFile(certFile)
 	if err != nil {
 		return nil, err
diff --git a/cmd/master.go b/cmd/master.go
index 5b345e9..e8db8e3 100644
--- a/cmd/master.go
+++ b/cmd/master.go
@@ -37,6 +37,7 @@ var masterCmd = &cobra.Command{
 		runChecks(check.MASTER, filename)
 		writeOutput(controlsCollection)
 	},
+	Deprecated: "this command will be retired soon. Please use the `run` command with `--targets=master` instead.",
 }
 
 func init() {
diff --git a/cmd/node.go b/cmd/node.go
index 707bff6..4eb13db 100644
--- a/cmd/node.go
+++ b/cmd/node.go
@@ -37,6 +37,7 @@ var nodeCmd = &cobra.Command{
 		runChecks(check.NODE, filename)
 		writeOutput(controlsCollection)
 	},
+	Deprecated: "this command will be retired soon. Please use the `run` command with `--targets=node` instead.",
 }
 
 func init() {
diff --git a/cmd/run.go b/cmd/run.go
index 20199c5..16b6641 100644
--- a/cmd/run.go
+++ b/cmd/run.go
@@ -52,7 +52,10 @@ var runCmd = &cobra.Command{
 
 		// Merge version-specific config if any.
 		path := filepath.Join(cfgDir, bv)
-		mergeConfig(path)
+		err = mergeConfig(path)
+		if err != nil {
+			fmt.Printf("Error in mergeConfig: %v\n", err)
+		}
 
 		err = run(targets, bv)
 		if err != nil {
diff --git a/cmd/util.go b/cmd/util.go
index 91476d9..d2a1baf 100644
--- a/cmd/util.go
+++ b/cmd/util.go
@@ -291,12 +291,15 @@ func getKubeVersion() (*KubeVersion, error) {
 	_, err := exec.LookPath("kubectl")
 
 	if err != nil {
+		glog.V(3).Infof("Error locating kubectl: %s", err)
 		_, err = exec.LookPath("kubelet")
 		if err != nil {
+			glog.V(3).Infof("Error locating kubelet: %s", err)
 			// Search for the kubelet binary all over the filesystem and run the first match to get the kubernetes version
 			cmd := exec.Command("/bin/sh", "-c", "`find / -type f -executable -name kubelet 2>/dev/null | grep -m1 .` --version")
 			out, err := cmd.CombinedOutput()
 			if err == nil {
+				glog.V(3).Infof("Found kubelet and query kubernetes version is: %s", string(out))
 				return getVersionFromKubeletOutput(string(out)), nil
 			}
 
@@ -313,6 +316,7 @@ func getKubeVersionFromKubectl() *KubeVersion {
 	cmd := exec.Command("kubectl", "version", "-o", "json")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
+		glog.V(2).Infof("Failed to query kubectl: %s", err)
 		glog.V(2).Info(err)
 	}
 
@@ -324,6 +328,7 @@ func getKubeVersionFromKubelet() *KubeVersion {
 	out, err := cmd.CombinedOutput()
 
 	if err != nil {
+		glog.V(2).Infof("Failed to query kubelet: %s", err)
 		glog.V(2).Info(err)
 	}
 
@@ -331,7 +336,7 @@ func getKubeVersionFromKubelet() *KubeVersion {
 }
 
 func getVersionFromKubectlOutput(s string) *KubeVersion {
-	glog.V(2).Info(s)
+	glog.V(2).Infof("Kubectl output: %s", s)
 	type versionResult struct {
 		ServerVersion VersionResponse
 	}
@@ -354,7 +359,7 @@ func getVersionFromKubectlOutput(s string) *KubeVersion {
 }
 
 func getVersionFromKubeletOutput(s string) *KubeVersion {
-	glog.V(2).Info(s)
+	glog.V(2).Infof("Kubelet output: %s", s)
 	serverVersionRe := regexp.MustCompile(`Kubernetes v(\d+.\d+)`)
 	subs := serverVersionRe.FindStringSubmatch(s)
 	if len(subs) < 2 {
diff --git a/docs/asff.md b/docs/asff.md
index 7445d84..40cdfbe 100644
--- a/docs/asff.md
+++ b/docs/asff.md
@@ -15,7 +15,7 @@ You can configure kube-bench with the `--asff` to send findings to AWS Security
 
 ## Configure permissions in an IAM Role
 
-* Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two potions:
+* Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two options:
   * You can run the kube-bench pod under a specific [service account associated with an IAM role](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) that has these permissions to write Security Hub findings.
   * Alternatively the pod can be granted permissions specified by the Role that your [EKS node group uses](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html).
   
@@ -36,16 +36,14 @@ Here is an example IAM Policy that you can attach to your EKS node group's IAM R
 }
 ```
 
-## Configure and rebuild kube-bench
+### Modify the job configuration
 
-You will need to download, build and push the kube-bench container image to your ECR repo as described in Step 3 of the [EKS instructions][eks-instructions], except that before you build the container image, you need to edit `cfg/eks-1.0/config.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN.
+* Modify the kube-bench Configmap in `job-eks-asff.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN.
+* In the same file, modify the image specifed in the Job to use the kube-bench image pushed to your ECR
+* [Optional] - If you have created a dedicated IAM role to be used with kube-bench as described above in [Configure permissions in an IAM Role](#configure-permissions-in-an-iam-role), you will need to add the IAM role arn to the kube-bench ServiceAccount in `job-eks-asff.yaml`.
+* Make sure that `job-eks-asff.yaml` specifies the container image you just pushed to your ECR registry.
 
-## Modify the job configuration
-
-* Modify `job-eks.yaml` to specify the `--asff` flag, so that kube-bench writes output in ASFF format to Security Hub
-* Make sure that `job-eks.yaml` specifies the container image you just pushed to your ECR registry.
-
-You can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks.yaml`
+You can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks-asff.yaml`
 
 Findings will be generated for any kube-bench test that generates a `[FAIL]` or `[WARN]` output. If all tests pass, no findings will be generated. However, it's recommended that you consult the pod log output to check whether any findings were generated but could not be written to Security Hub.
 
diff --git a/job-eks-asff.yaml b/job-eks-asff.yaml
new file mode 100644
index 0000000..741e282
--- /dev/null
+++ b/job-eks-asff.yaml
@@ -0,0 +1,67 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: kube-bench
+  # If using a dedicated IAM role for kube-bench, uncomment the annotations
+  # block below and replace the ROLE_ARN
+  # annotations:
+  #   eks.amazonaws.com/role-arn: "<ROLE_ARN>"
+
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: kube-bench-eks-config
+data:
+  config.yaml: |
+    AWS_ACCOUNT: "<AWS_ACCT_NUMBER>"
+    AWS_REGION: "<AWS_REGION>"
+    CLUSTER_ARN: "<AWS_CLUSTER_ARN>"
+
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: kube-bench
+spec:
+  template:
+    spec:
+      hostPID: true
+      containers:
+        - name: kube-bench
+          # Push the image to your ECR and then refer to it here
+          image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
+          command: ["kube-bench", "node", "--benchmark", "eks-1.0", "--asff"]
+          volumeMounts:
+            - name: var-lib-kubelet
+              mountPath: /var/lib/kubelet
+              readOnly: true
+            - name: etc-systemd
+              mountPath: /etc/systemd
+              readOnly: true
+            - name: etc-kubernetes
+              mountPath: /etc/kubernetes
+              readOnly: true
+            - name: kube-bench-eks-config
+              mountPath: "/opt/kube-bench/cfg/eks-1.0/config.yaml"
+              subPath: config.yaml
+              readOnly: true
+      restartPolicy: Never
+      serviceAccountName: kube-bench
+      volumes:
+        - name: var-lib-kubelet
+          hostPath:
+            path: "/var/lib/kubelet"
+        - name: etc-systemd
+          hostPath:
+            path: "/etc/systemd"
+        - name: etc-kubernetes
+          hostPath:
+            path: "/etc/kubernetes"
+        - name: kube-bench-eks-config
+          configMap:
+            name: kube-bench-eks-config
+            items:
+              - key: config.yaml
+                path: config.yaml
diff --git a/job-eks.yaml b/job-eks.yaml
index 7a51e75..720c428 100644
--- a/job-eks.yaml
+++ b/job-eks.yaml
@@ -10,11 +10,9 @@ spec:
       containers:
         - name: kube-bench
           # Push the image to your ECR and then refer to it here
-          image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
-          # Use the --asff flag if you would like to send findings to AWS Security Hub
-          # Note that this requires you to rebuild a version of the kube-bench image
-          # after editing the cfg/eks-1.0/config.yaml with your account information
-          # command: ["kube-bench", "node", "--benchmark", "eks-1.0", "--asff"]
+          # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
+          image: aquasec/kube-bench:latest
+          # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead
           command: ["kube-bench", "node", "--benchmark", "eks-1.0"]
           volumeMounts:
             - name: var-lib-kubelet
diff --git a/job-master.yaml b/job-master.yaml
index ad6be40..4154506 100644
--- a/job-master.yaml
+++ b/job-master.yaml
@@ -16,7 +16,7 @@ spec:
       containers:
         - name: kube-bench
           image: aquasec/kube-bench:latest
-          command: ["kube-bench", "master"]
+          command: ["kube-bench", "run", "--targets=master"]
           volumeMounts:
             - name: var-lib-etcd
               mountPath: /var/lib/etcd
diff --git a/job-node.yaml b/job-node.yaml
index 7160f4a..6d4bbce 100644
--- a/job-node.yaml
+++ b/job-node.yaml
@@ -10,7 +10,7 @@ spec:
       containers:
         - name: kube-bench
           image: aquasec/kube-bench:latest
-          command: ["kube-bench", "node"]
+          command: ["kube-bench", "run", "--targets=node"]
           volumeMounts:
             - name: var-lib-kubelet
               mountPath: /var/lib/kubelet


Test patch:
diff --git a/cmd/common_test.go b/cmd/common_test.go
index 60fb234..048ed4b 100644
--- a/cmd/common_test.go
+++ b/cmd/common_test.go
@@ -195,17 +195,19 @@ func TestIsMaster(t *testing.T) {
 	defer restore()
 
 	for _, tc := range testCases {
-		cfgFile = tc.cfgFile
-		initConfig()
-
-		oldGetBinariesFunc := getBinariesFunc
-		getBinariesFunc = tc.getBinariesFunc
-		defer func() {
-			getBinariesFunc = oldGetBinariesFunc
-			cfgFile = ""
+		func() {
+			cfgFile = tc.cfgFile
+			initConfig()
+
+			oldGetBinariesFunc := getBinariesFunc
+			getBinariesFunc = tc.getBinariesFunc
+			defer func() {
+				getBinariesFunc = oldGetBinariesFunc
+				cfgFile = ""
+			}()
+
+			assert.Equal(t, tc.isMaster, isMaster(), tc.name)
 		}()
-
-		assert.Equal(t, tc.isMaster, isMaster(), tc.name)
 	}
 }
 
@@ -506,17 +508,19 @@ func TestIsEtcd(t *testing.T) {
 	defer restore()
 
 	for _, tc := range testCases {
-		cfgFile = tc.cfgFile
-		initConfig()
-
-		oldGetBinariesFunc := getBinariesFunc
-		getBinariesFunc = tc.getBinariesFunc
-		defer func() {
-			getBinariesFunc = oldGetBinariesFunc
-			cfgFile = ""
+		func() {
+			cfgFile = tc.cfgFile
+			initConfig()
+
+			oldGetBinariesFunc := getBinariesFunc
+			getBinariesFunc = tc.getBinariesFunc
+			defer func() {
+				getBinariesFunc = oldGetBinariesFunc
+				cfgFile = ""
+			}()
+
+			assert.Equal(t, tc.isEtcd, isEtcd(), tc.name)
 		}()
-
-		assert.Equal(t, tc.isEtcd, isEtcd(), tc.name)
 	}
 }
 
diff --git a/cmd/kubernetes_version_test.go b/cmd/kubernetes_version_test.go
index 66d9b0a..b06f79f 100644
--- a/cmd/kubernetes_version_test.go
+++ b/cmd/kubernetes_version_test.go
@@ -11,8 +11,8 @@ import (
 	"testing"
 )
 
-func TestLoadCertficate(t *testing.T) {
-	tmp, err := ioutil.TempDir("", "TestFakeLoadCertficate")
+func TestLoadCertificate(t *testing.T) {
+	tmp, err := ioutil.TempDir("", "TestFakeLoadCertificate")
 	if err != nil {
 		t.Fatalf("unable to create temp directory: %v", err)
 	}
@@ -58,7 +58,7 @@ FAjB57z2NcIgJuVpQnGRYtr/JcH2Qdsq8bLtXaojUIWOOqoTDRLYozdMOOQ=
 
 	for id, c := range cases {
 		t.Run(strconv.Itoa(id), func(t *testing.T) {
-			tlsCert, err := loadCertficate(c.file)
+			tlsCert, err := loadCertificate(c.file)
 			if !c.fail {
 				if err != nil {
 					t.Errorf("unexpected error: %v", err)