From 865817dfda9c0360cc71aba36613f2070ed60781 Mon Sep 17 00:00:00 2001 From: Huang Huang Date: Fri, 25 Nov 2022 21:32:49 +0800 Subject: [PATCH] support customize datadir locations of etcd (#1330) --- cfg/cis-1.20/master.yaml | 8 ++++++- cfg/cis-1.23/master.yaml | 8 ++++++- cfg/cis-1.5/master.yaml | 16 +++++++++++-- cfg/cis-1.6/master.yaml | 16 +++++++++++-- cfg/config.yaml | 8 +++++++ cmd/common.go | 2 ++ cmd/util.go | 1 + cmd/util_test.go | 52 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 105 insertions(+), 6 deletions(-) diff --git a/cfg/cis-1.20/master.yaml b/cfg/cis-1.20/master.yaml index fcbfcd4..10e5028 100644 --- a/cfg/cis-1.20/master.yaml +++ b/cfg/cis-1.20/master.yaml @@ -153,7 +153,13 @@ groups: - id: 1.1.11 text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c permissions=%a + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c permissions=%a "$DATA_DIR" tests: test_items: - flag: "permissions" diff --git a/cfg/cis-1.23/master.yaml b/cfg/cis-1.23/master.yaml index c77c9a1..8ed17af 100644 --- a/cfg/cis-1.23/master.yaml +++ b/cfg/cis-1.23/master.yaml @@ -147,7 +147,13 @@ groups: - id: 1.1.11 text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c permissions=%a + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c permissions=%a "$DATA_DIR" tests: test_items: - flag: "permissions" diff --git a/cfg/cis-1.5/master.yaml b/cfg/cis-1.5/master.yaml index 926cc32..df0b491 100644 --- a/cfg/cis-1.5/master.yaml +++ b/cfg/cis-1.5/master.yaml @@ -158,7 +158,13 @@ groups: - id: 1.1.11 text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c permissions=%a + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c permissions=%a "$DATA_DIR" tests: test_items: - flag: "permissions" @@ -176,7 +182,13 @@ groups: - id: 1.1.12 text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %U:%G + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c %U:%G $DATA_DIR tests: test_items: - flag: "etcd:etcd" diff --git a/cfg/cis-1.6/master.yaml b/cfg/cis-1.6/master.yaml index 59d5e0b..85ed523 100644 --- a/cfg/cis-1.6/master.yaml +++ b/cfg/cis-1.6/master.yaml @@ -153,7 +153,13 @@ groups: - id: 1.1.11 text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c permissions=%a + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c permissions=%a "$DATA_DIR" tests: test_items: - flag: "permissions" @@ -170,7 +176,13 @@ groups: - id: 1.1.12 text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)" - audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %U:%G + audit: | + DATA_DIR='' + for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do + if test -d "$d"; then DATA_DIR="$d"; fi + done + if ! test -d "$DATA_DIR"; then DATA_DIR=$etcddatadir; fi + stat -c %U:%G $DATA_DIR tests: test_items: - flag: "etcd:etcd" diff --git a/cfg/config.yaml b/cfg/config.yaml index ad24177..306c875 100644 --- a/cfg/config.yaml +++ b/cfg/config.yaml @@ -89,6 +89,9 @@ master: bins: - "etcd" - "openshift start etcd" + datadirs: + - /var/lib/etcd/default.etcd + - /var/lib/etcd/data.etcd confs: - /etc/kubernetes/manifests/etcd.yaml - /etc/kubernetes/manifests/etcd.yml @@ -99,6 +102,7 @@ master: - /var/snap/microk8s/current/args/etcd - /usr/lib/systemd/system/etcd.service defaultconf: /etc/kubernetes/manifests/etcd.yaml + defaultdatadir: /var/lib/etcd/default.etcd flanneld: optional: true @@ -211,6 +215,9 @@ etcd: etcd: bins: - "etcd" + datadirs: + - /var/lib/etcd/default.etcd + - /var/lib/etcd/data.etcd confs: - /etc/kubernetes/manifests/etcd.yaml - /etc/kubernetes/manifests/etcd.yml @@ -221,6 +228,7 @@ etcd: - /var/snap/microk8s/current/args/etcd - /usr/lib/systemd/system/etcd.service defaultconf: /etc/kubernetes/manifests/etcd.yaml + defaultdatadir: /var/lib/etcd/default.etcd controlplane: components: diff --git a/cmd/common.go b/cmd/common.go index cf29794..dc447e8 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -96,6 +96,7 @@ func runChecks(nodetype check.NodeType, testYamlFile, detectedVersion string) { svcmap := getFiles(typeConf, "service") kubeconfmap := getFiles(typeConf, "kubeconfig") cafilemap := getFiles(typeConf, "ca") + datadirmap := getFiles(typeConf, "datadir") // Variable substitutions. Replace all occurrences of variables in controls files. s := string(in) @@ -104,6 +105,7 @@ func runChecks(nodetype check.NodeType, testYamlFile, detectedVersion string) { s, _ = makeSubstitutions(s, "svc", svcmap) s, _ = makeSubstitutions(s, "kubeconfig", kubeconfmap) s, _ = makeSubstitutions(s, "cafile", cafilemap) + s, _ = makeSubstitutions(s, "datadir", datadirmap) controls, err := check.NewControls(nodetype, []byte(s), detectedVersion) if err != nil { diff --git a/cmd/util.go b/cmd/util.go index 2ab2cca..d67d854 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -33,6 +33,7 @@ var ( "kubeconfig": {"kubeconfig", "defaultkubeconfig"}, "service": {"svc", "defaultsvc"}, "config": {"confs", "defaultconf"}, + "datadir": {"datadirs", "defaultdatadir"}, } ) diff --git a/cmd/util_test.go b/cmd/util_test.go index 7ced42a..ecdd04c 100644 --- a/cmd/util_test.go +++ b/cmd/util_test.go @@ -395,6 +395,58 @@ func TestGetServiceFiles(t *testing.T) { } } +func TestGetDatadirFiles(t *testing.T) { + var err error + datadir, err := ioutil.TempDir("", "kube-bench-test-etcd-data-dir") + if err != nil { + t.Fatalf("Failed to create temp directory") + } + defer os.RemoveAll(datadir) + + cases := []struct { + config map[string]interface{} + exp map[string]string + statResults []error + }{ + { + config: map[string]interface{}{ + "components": []string{"etcd"}, + "etcd": map[string]interface{}{"datadirs": []string{datadir}, + "defaultdatadir": "/var/lib/etcd/default.etcd"}, + }, + statResults: []error{nil}, + exp: map[string]string{"etcd": datadir}, + }, + // fallback to defaultdatadir + { + config: map[string]interface{}{ + "components": []string{"etcd"}, + "etcd": map[string]interface{}{"datadirs": []string{"/path/to/etcd/data.etcd"}, + "defaultdatadir": "/var/lib/etcd/default.etcd"}, + }, + statResults: []error{os.ErrNotExist}, + exp: map[string]string{"etcd": "/var/lib/etcd/default.etcd"}, + }, + } + + v := viper.New() + statFunc = fakestat + + for id, c := range cases { + t.Run(strconv.Itoa(id), func(t *testing.T) { + for k, val := range c.config { + v.Set(k, val) + } + e = c.statResults + eIndex = 0 + m := getFiles(v, "datadir") + if !reflect.DeepEqual(m, c.exp) { + t.Fatalf("Got %v\nExpected %v", m, c.exp) + } + }) + } +} + func TestMakeSubsitutions(t *testing.T) { cases := []struct { input string