Compare commits

...

6 Commits

Author SHA1 Message Date
David Wertenteil
6be692c66f Merge pull request #4 from Daniel-GrunbergerCA/master
add exclude-namespaces flag
2021-08-18 11:56:43 +03:00
danielgrunbergerarmo
3c062238ad add cli flag 2021-08-18 11:48:10 +03:00
Daniel Grunberger
954224e9f6 Update README.md 2021-08-17 17:39:50 +03:00
David Wertenteil
a5f99e0a8d Merge pull request #3 from dwertent/master
Update description display
2021-08-17 16:27:53 +03:00
dwertent
d484aeb62c update description 2021-08-17 16:24:23 +03:00
Daniel Grunberger
8c3eeab7ed Update README.md 2021-08-17 13:37:24 +03:00
9 changed files with 45 additions and 22 deletions

View File

@@ -34,17 +34,14 @@ To get a fast check of the security posture of your Kubernetes cluster, run this
Kubescape is running the following tests according to what is defined by [Kubernetes Hardening Guidance by to NSA and CISA](https://www.nsa.gov/News-Features/Feature-Stories/Article-View/Article/2716980/nsa-cisa-release-kubernetes-hardening-guidance/)
* Non-root containers
* Immutable container filesystem
* Building secure container images
* Privileged containers
* hostPID, hostIPC privileges
* hostNetwork access
* allowedHostPaths field
* Protecting pod service account tokens
* Pods in kube-system and kube-public
* Resource policies
* Control plane hardening
* Encrypted secrets
* Anonymous Requests
* Exposed dashboard
## Technology

View File

@@ -42,11 +42,11 @@ type ControlReport struct {
Description string `json:"description"`
}
type RuleReport struct {
Name string `json:"name"`
Remediation string `json:"remediation"`
RuleStatus RuleStatus `json:"ruleStatus"`
RuleResponses []RuleResponse `json:"ruleResponses"`
NumOfResources int
Name string `json:"name"`
Remediation string `json:"remediation"`
RuleStatus RuleStatus `json:"ruleStatus"`
RuleResponses []RuleResponse `json:"ruleResponses"`
ListInputResources []map[string]interface{} `json:"-"`
}
type RuleStatus struct {
Status string `json:"status"`

View File

@@ -70,7 +70,10 @@ func ParseRegoResult(regoResult *rego.ResultSet) ([]RuleResponse, error) {
func (controlReport *ControlReport) GetNumberOfResources() int {
sum := 0
for i := range controlReport.RuleReports {
sum += controlReport.RuleReports[i].NumOfResources
if controlReport.RuleReports[i].ListInputResources == nil {
continue
}
sum += len(controlReport.RuleReports[i].ListInputResources)
}
return sum
}

View File

@@ -45,7 +45,7 @@ func (flagHandler *FlagHandler) Help() {
}
func (flagHandler *FlagHandler) Version() {
fmt.Println("bla.bla.bla")
fmt.Println("")
}
func (flagHandler *FlagHandler) Scan() {

View File

@@ -87,7 +87,7 @@ func (opap *OPAProcessor) ProcessRulesHandler(opaSessionObj *cautils.OPASessionO
} else {
ruleReport.RuleStatus.Status = "success"
}
ruleReport.NumOfResources = len(k8sObjects)
ruleReport.ListInputResources = k8sObjects
ruleReports = append(ruleReports, ruleReport)
}
controlReport.RuleReports = ruleReports

View File

@@ -1,6 +1,7 @@
package policyhandler
import (
"flag"
"fmt"
"kube-escape/cautils"
@@ -52,7 +53,11 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opap
// get k8s resources
cautils.ProgressTextDisplay("Accessing Kubernetes objects")
glog.Infof(fmt.Sprintf("Getting kubernetes objects. reportID: %s", notification.ReportID))
k8sResources, err := policyHandler.getK8sResources(frameworks, &notification.Designators)
excludedNamespaces := ""
if flag.Arg(3) == "--exclude-namespaces" {
excludedNamespaces = flag.Arg(4)
}
k8sResources, err := policyHandler.getK8sResources(frameworks, &notification.Designators, excludedNamespaces)
if err != nil || len(*k8sResources) == 0 {
glog.Error(err)
} else {

View File

@@ -3,6 +3,7 @@ package policyhandler
import (
"fmt"
"kube-escape/cautils"
"strings"
"kube-escape/cautils/k8sinterface"
@@ -18,7 +19,7 @@ import (
const SelectAllResources = "*"
func (policyHandler *PolicyHandler) getK8sResources(frameworks []opapolicy.Framework, designator *armotypes.PortalDesignator) (*cautils.K8SResources, error) {
func (policyHandler *PolicyHandler) getK8sResources(frameworks []opapolicy.Framework, designator *armotypes.PortalDesignator, excludedNamespaces string) (*cautils.K8SResources, error) {
// build resources map
k8sResourcesMap := setResourceMap(frameworks)
@@ -26,20 +27,20 @@ func (policyHandler *PolicyHandler) getK8sResources(frameworks []opapolicy.Frame
_, namespace, labels := armotypes.DigestPortalDesignator(designator)
// pull k8s recourses
if err := policyHandler.pullResources(k8sResourcesMap, namespace, labels); err != nil {
if err := policyHandler.pullResources(k8sResourcesMap, namespace, labels, excludedNamespaces); err != nil {
return k8sResourcesMap, err
}
return k8sResourcesMap, nil
}
func (policyHandler *PolicyHandler) pullResources(k8sResources *cautils.K8SResources, namespace string, labels map[string]string) error {
func (policyHandler *PolicyHandler) pullResources(k8sResources *cautils.K8SResources, namespace string, labels map[string]string, excludedNamespaces string) error {
var errs error
for groupResource := range *k8sResources {
apiGroup, apiVersion, resource := k8sinterface.StringToResourceGroup(groupResource)
gvr := schema.GroupVersionResource{Group: apiGroup, Version: apiVersion, Resource: resource}
result, err := policyHandler.pullSingleResource(&gvr, namespace, labels)
result, err := policyHandler.pullSingleResource(&gvr, namespace, labels, excludedNamespaces)
if err != nil {
// handle error
if errs == nil {
@@ -55,10 +56,16 @@ func (policyHandler *PolicyHandler) pullResources(k8sResources *cautils.K8SResou
return errs
}
func (policyHandler *PolicyHandler) pullSingleResource(resource *schema.GroupVersionResource, namespace string, labels map[string]string) ([]unstructured.Unstructured, error) {
func (policyHandler *PolicyHandler) pullSingleResource(resource *schema.GroupVersionResource, namespace string, labels map[string]string, excludedNamespaces string) ([]unstructured.Unstructured, error) {
// set labels
listOptions := metav1.ListOptions{}
if excludedNamespaces != "" {
excludedNamespacesSlice := strings.Split(excludedNamespaces, ",")
for _, excludedNamespace := range excludedNamespacesSlice {
listOptions.FieldSelector += "metadata.namespace!=" + excludedNamespace + ","
}
}
if labels != nil && len(labels) > 0 {
set := k8slabels.Set(labels)
listOptions.LabelSelector = set.AsSelector().String()

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"kube-escape/cautils"
"os"
"strings"
"kube-escape/cautils/k8sinterface"
"kube-escape/cautils/opapolicy"
@@ -62,7 +61,7 @@ func (printer *Printer) SummerySetup(postureReport *opapolicy.PostureReport) {
TotalResources: cr.GetNumberOfResources(),
TotalFailed: len(workloadsSummery),
WorkloadSummery: mapResources,
Description: strings.ReplaceAll(cr.Description, ". ", fmt.Sprintf(".\n%s%s", INDENT, INDENT)),
Description: cr.Description,
}
}
}
@@ -72,9 +71,21 @@ func (printer *Printer) PrintResults() {
for control, controlSummery := range printer.summery {
printer.printTitle(control, &controlSummery)
printer.printResult(control, &controlSummery)
if controlSummery.TotalResources > 0 {
printer.printSummery(control, &controlSummery)
}
}
}
func (print *Printer) printSummery(controlName string, controlSummery *ControlSummery) {
cautils.SimpleDisplay(os.Stdout, "Summary - ")
cautils.SuccessDisplay(os.Stdout, "Passed:%v ", controlSummery.TotalResources-controlSummery.TotalFailed)
cautils.FailureDisplay(os.Stdout, "Failed:%v ", controlSummery.TotalFailed)
cautils.InfoDisplay(os.Stdout, "Total:%v\n", controlSummery.TotalResources)
}
func (printer *Printer) printTitle(controlName string, controlSummery *ControlSummery) {
cautils.InfoDisplay(os.Stdout, "[control: %s] ", controlName)
if controlSummery.TotalResources == 0 {
@@ -85,7 +96,7 @@ func (printer *Printer) printTitle(controlName string, controlSummery *ControlSu
cautils.FailureDisplay(os.Stdout, "failed %v\n", emoji.SadButRelievedFace)
}
cautils.SimpleDisplay(os.Stdout, "%sDescription: %s\n", INDENT, controlSummery.Description)
cautils.SimpleDisplay(os.Stdout, "Description: %s\n", controlSummery.Description)
}
func (printer *Printer) printResult(controlName string, controlSummery *ControlSummery) {

View File

@@ -14,7 +14,7 @@ type ControlSummery struct {
TotalResources int
TotalFailed int
Description string
WorkloadSummery map[string][]WorkloadSummery
WorkloadSummery map[string][]WorkloadSummery // <namespace>:[<WorkloadSummery>]
}
type WorkloadSummery struct {