Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeing "No such file or directory" for CIS benchmark 1.1.9 using K8s 1.2.1 #867

Closed
davidhay1969 opened this issue May 4, 2021 · 14 comments · Fixed by #877
Closed

Seeing "No such file or directory" for CIS benchmark 1.1.9 using K8s 1.2.1 #867

davidhay1969 opened this issue May 4, 2021 · 14 comments · Fixed by #877

Comments

@davidhay1969
Copy link
Contributor

Overview

I'm seeing: -

 "permissions=644\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory\n"

as part of the output from kube-bench for CIS test 1.1.9 ( and also for 1.1.10 ).

This is being run against the K8s Master ( Control Plane ) node.

More specifically, this is the entire output from that particular run: -

I0504 17:36:02.657095   21516 common.go:343] Mapped Kubernetes version: 1.21 to Benchmark version: cis-1.6
I0504 17:36:02.657102   21516 common.go:346] Kubernetes version: "1.21" to Benchmark version: "cis-1.6"
...
I0504 17:36:02.705809   21516 check.go:110] -----   Running check 1.1.9   -----
I0504 17:36:02.712997   21516 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a\nfind /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a"
I0504 17:36:02.713018   21516 check.go:300] Output:
 "permissions=644\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory\n"
I0504 17:36:02.713091   21516 check.go:221] Running 1 test_items
I0504 17:36:02.713152   21516 test.go:151] In flagTestItem.findValue 644
I0504 17:36:02.713161   21516 test.go:245] Flag 'permissions' exists
I0504 17:36:02.713217   21516 test.go:151] In flagTestItem.findValue 644
I0504 17:36:02.713226   21516 test.go:245] Flag 'permissions' exists
I0504 17:36:02.713259   21516 test.go:151] In flagTestItem.findValue 
I0504 17:36:02.713265   21516 test.go:245] Flag 'permissions' does not exist
I0504 17:36:02.713301   21516 check.go:245] Used auditCommand
I0504 17:36:02.713308   21516 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:false, flagFound:false, actualResult:"permissions=644\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory", ExpectedResult:"'permissions' is present"}
I0504 17:36:02.713379   21516 check.go:184] Command: "" TestResult: false State: "WARN" 

Looking at master.yaml for the CIS 1.6 tests, I can see the commands being run: -

        audit: |
          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a

and it appears to be the second find command which is borking 😢

Looking at my K8s Master node, whilst I DO have the /var/lib/cni/networks subdirectory, it actually contains no content.

However, the command, if run manually on the node itself, does work: -

find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a

albeit returning nothing because, of course, the subdirectory is empty.

Therefore, I'm at a loss to know why kube-bench is instead returning "No such file or directory" rather than nothing ( which, by my reading of the YAML, would be OK )

What am I missing ?

How did you run kube-bench?

I'm running kube-bench via the job-master.yaml slightly modified to add logging: -

command: ["kube-bench", "-v3", "--logtostderr", "--skip=1.1.12,1.2.6,1.2.10,1.2.16", "run", "--targets=master"]

rather than the default of: -

command: ["kube-bench", "run", "--targets=master"]

( note that I'm also skipping some tests )

I'm also using my own build of the kube-bench image, from the Dockerfile, as I needed to build it for my target IBM Z s390x platform.

What happened?


I0504 17:36:02.705809   21516 check.go:110] -----   Running check 1.1.9   -----
I0504 17:36:02.712997   21516 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a\nfind /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a"
I0504 17:36:02.713018   21516 check.go:300] Output:
 "permissions=644\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory\n"
I0504 17:36:02.713091   21516 check.go:221] Running 1 test_items
I0504 17:36:02.713152   21516 test.go:151] In flagTestItem.findValue 644
I0504 17:36:02.713161   21516 test.go:245] Flag 'permissions' exists
I0504 17:36:02.713217   21516 test.go:151] In flagTestItem.findValue 644
I0504 17:36:02.713226   21516 test.go:245] Flag 'permissions' exists
I0504 17:36:02.713259   21516 test.go:151] In flagTestItem.findValue 
I0504 17:36:02.713265   21516 test.go:245] Flag 'permissions' does not exist
I0504 17:36:02.713301   21516 check.go:245] Used auditCommand
I0504 17:36:02.713308   21516 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:false, flagFound:false, actualResult:"permissions=644\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory", ExpectedResult:"'permissions' is present"}
I0504 17:36:02.713379   21516 check.go:184] Command: "" TestResult: false State: "WARN" 
I0504 17:36:02.713414   21516 check.go:110] -----   Running check 1.1.10   -----
I0504 17:36:02.720453   21516 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c %U:%G\nfind /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c %U:%G"
I0504 17:36:02.720469   21516 check.go:300] Output:
 "root:root\nroot:root\nfind: /var/lib/cni/networks: No such file or directory\n"
