kube-bench
kube-bench copied to clipboard
etcd data-dir ownership check fails if etcd user is not listed in /etc/passwd mounted from host
Overview
The etcd data directory ownership check fails even though the data directory is owned by etcd:etcd
How did you run kube-bench?
$ git clone [email protected]:aquasecurity/kube-bench.git && cd kube-bench
$ git log | head -n 1
commit af7e0c0f0bb7b6d7351bb5954734b8a6709c9ccd
$ kubectl apply -f job-master.yaml
What happened?
$ kubectl logs kube-bench-master-x2l2x
[INFO] 1 Control Plane Security Configuration
[INFO] 1.1 Control Plane Node Configuration Files
...
[FAIL] 1.1.12 Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)
...
== Remediations master ==
...
1.1.12 On the etcd server node, get the etcd data directory, passed as an argument --data-dir,
from the command 'ps -ef | grep etcd'.
Run the below command (based on the etcd data directory found above).
For example, chown etcd:etcd /var/lib/etcd
...
From -v 3:
I0701 15:31:02.076278 10478 check.go:110] ----- Running check 1.1.12 -----
I0701 15:31:02.084786 10478 check.go:299] Command: "ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G"
I0701 15:31:02.084807 10478 check.go:300] Output:
"UNKNOWN:UNKNOWN\n"
I0701 15:31:02.084819 10478 check.go:221] Running 1 test_items
I0701 15:31:02.084848 10478 test.go:153] In flagTestItem.findValue
I0701 15:31:02.084855 10478 test.go:247] Flag 'etcd:etcd' does not exist
I0701 15:31:02.084864 10478 check.go:245] Used auditCommand
I0701 15:31:02.084890 10478 check.go:277] Returning from execute on tests: finalOutput &check.testOutput{testResult:false, flagFound:false, actualResult:"UNKNOWN:UNKNOWN", ExpectedResult:"'etcd:etcd' is present"}
I0701 15:31:02.084903 10478 check.go:184] Command: "" TestResult: false State: "FAIL"
From the master node:
[root@localhost ~]# ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %U:%G
etcd:etcd
[root@localhost ~]# ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'
/var/lib/etcd
[root@localhost ~]# stat /var/lib/etcd
File: /var/lib/etcd
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd01h/64769d Inode: 1572872 Links: 3
Access: (0700/drwx------) Uid: ( 998/ etcd) Gid: ( 997/ etcd)
Context: system_u:object_r:var_lib_t:s0
Access: 2022-07-01 15:00:41.174627650 +0000
Modify: 2022-07-01 15:01:15.472573281 +0000
Change: 2022-07-01 15:01:15.472573281 +0000
Birth: 2022-07-01 14:58:24.523999708 +0000
[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
From inside the kube-bench container:
/opt/kube-bench # ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %U:%G
UNKNOWN:UNKNOWN
/opt/kube-bench # ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'
/var/lib/etcd
/opt/kube-bench # stat /var/lib/etcd/
File: /var/lib/etcd/
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd01h/64769d Inode: 1572872 Links: 3
Access: (0700/drwx------) Uid: ( 998/ UNKNOWN) Gid: ( 997/ UNKNOWN)
Access: 2022-07-01 15:00:41.174627650 +0000
Modify: 2022-07-01 15:01:15.472573281 +0000
Change: 2022-07-01 15:01:15.472573281 +0000
[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:
Check 1.1.12 to pass
Environment
CLI: 0.6.8 job-master.yaml: commit af7e0c0f0bb7b6d7351bb5954734b8a6709c9ccd
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5", GitCommit:"c285e781331a3785a7f436042c65c5641ce8a9e9", GitTreeState:"clean", BuildDate:"2022-03-16T15:58:47Z", GoVersion:"go1.17.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.8", GitCommit:"a12b886b1da059e0190c54d09c5eab5219dd7acf", GitTreeState:"clean", BuildDate:"2022-06-16T05:51:36Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}
Anything else you would like to add:
The problem is that getent(2) doesn't work because of user namespaces.
stat tries to read from /etc/passwd in that case. Which also fails if the user is not listed in there.
I'm not sure how one would get a UID to username mapping from a shared PID namespace without the /etc/passwd file, but maybe a smart person here might have an idea:-)
@m1ghtym0 Thanks for reporting.
i think this is the workaround:
$ adduser --system --no-create-home --group --disabled-login etcd --uid 998
$ getent passwd etcd etcd:x:998:998::/home/etcd:/usr/sbin/nologin
$ chown -R etcd:etcd /var/lib/etcd