Compare commits

..

8 Commits

Author SHA1 Message Date
Liz Rice
77481e8739 Merge pull request #169 from mikekim/fix-1.3.7
Fixing 1.3.7 on 1.11 master.
2018-10-29 12:12:39 +00:00
Liz Rice
48489637c5 Merge branch 'master' into fix-1.3.7 2018-10-29 12:08:22 +00:00
Liz Rice
15537cb42b Merge pull request #168 from mikekim/fix-dollar-in-paths
Fixing checks 2.2.9 and 2.2.10 on 1.11 nodes.
2018-10-27 09:31:55 +01:00
Michal Jankowski
9988503223 Fixing 1.3.7 on 1.11 master.
With multiple test items operator defaults to "and". In case of 1.3.7
the tests check whether --address flag is either set to 127.0.0.1 or not
set at all. Those conditions cannot be met at the same time.
2018-10-25 15:32:41 -07:00
Michal Jankowski
5f254de415 Fixing checks 2.2.9 and 2.2.10 on 1.11 nodes.
Path to kubelet configuration was accidentally prefixed with a dollar
symbol (probably as a result of copying some other test that used
variable name).
After removing the dollar sign from paths both checks pass on conforming
deployment.
2018-10-24 17:06:21 -07:00
Liz Rice
64f4f638e9 Merge pull request #167 from aquasecurity/fix-issue-with-kubelet-config-and-unitfile-checks
Fix issue with kubelet config and unitfile checks
2018-10-23 14:45:19 +01:00
Abubakr-Sadik Nii Nai Davis
97623aea05 Update kubernetes node benchmark to check kubelet systemd unitfile.
Also clean up the config file for 1.11 a bit.
2018-10-23 02:30:08 +00:00
Abubakr-Sadik Nii Nai Davis
ed21839464 Add getServiceFiles function.
The CIS benchmark check for node checks 2 config files for kubelet:
  - kubelet config file (kubelet.conf)
  - kubelet systemd unitfile (10-kubeadm.conf)

The getServiceFiles function gets candidates for kubelet systemd
unitfile and returns valid untifiles.
2018-10-23 02:26:38 +00:00
6 changed files with 117 additions and 28 deletions

View File

@@ -9,39 +9,21 @@
master:
apiserver:
confs:
- /etc/kubernetes/manifests/kube-apiserver.yaml
- /etc/kubernetes/manifests/kube-apiserver.manifest
defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
confs:
- /etc/kubernetes/manifests/kube-scheduler.yaml
- /etc/kubernetes/manifests/kube-scheduler.manifest
defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml
controllermanager:
confs:
- /etc/kubernetes/manifests/kube-controller-manager.yaml
- /etc/kubernetes/manifests/kube-controller-manager.manifest
defaultconf: /etc/kubernetes/manifests/kube-controller-manager.yaml
etcd:
confs:
- /etc/kubernetes/manifests/etcd.yaml
- /etc/kubernetes/manifests/etcd.manifest
defaultconf: /etc/kubernetes/manifests/etcd.yaml
node:
kubelet:
confs:
- /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
- /etc/kubernetes/kubelet.conf
defaultconf: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
defaultconf: /etc/kubernetes/kubelet.conf
defaultsvc: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
proxy:
confs:
- /etc/kubernetes/addons/kube-proxy-daemonset.yaml
defaultconf: /etc/kubernetes/addons/kube-proxy-daemonset.yaml

View File

@@ -790,6 +790,7 @@ groups:
text: "Ensure that the --address argument is set to 127.0.0.1 (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--address"
compare:

View File