I0504 17:36:02.720475   21516 check.go:221] Running 1 test_items
I0504 17:36:02.720565   21516 test.go:151] In flagTestItem.findValue root:root
I0504 17:36:02.720572   21516 test.go:245] Flag 'root:root' exists
I0504 17:36:02.720608   21516 test.go:151] In flagTestItem.findValue root:root
I0504 17:36:02.720617   21516 test.go:245] Flag 'root:root' exists
I0504 17:36:02.720620   21516 test.go:151] In flagTestItem.findValue 
I0504 17:36:02.720646   21516 test.go:245] Flag 'root:root' does not exist
I0504 17:36:02.720672   21516 check.go:245] Used auditCommand
I0504 17:36:02.720677   21516 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:false, flagFound:false, actualResult:"root:root\nroot:root\nfind: /var/lib/cni/networks: No such file or directory", ExpectedResult:"'root:root' is present"}
I0504 17:36:02.720703   21516 check.go:184] Command: "" TestResult: false State: "WARN" 

What did you expect to happen:

Both tests should pass i.e. not throw a WARN, as the preceding commands both run happily, when run manually: -

## Set kubeletbin variable

export kubeletbin="kubelet"

## Check permissions

ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a

permissions=644
permissions=644

## Check ownership

ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c %U:%G

root:root
root:root

Environment

kube-bench image built from Dockerfile

kube-bench-master job run from slightly amended job-master.yaml

kubectl version

Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T21:16:14Z", GoVersion:"go1.16.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:25:06Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/s390x"}

Running processes

ps -eaf | grep kube

root      2957  2934 10 17:50 ?        00:00:25 kube-apiserver --advertise-address=172.16.84.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction,AlwaysPullImages,SecurityContextDeny --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key --profiling=false --audit-log-path=/var/log/apiserver/audit.log --audit-log-maxage=30 --audit-log-maxbackup=10 --audit-log-maxsize=100 --anonymous-auth=false --encryption-provider-config=/etc/kubernetes/pki/secrets.yml --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
root      3266  3235  2 17:50 ?        00:00:05 kube-controller-manager --allocate-node-cidrs=true --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf --bind-address=127.0.0.1 --client-ca-file=/etc/kubernetes/pki/ca.crt --cluster-cidr=10.244.0.0/16 --cluster-name=kubernetes --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt --cluster-signing-key-file=/etc/kubernetes/pki/ca.key --controllers=*,bootstrapsigner,tokencleaner --kubeconfig=/etc/kubernetes/controller-manager.conf --leader-elect=true --port=0 --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --root-ca-file=/etc/kubernetes/pki/ca.crt --service-account-private-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --use-service-account-credentials=true --profiling=false --terminated-pod-gc-threshold=10
root      3413  3385  1 17:50 ?        00:00:02 kube-scheduler --authentication-kubeconfig=/etc/kubernetes/scheduler.conf --authorization-kubeconfig=/etc/kubernetes/scheduler.conf --bind-address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=true --port=0 --profiling=false
root      6724  2592  0 17:54 pts/1    00:00:00 grep --color=auto kube
root      9123  9099  0 Apr30 ?        00:46:15 etcd --advertise-client-urls=https://172.16.84.4:2379 --cert-file=/etc/kubernetes/pki/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/etcd --initial-advertise-peer-urls=https://172.16.84.4:2380 --initial-cluster=de1dc841cd20=https://172.16.84.4:2380 --key-file=/etc/kubernetes/pki/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://172.16.84.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://172.16.84.4:2380 --name=de1dc841cd20 --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/etc/kubernetes/pki/etcd/peer.key --peer-trusted-ca-file=/etckubernetes/pki/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
root     10432 10402  0 Apr30 ?        00:00:49 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf --hostname-override=de1dc841cd20
root     12696 12669  0 Apr30 ?        00:20:03 /usr/bin/kube-controllers
root     20241     1  2 09:52 ?        00:09:49 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.4.1 --cni-conf-dir=/etc/cni/net.d/ --protect-kernel-defaults=true

