mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2024-11-25 09:28:16 +00:00
Fix invalid JSON output (#629)
* Fix invalid JSON output Fixes #622 * Apply suggestions from code review Co-authored-by: Liz Rice <liz@lizrice.com> * Add tests Co-authored-by: Liz Rice <liz@lizrice.com>
This commit is contained in:
parent
5cf3821eb6
commit
52ebfa5b5a
@ -16,10 +16,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aquasecurity/kube-bench/check"
|
"github.com/aquasecurity/kube-bench/check"
|
||||||
@ -63,8 +66,6 @@ func NewRunFilter(opts FilterOpts) (check.Predicate, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runChecks(nodetype check.NodeType, testYamlFile string) {
|
func runChecks(nodetype check.NodeType, testYamlFile string) {
|
||||||
var summary check.Summary
|
|
||||||
|
|
||||||
// Verify config file was loaded into Viper during Cobra sub-command initialization.
|
// Verify config file was loaded into Viper during Cobra sub-command initialization.
|
||||||
if configFileError != nil {
|
if configFileError != nil {
|
||||||
colorPrint(check.FAIL, fmt.Sprintf("Failed to read config file: %v\n", configFileError))
|
colorPrint(check.FAIL, fmt.Sprintf("Failed to read config file: %v\n", configFileError))
|
||||||
@ -117,36 +118,8 @@ func runChecks(nodetype check.NodeType, testYamlFile string) {
|
|||||||
exitWithError(fmt.Errorf("error setting up run filter: %v", err))
|
exitWithError(fmt.Errorf("error setting up run filter: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
summary = controls.RunChecks(runner, filter)
|
controls.RunChecks(runner, filter)
|
||||||
|
controlsCollection = append(controlsCollection, controls)
|
||||||
if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && junitFmt {
|
|
||||||
out, err := controls.JUnit()
|
|
||||||
if err != nil {
|
|
||||||
exitWithError(fmt.Errorf("failed to output in JUnit format: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintOutput(string(out), outputFile)
|
|
||||||
// if we successfully ran some tests and it's json format, ignore the warnings
|
|
||||||
} else if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && jsonFmt {
|
|
||||||
out, err := controls.JSON()
|
|
||||||
if err != nil {
|
|
||||||
exitWithError(fmt.Errorf("failed to output in JSON format: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintOutput(string(out), outputFile)
|
|
||||||
} else {
|
|
||||||
// if we want to store in PostgreSQL, convert to JSON and save it
|
|
||||||
if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && pgSQL {
|
|
||||||
out, err := controls.JSON()
|
|
||||||
if err != nil {
|
|
||||||
exitWithError(fmt.Errorf("failed to output in JSON format: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
savePgsql(string(out))
|
|
||||||
} else {
|
|
||||||
prettyPrint(controls, summary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// colorPrint outputs the state in a specific colour, along with a message string
|
// colorPrint outputs the state in a specific colour, along with a message string
|
||||||
@ -359,6 +332,62 @@ func isThisNodeRunning(nodeType check.NodeType) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeOutput(controlsCollection []*check.Controls) {
|
||||||
|
sort.Slice(controlsCollection, func(i, j int) bool {
|
||||||
|
iid, _ := strconv.Atoi(controlsCollection[i].ID)
|
||||||
|
jid, _ := strconv.Atoi(controlsCollection[j].ID)
|
||||||
|
return iid < jid
|
||||||
|
})
|
||||||
|
if junitFmt {
|
||||||
|
writeJunitOutput(controlsCollection)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if jsonFmt {
|
||||||
|
writeJsonOutput(controlsCollection)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if pgSQL {
|
||||||
|
writePgsqlOutput(controlsCollection)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
writeStdoutOutput(controlsCollection)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeJsonOutput(controlsCollection []*check.Controls) {
|
||||||
|
out, err := json.Marshal(controlsCollection)
|
||||||
|
if err != nil {
|
||||||
|
exitWithError(fmt.Errorf("failed to output in JSON format: %v", err))
|
||||||
|
}
|
||||||
|
PrintOutput(string(out), outputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeJunitOutput(controlsCollection []*check.Controls) {
|
||||||
|
for _, controls := range controlsCollection {
|
||||||
|
out, err := controls.JUnit()
|
||||||
|
if err != nil {
|
||||||
|
exitWithError(fmt.Errorf("failed to output in JUnit format: %v", err))
|
||||||
|
}
|
||||||
|
PrintOutput(string(out), outputFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writePgsqlOutput(controlsCollection []*check.Controls) {
|
||||||
|
for _, controls := range controlsCollection {
|
||||||
|
out, err := controls.JSON()
|
||||||
|
if err != nil {
|
||||||
|
exitWithError(fmt.Errorf("failed to output in Postgresql format: %v", err))
|
||||||
|
}
|
||||||
|
savePgsql(string(out))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeStdoutOutput(controlsCollection []*check.Controls) {
|
||||||
|
for _, controls := range controlsCollection {
|
||||||
|
summary := controls.Summary
|
||||||
|
prettyPrint(controls, summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printRawOutput(output string) {
|
func printRawOutput(output string) {
|
||||||
for _, row := range strings.Split(output, "\n") {
|
for _, row := range strings.Split(output, "\n") {
|
||||||
fmt.Println(fmt.Sprintf("\t %s", row))
|
fmt.Println(fmt.Sprintf("\t %s", row))
|
||||||
|
@ -15,12 +15,15 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aquasecurity/kube-bench/check"
|
"github.com/aquasecurity/kube-bench/check"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -475,6 +478,51 @@ func TestIsEtcd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteResultToJsonFile(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
controlsCollection = []*check.Controls{}
|
||||||
|
jsonFmt = false
|
||||||
|
outputFile = ""
|
||||||
|
}()
|
||||||
|
var err error
|
||||||
|
jsonFmt = true
|
||||||
|
outputFile = path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().UnixNano()))
|
||||||
|
|
||||||
|
controlsCollection, err = parseControlsJsonFile("./testdata/controlsCollection.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
writeOutput(controlsCollection)
|
||||||
|
|
||||||
|
var expect []*check.Controls
|
||||||
|
var result []*check.Controls
|
||||||
|
result, err = parseControlsJsonFile(outputFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
expect, err = parseControlsJsonFile("./testdata/result.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expect, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseControlsJsonFile(filepath string) ([]*check.Controls, error) {
|
||||||
|
var result []*check.Controls
|
||||||
|
|
||||||
|
d, err := ioutil.ReadFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(d, &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func loadConfigForTest() (*viper.Viper, error) {
|
func loadConfigForTest() (*viper.Viper, error) {
|
||||||
viperWithData := viper.New()
|
viperWithData := viper.New()
|
||||||
viperWithData.SetConfigFile(filepath.Join("..", cfgDir, "config.yaml"))
|
viperWithData.SetConfigFile(filepath.Join("..", cfgDir, "config.yaml"))
|
||||||
|
@ -27,6 +27,7 @@ var masterCmd = &cobra.Command{
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
filename := loadConfig(check.MASTER)
|
filename := loadConfig(check.MASTER)
|
||||||
runChecks(check.MASTER, filename)
|
runChecks(check.MASTER, filename)
|
||||||
|
writeOutput(controlsCollection)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ var nodeCmd = &cobra.Command{
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
filename := loadConfig(check.NODE)
|
filename := loadConfig(check.NODE)
|
||||||
runChecks(check.NODE, filename)
|
runChecks(check.NODE, filename)
|
||||||
|
writeOutput(controlsCollection)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ var (
|
|||||||
includeTestOutput bool
|
includeTestOutput bool
|
||||||
outputFile string
|
outputFile string
|
||||||
configFileError error
|
configFileError error
|
||||||
|
controlsCollection []*check.Controls
|
||||||
)
|
)
|
||||||
|
|
||||||
// RootCmd represents the base command when called without any subcommands
|
// RootCmd represents the base command when called without any subcommands
|
||||||
@ -104,6 +105,7 @@ var RootCmd = &cobra.Command{
|
|||||||
runChecks(check.MANAGEDSERVICES, loadConfig(check.MANAGEDSERVICES))
|
runChecks(check.MANAGEDSERVICES, loadConfig(check.MANAGEDSERVICES))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeOutput(controlsCollection)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ func run(targets []string, benchmarkVersion string) (err error) {
|
|||||||
runChecks(testType, yamlFile)
|
runChecks(testType, yamlFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeOutput(controlsCollection)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
114
cmd/testdata/controlsCollection.json
vendored
Normal file
114
cmd/testdata/controlsCollection.json
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"version": "1.15",
|
||||||
|
"text": "Etcd Node Configuration",
|
||||||
|
"node_type": "etcd",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "2",
|
||||||
|
"pass": 7,
|
||||||
|
"fail": 0,
|
||||||
|
"warn": 0,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Etcd Node Configuration Files",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "2.1",
|
||||||
|
"test_desc": "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)",
|
||||||
|
"audit": "/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "",
|
||||||
|
"remediation": "Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=</path/to/ca-file>\n--key-file=</path/to/key-file>\n",
|
||||||
|
"test_info": [
|
||||||
|
"Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=</path/to/ca-file>\n--key-file=</path/to/key-file>\n"
|
||||||
|
],
|
||||||
|
"status": "PASS",
|
||||||
|
"actual_value": "root 3277 3218 3 Apr19 ? 03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\nroot 4624 4605 8 Apr21 ? 04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/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=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\n",
|
||||||
|
"scored": true,
|
||||||
|
"expected_result": "'--cert-file' is present AND '--key-file' is present"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 7,
|
||||||
|
"total_fail": 0,
|
||||||
|
"total_warn": 0,
|
||||||
|
"total_info": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"version": "1.5",
|
||||||
|
"text": "Control Plane Configuration",
|
||||||
|
"node_type": "controlplane",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "3.1",
|
||||||
|
"pass": 0,
|
||||||
|
"fail": 0,
|
||||||
|
"warn": 1,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Authentication and Authorization",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "3.1.1",
|
||||||
|
"test_desc": "Client certificate authentication should not be used for users (Not Scored)",
|
||||||
|
"audit": "",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "manual",
|
||||||
|
"remediation": "Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n",
|
||||||
|
"test_info": [
|
||||||
|
"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n"
|
||||||
|
],
|
||||||
|
"status": "WARN",
|
||||||
|
"actual_value": "",
|
||||||
|
"scored": false,
|
||||||
|
"expected_result": "",
|
||||||
|
"reason": "Test marked as a manual test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 0,
|
||||||
|
"total_fail": 0,
|
||||||
|
"total_warn": 3,
|
||||||
|
"total_info": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"version": "1.5",
|
||||||
|
"text": "Master Node Security Configuration",
|
||||||
|
"node_type": "master",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "1.1",
|
||||||
|
"pass": 15,
|
||||||
|
"fail": 1,
|
||||||
|
"warn": 5,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Master Node Configuration Files",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "1.1.1",
|
||||||
|
"test_desc": "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)",
|
||||||
|
"audit": "/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-apiserver.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-apiserver.yaml; fi'",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "",
|
||||||
|
"remediation": "Run the below command (based on the file location on your system) on the\nmaster node.\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\n",
|
||||||
|
"test_info": [
|
||||||
|
"Run the below command (based on the file location on your system) on the\nmaster node.\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\n"
|
||||||
|
],
|
||||||
|
"status": "PASS",
|
||||||
|
"actual_value": "permissions=600\n",
|
||||||
|
"scored": true,
|
||||||
|
"expected_result": "bitmask '600' AND '644'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 42,
|
||||||
|
"total_fail": 12,
|
||||||
|
"total_warn": 11,
|
||||||
|
"total_info": 0
|
||||||
|
}
|
||||||
|
]
|
114
cmd/testdata/result.json
vendored
Normal file
114
cmd/testdata/result.json
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"version": "1.5",
|
||||||
|
"text": "Master Node Security Configuration",
|
||||||
|
"node_type": "master",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "1.1",
|
||||||
|
"pass": 15,
|
||||||
|
"fail": 1,
|
||||||
|
"warn": 5,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Master Node Configuration Files",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "1.1.1",
|
||||||
|
"test_desc": "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)",
|
||||||
|
"audit": "/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-apiserver.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-apiserver.yaml; fi'",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "",
|
||||||
|
"remediation": "Run the below command (based on the file location on your system) on the\nmaster node.\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\n",
|
||||||
|
"test_info": [
|
||||||
|
"Run the below command (based on the file location on your system) on the\nmaster node.\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\n"
|
||||||
|
],
|
||||||
|
"status": "PASS",
|
||||||
|
"actual_value": "permissions=600\n",
|
||||||
|
"scored": true,
|
||||||
|
"expected_result": "bitmask '600' AND '644'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 42,
|
||||||
|
"total_fail": 12,
|
||||||
|
"total_warn": 11,
|
||||||
|
"total_info": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"version": "1.15",
|
||||||
|
"text": "Etcd Node Configuration",
|
||||||
|
"node_type": "etcd",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "2",
|
||||||
|
"pass": 7,
|
||||||
|
"fail": 0,
|
||||||
|
"warn": 0,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Etcd Node Configuration Files",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "2.1",
|
||||||
|
"test_desc": "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)",
|
||||||
|
"audit": "/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "",
|
||||||
|
"remediation": "Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=</path/to/ca-file>\n--key-file=</path/to/key-file>\n",
|
||||||
|
"test_info": [
|
||||||
|
"Follow the etcd service documentation and configure TLS encryption.\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\non the master node and set the below parameters.\n--cert-file=</path/to/ca-file>\n--key-file=</path/to/key-file>\n"
|
||||||
|
],
|
||||||
|
"status": "PASS",
|
||||||
|
"actual_value": "root 3277 3218 3 Apr19 ? 03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\nroot 4624 4605 8 Apr21 ? 04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/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=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\n",
|
||||||
|
"scored": true,
|
||||||
|
"expected_result": "'--cert-file' is present AND '--key-file' is present"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 7,
|
||||||
|
"total_fail": 0,
|
||||||
|
"total_warn": 0,
|
||||||
|
"total_info": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"version": "1.5",
|
||||||
|
"text": "Control Plane Configuration",
|
||||||
|
"node_type": "controlplane",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"section": "3.1",
|
||||||
|
"pass": 0,
|
||||||
|
"fail": 0,
|
||||||
|
"warn": 1,
|
||||||
|
"info": 0,
|
||||||
|
"desc": "Authentication and Authorization",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"test_number": "3.1.1",
|
||||||
|
"test_desc": "Client certificate authentication should not be used for users (Not Scored)",
|
||||||
|
"audit": "",
|
||||||
|
"AuditConfig": "",
|
||||||
|
"type": "manual",
|
||||||
|
"remediation": "Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n",
|
||||||
|
"test_info": [
|
||||||
|
"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n"
|
||||||
|
],
|
||||||
|
"status": "WARN",
|
||||||
|
"actual_value": "",
|
||||||
|
"scored": false,
|
||||||
|
"expected_result": "",
|
||||||
|
"reason": "Test marked as a manual test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total_pass": 0,
|
||||||
|
"total_fail": 0,
|
||||||
|
"total_warn": 3,
|
||||||
|
"total_info": 0
|
||||||
|
}
|
||||||
|
]
|
30
integration/testdata/cis-1.5/job.data
vendored
30
integration/testdata/cis-1.5/job.data
vendored
@ -186,6 +186,21 @@ on the master node and set the below parameter.
|
|||||||
13 checks FAIL
|
13 checks FAIL
|
||||||
11 checks WARN
|
11 checks WARN
|
||||||
0 checks INFO
|
0 checks INFO
|
||||||
|
[INFO] 2 Etcd Node Configuration
|
||||||
|
[INFO] 2 Etcd Node Configuration Files
|
||||||
|
[PASS] 2.1 Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)
|
||||||
|
[PASS] 2.2 Ensure that the --client-cert-auth argument is set to true (Scored)
|
||||||
|
[PASS] 2.3 Ensure that the --auto-tls argument is not set to true (Scored)
|
||||||
|
[PASS] 2.4 Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Scored)
|
||||||
|
[PASS] 2.5 Ensure that the --peer-client-cert-auth argument is set to true (Scored)
|
||||||
|
[PASS] 2.6 Ensure that the --peer-auto-tls argument is not set to true (Scored)
|
||||||
|
[PASS] 2.7 Ensure that a unique Certificate Authority is used for etcd (Not Scored)
|
||||||
|
|
||||||
|
== Summary ==
|
||||||
|
7 checks PASS
|
||||||
|
0 checks FAIL
|
||||||
|
0 checks WARN
|
||||||
|
0 checks INFO
|
||||||
[INFO] 3 Control Plane Configuration
|
[INFO] 3 Control Plane Configuration
|
||||||
[INFO] 3.1 Authentication and Authorization
|
[INFO] 3.1 Authentication and Authorization
|
||||||
[WARN] 3.1.1 Client certificate authentication should not be used for users (Not Scored)
|
[WARN] 3.1.1 Client certificate authentication should not be used for users (Not Scored)
|
||||||
@ -208,21 +223,6 @@ minimum.
|
|||||||
0 checks FAIL
|
0 checks FAIL
|
||||||
3 checks WARN
|
3 checks WARN
|
||||||
0 checks INFO
|
0 checks INFO
|
||||||
[INFO] 2 Etcd Node Configuration
|
|
||||||
[INFO] 2 Etcd Node Configuration Files
|
|
||||||
[PASS] 2.1 Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)
|
|
||||||
[PASS] 2.2 Ensure that the --client-cert-auth argument is set to true (Scored)
|
|
||||||
[PASS] 2.3 Ensure that the --auto-tls argument is not set to true (Scored)
|
|
||||||
[PASS] 2.4 Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Scored)
|
|
||||||
[PASS] 2.5 Ensure that the --peer-client-cert-auth argument is set to true (Scored)
|
|
||||||
[PASS] 2.6 Ensure that the --peer-auto-tls argument is not set to true (Scored)
|
|
||||||
[PASS] 2.7 Ensure that a unique Certificate Authority is used for etcd (Not Scored)
|
|
||||||
|
|
||||||
== Summary ==
|
|
||||||
7 checks PASS
|
|
||||||
0 checks FAIL
|
|
||||||
0 checks WARN
|
|
||||||
0 checks INFO
|
|
||||||
[INFO] 4 Worker Node Security Configuration
|
[INFO] 4 Worker Node Security Configuration
|
||||||
[INFO] 4.1 Worker Node Configuration Files
|
[INFO] 4.1 Worker Node Configuration Files
|
||||||
[PASS] 4.1.1 Ensure that the kubelet service file permissions are set to 644 or more restrictive (Scored)
|
[PASS] 4.1.1 Ensure that the kubelet service file permissions are set to 644 or more restrictive (Scored)
|
||||||
|
Loading…
Reference in New Issue
Block a user