@@ -362,7 +362,7 @@ groups:
- id: 2.2.3
text: "Ensure that the kubelet service file permissions are set to 644 or
more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %a $kubeletconf; fi'"
audit: "/bin/sh -c 'if test -e $kubeletsvc; then stat -c %a $kubeletsvc; fi'"
tests:
bin_op: or
test_items:
@@ -384,12 +384,12 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chmod 755 $kubeletconf
chmod 755 $kubeletsvc
scored: true
- id: 2.2.4
text: "Ensure that the kubelet service file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'"
audit: "/bin/sh -c 'if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'"
tests:
test_items:
- flag: "root:root"
@@ -397,7 +397,7 @@ groups:
remediation: |
Run the below command (based on the file location on your system) on the each worker
node. For example,
chown root:root $kubeletconf
chown root:root $kubeletsvc
scored: true
- id: 2.2.5
@@ -460,7 +460,7 @@ groups:
- id: 2.2.9
text: "Ensure that the kubelet configuration file ownership is set to root:root (Scored)"
audit: "/bin/sh -c 'if test -e $/var/lib/kubelet/config.yaml; then stat -c %U:%G $/var/lib/kubelet/config.yaml; fi'"
audit: "/bin/sh -c 'if test -e /var/lib/kubelet/config.yaml; then stat -c %U:%G /var/lib/kubelet/config.yaml; fi'"
tests:
test_items:
- flag: "root:root"
@@ -472,7 +472,7 @@ groups:
- id: 2.2.10
text: "Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Scored)"
audit: "/bin/sh -c 'if test -e $/var/lib/kubelet/config.yaml; then stat -c %a $/var/lib/kubelet/config.yaml; fi'"
audit: "/bin/sh -c 'if test -e /var/lib/kubelet/config.yaml; then stat -c %a /var/lib/kubelet/config.yaml; fi'"
tests:
bin_op: or
test_items:

View File

@@ -79,11 +79,13 @@ func runChecks(nodetype check.NodeType) {
typeConf = viper.Sub(string(nodetype))
binmap := getBinaries(typeConf)
confmap := getConfigFiles(typeConf)
svcmap := getServiceFiles(typeConf)
// Variable substitutions. Replace all occurrences of variables in controls files.
s := string(in)
s = makeSubstitutions(s, "bin", binmap)
s = makeSubstitutions(s, "conf", confmap)
s = makeSubstitutions(s, "svc", svcmap)
controls, err := check.NewControls(nodetype, []byte(s))
if err != nil {

View File

@@ -172,8 +172,6 @@ func decrementVersion(version string) string {
}
// getConfigFiles finds which of the set of candidate config files exist
// accepts a string 't' which indicates the type of config file, conf,
// podspec or untifile.
func getConfigFiles(v *viper.Viper) map[string]string {
confmap := make(map[string]string)
@@ -204,6 +202,37 @@ func getConfigFiles(v *viper.Viper) map[string]string {
return confmap
}
// getServiceFiles finds which of the set of candidate service files exist
func getServiceFiles(v *viper.Viper) map[string]string {
svcmap := make(map[string]string)
for _, component := range v.GetStringSlice("components") {
s := v.Sub(component)
if s == nil {
continue
}
// See if any of the candidate config files exist
svc := findConfigFile(s.GetStringSlice("svc"))
if svc == "" {
if s.IsSet("defaultsvc") {
svc = s.GetString("defaultsvc")
glog.V(2).Info(fmt.Sprintf("Using default service file name '%s' for component %s", svc, component))
} else {
// Default the service file name that we'll substitute to the name of the component
glog.V(2).Info(fmt.Sprintf("Missing service file for %s", component))
svc = component
}
} else {
glog.V(2).Info(fmt.Sprintf("Component %s uses service file '%s'", component, svc))
}
svcmap[component] = svc
}
return svcmap
}
// verifyBin checks that the binary specified is running
func verifyBin(bin string) bool {

View File

@@ -289,6 +289,81 @@ func TestGetConfigFiles(t *testing.T) {
}
}
func TestGetServiceFiles(t *testing.T) {
cases := []struct {
config map[string]interface{}
exp map[string]string
statResults []error
}{
{
config: map[string]interface{}{
"components": []string{"kubelet"},
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
},
statResults: []error{os.ErrNotExist, nil},
exp: map[string]string{"kubelet": "10-kubeadm.conf"},
},
{
// Component "thing" isn't included in the list of components
config: map[string]interface{}{
"components": []string{"kubelet"},
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
},
statResults: []error{os.ErrNotExist, nil},
exp: map[string]string{"kubelet": "10-kubeadm.conf"},
},
{
// More than one component
config: map[string]interface{}{
"components": []string{"kubelet", "thing"},
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
},
statResults: []error{os.ErrNotExist, nil, nil},
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "/my/file/thing"},
},
{
// Default thing to specified default service
config: map[string]interface{}{
"components": []string{"kubelet", "thing"},
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}, "defaultsvc": "another/thing"},
},
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "another/thing"},
},
{
// Default thing to component name
config: map[string]interface{}{
"components": []string{"kubelet", "thing"},
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
},
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "thing"},
},
}
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 := getServiceFiles(v)
if !reflect.DeepEqual(m, c.exp) {
t.Fatalf("Got %v\nExpected %v", m, c.exp)
}
})
}
}
func TestMakeSubsitutions(t *testing.T) {
cases := []struct {
input string