Configuration files

See above

Anything else you would like to add:

Nope, but I suspect it's pilot error on my part 😭

@yoavrotems
Copy link
Contributor

I'm not sure on what is the difference if you say that running the command manually returns nothing but running it with kube-bench returns file not exist (maybe some output redirections? something like 2> /dev/null) anyway, I might have a solution for you,
the test is:

      - id: 1.1.9
        text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
        audit: |
          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a
        use_multiple_values: true
        tests:
          test_items:
            - flag: "permissions"
              compare:
                op: bitmask
                value: "644"
        remediation: |
          Run the below command (based on the file location on your system) on the master node.
          For example,
          chmod 644 <path/to/cni/files>
        scored: false

I think that if you change it to be:

      - id: 1.1.9
        text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
        audit: |
          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a
        use_multiple_values: true
        tests:
          bin_op: or
          test_items:
            - flag: "permissions"
              compare:
                op: bitmask
                value: "644"
            - flag: "permissions"
              set: false
        remediation: |
          Run the below command (based on the file location on your system) on the master node.
          For example,
          chmod 644 <path/to/cni/files>
        scored: false

This should fix this issue without hurting the test integrity, since we either checking if the is permissions then is should be 644 or more restrictive but if it doesn't have permissions in the output at all it still should be fine and pass because it's not less restrictive then 644 it simply doesn't exist.
Try this out and if it works update here and me you or even someone else could open a PR about it :)

@davidhay1969
Copy link
Contributor Author

Thanks @yoavrotems will have a play, and report back ... as you say, if it works, I'll open a PR 👍

@yoavrotems
Copy link
Contributor

yoavrotems commented May 18, 2021

Hey :) anything new? @davidhay1969

@davidhay1969
Copy link
Contributor Author

Apologies @yoavrotems got side-tracked, and forgot to test - on it now, watch this space ......

@davidhay1969
Copy link
Contributor Author

Alas, I suspect I'm doing it wrong, but still seeing the same warning for 1.1.9, having changed cfg/cis-1.6/master.yaml to: -

      - id: 1.1.9
        text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
        audit: |
          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a
        use_multiple_values: true
        tests:
          bin_op: or
          test_items:
            - flag: "permissions"
              compare:
                op: bitmask
                value: "644"
            - flag: "permissions"
              set: false
        remediation: |
          Run the below command (based on the file location on your system) on the master node.
          For example,
          chmod 644 <path/to/cni/files>
        scored: false

I turned on verbose logging: -

"kube-bench", "-v", "3", 

and can see: -

I0518 16:29:45.050458   28404 check.go:184] Command: "" TestResult: true State: "PASS" 
I0518 16:29:45.050468   28404 check.go:110] -----   Running check 1.1.9   -----
I0518 16:29:45.056419   28404 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a\nfind /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a"
I0518 16:29:45.056439   28404 check.go:300] Output:
 "permissions=600\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory\n"
I0518 16:29:45.056483   28404 check.go:221] Running 2 test_items
I0518 16:29:45.056529   28404 test.go:151] In flagTestItem.findValue 600
I0518 16:29:45.056555   28404 test.go:245] Flag 'permissions' exists
I0518 16:29:45.056595   28404 test.go:151] In flagTestItem.findValue 644
I0518 16:29:45.056603   28404 test.go:245] Flag 'permissions' exists
I0518 16:29:45.056607   28404 test.go:151] In flagTestItem.findValue 
I0518 16:29:45.056631   28404 test.go:245] Flag 'permissions' does not exist
I0518 16:29:45.056638   28404 check.go:245] Used auditCommand
I0518 16:29:45.056676   28404 test.go:151] In flagTestItem.findValue 600
I0518 16:29:45.056684   28404 test.go:245] Flag 'permissions' exists
I0518 16:29:45.056688   28404 check.go:245] Used auditCommand
I0518 16:29:45.056712   28404 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:false, flagFound:false, actualResult:"permissions=600\npermissions=644\nfind: /var/lib/cni/networks: No such file or directory", ExpectedResult:"'permissions' is present OR 'permissions' is not present"}
I0518 16:29:45.056751   28404 check.go:184] Command: "" TestResult: false State: "WARN" 

in the pod logs ....

Looking further now ....

@davidhay1969
Copy link
Contributor Author

Again, running the commands manually against the Control Plane Node works as expected: -

ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a

permissions=644
permissions=644

find /var/lib/cni/networks// -type f | xargs --no-run-if-empty stat -c permissions=%a

<RETURNS NOTHING>

@davidhay1969
Copy link
Contributor Author

Wondering whether the code "assumes" that a single Bash command will be included in the audit: block, whereas we're providing two commands: -

        audit: |
          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a

Looking at the runAudit function in check.go : -

func runAudit(audit string) (output string, err error) {
        	var out bytes.Buffer
        	audit = strings.TrimSpace(audit)
        	if len(audit) == 0 {
        		return output, err
        	}
        	cmd := exec.Command("/bin/sh")
        	cmd.Stdin = strings.NewReader(audit)
        	cmd.Stdout = &amp;out
        	cmd.Stderr = &amp;out
        	err = cmd.Run()
        	output = out.String()
        	if err != nil {
        		err = fmt.Errorf("failed to run: %q, output: %q, error: %s", audit, output, err)
        	} else {
        		glog.V(3).Infof("Command: %q", audit)
        		glog.V(3).Infof("Output:\n %q", output)
        	}
        	return output, err
        }

😖 😕

@yoavrotems
Copy link
Contributor

There isn't suppose to be problem with multiple line audit we use it in other places and it works.
Seems that the problem is that it return error from the command since find couldn't find any file, I think that redirecting the output will work.
The --no-run-if-empty will never apply since find return the error, lets try what I suggested.
Remove the bin_op: or and the permissions set: false.
And instead lets just redirect the error output from find, something like this:
find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a
Then we shouldn't get the error code.

@davidhay1969
Copy link
Contributor Author

Ahhhh, now that looks much better.

Having changed from: -

- id: 1.1.9
  text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
  audit: |
    ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
    find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a
  use_multiple_values: true
  tests:
    test_items:
      - flag: "permissions"
        compare:
          op: bitmask
          value: "644"
  remediation: |
    Run the below command (based on the file location on your system) on the master node.
    For example,
    chmod 644 <path/to/cni/files>
  scored: false

to: -

- id: 1.1.9
  text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
  audit: |
    ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
    find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a
  use_multiple_values: true
  tests:
    test_items:
      - flag: "permissions"
        compare:
          op: bitmask
          value: "644"
  remediation: |
    Run the below command (based on the file location on your system) on the master node.
    For example,
    chmod 644 <path/to/cni/files>
  scored: false

I now see: -

I0519 17:55:49.208288   23397 check.go:110] -----   Running check 1.1.9   -----
I0519 17:55:49.221723   23397 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a\nfind /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a"
I0519 17:55:49.221745   23397 check.go:300] Output:
 "permissions=600\npermissions=644\n"
I0519 17:55:49.221753   23397 check.go:221] Running 1 test_items
I0519 17:55:49.221799   23397 test.go:151] In flagTestItem.findValue 600
I0519 17:55:49.221807   23397 test.go:245] Flag 'permissions' exists
I0519 17:55:49.221833   23397 test.go:151] In flagTestItem.findValue 644
I0519 17:55:49.221839   23397 test.go:245] Flag 'permissions' exists
I0519 17:55:49.221845   23397 check.go:245] Used auditCommand
I0519 17:55:49.221852   23397 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:true, flagFound:false, actualResult:"permissions=600\npermissions=644", ExpectedResult:"permissions has permissions 644, expected 644 or more restrictive"}
I0519 17:55:49.221866   23397 check.go:184] Command: "" TestResult: true State: "PASS" 

running kube-bench in verbose mode: -

command: ["kube-bench", "-v", "3", "--skip=1.1.12,1.2.1,1.2.6,1.2.10,1.2.16", "run", "--targets=master"]

and I no longer see a warning for 1.1.9

Will do the same for 1.1.10 and test again .....

Thanks @yoavrotems you're a Jedi!

@davidhay1969
Copy link
Contributor Author

Yep, 1.1.10 also looks good

I0519 18:02:42.365505   28354 check.go:110] -----   Running check 1.1.9   -----
I0519 18:02:42.396191   28354 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a\nfind /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a"
I0519 18:02:42.396301   28354 check.go:300] Output:
 "permissions=600\npermissions=644\n"
I0519 18:02:42.396349   28354 check.go:221] Running 1 test_items
I0519 18:02:42.396464   28354 test.go:151] In flagTestItem.findValue 600
I0519 18:02:42.396550   28354 test.go:245] Flag 'permissions' exists
I0519 18:02:42.396636   28354 test.go:151] In flagTestItem.findValue 644
I0519 18:02:42.396707   28354 test.go:245] Flag 'permissions' exists
I0519 18:02:42.396744   28354 check.go:245] Used auditCommand
I0519 18:02:42.396783   28354 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:true, flagFound:false, actualResult:"permissions=600\npermissions=644", ExpectedResult:"permissions has permissions 644, expected 644 or more restrictive"}
I0519 18:02:42.396833   28354 check.go:184] Command: "" TestResult: true State: "PASS" 
I0519 18:02:42.396868   28354 check.go:110] -----   Running check 1.1.10   -----
I0519 18:02:42.404323   28354 check.go:299] Command: "ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c %U:%G\nfind /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G"
I0519 18:02:42.404347   28354 check.go:300] Output:
 "root:root\nroot:root\n"
I0519 18:02:42.404355   28354 check.go:221] Running 1 test_items
I0519 18:02:42.404403   28354 test.go:151] In flagTestItem.findValue root:root
I0519 18:02:42.404416   28354 test.go:245] Flag 'root:root' exists
I0519 18:02:42.404451   28354 test.go:151] In flagTestItem.findValue root:root
I0519 18:02:42.404458   28354 test.go:245] Flag 'root:root' exists
I0519 18:02:42.404465   28354 check.go:245] Used auditCommand
I0519 18:02:42.404471   28354 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:true, flagFound:false, actualResult:"root:root\nroot:root", ExpectedResult:"'root:root' is present"}
I0519 18:02:42.404483   28354 check.go:184] Command: "" TestResult: true State: "PASS" 
I0519 18:02:42.404499   28354 check.go:110] -----   Running check 1.1.11   -----
I0519 18:02:42.410556   28354 check.go:299] Command: "ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c permissions=%a"
I0519 18:02:42.410634   28354 check.go:300] Output:
 "permissions=700\n"
I0519 18:02:42.410722   28354 check.go:221] Running 1 test_items
I0519 18:02:42.410775   28354 test.go:151] In flagTestItem.findValue 700
I0519 18:02:42.410813   28354 test.go:245] Flag 'permissions' exists
I0519 18:02:42.410847   28354 check.go:245] Used auditCommand
I0519 18:02:42.410875   28354 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:true, flagFound:false, actualResult:"permissions=700", ExpectedResult:"permissions has permissions 700, expected 700 or more restrictive"}
I0519 18:02:42.410921   28354 check.go:184] Command: "" TestResult: true State: "PASS" 

@davidhay1969
Copy link
Contributor Author

So, TL;DR;, your change "merely" adds in some output redirection for the find command: -

diff --git a/cfg/cis-1.6/master.yaml b/cfg/cis-1.6/master.yaml
index 726df72..0b21cf6 100644
--- a/cfg/cis-1.6/master.yaml
+++ b/cfg/cis-1.6/master.yaml
@@ -122,7 +122,7 @@ groups:
         text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)"
         audit: |
           ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c permissions=%a
-          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c permissions=%a
+          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a
         use_multiple_values: true
         tests:
           test_items:
@@ -140,7 +140,7 @@ groups:
         text: "Ensure that the Container Network Interface file ownership is set to root:root (Manual)"
         audit: |
           ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs stat -c %U:%G
-          find /var/lib/cni/networks -type f | xargs --no-run-if-empty stat -c %U:%G
+          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G
         use_multiple_values: true
         tests:
           test_items:

which is awesome.

Thanks again, @yoavrotems - do you want to go ahead and raise a PR ? Otherwise, more than happy to do that, giving you ALL THE CREDIT, and ask you to review it ?

@yoavrotems
Copy link
Contributor

No credit needed but yes it will be awesome of you to PR it :) ! @davidhay1969

@davidhay1969
Copy link
Contributor Author

👍 will do it when I get home later this PM. Cheers 🥂

@davidhay1969
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants