diff --git a/README.md b/README.md index 50ff8d3d..16e7a635 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ Kubescape is a K8s open-source tool providing a multi-cloud K8s single pane of glass, including risk analysis, security compliance, RBAC visualizer and image vulnerabilities scanning. -Kubescape scans K8s clusters, YAML files, and HELM charts, detecting misconfigurations according to multiple frameworks (such as the [NSA-CISA](https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo) , [MITRE ATT&CK®](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/)), software vulnerabilities, and RBAC (role-based-access-control) violations at early stages of the CI/CD pipeline, calculates risk score instantly and shows risk trends over time. +Kubescape scans K8s clusters, YAML files, and HELM charts, detecting misconfigurations according to multiple frameworks (such as the [NSA-CISA](https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo&utm_source=github&utm_medium=repository +) , [MITRE ATT&CK®](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/)), software vulnerabilities, and RBAC (role-based-access-control) violations at early stages of the CI/CD pipeline, calculates risk score instantly and shows risk trends over time. It became one of the fastest-growing Kubernetes tools among developers due to its easy-to-use CLI interface, flexible output formats, and automated scanning capabilities, saving Kubernetes users and admins’ precious time, effort, and resources. Kubescape integrates natively with other DevOps tools, including Jenkins, CircleCI, Github workflows, Prometheus, and Slack, and supports multi-cloud K8s deployments like EKS, GKE, and AKS. @@ -66,7 +67,7 @@ Want to contribute? Want to discuss something? Have an issue? * Feel free to pick a task from the [roadmap](docs/roadmap.md) or suggest a feature of your own. [Contact us](MAINTAINERS.md) directly for more information :) * Open a issue, we are trying to respond within 48 hours -* [Join us](https://armosec.github.io/kubescape/) in a discussion on our discord server! +* [Join us](https://armosec.github.io/kubescape) in a discussion on our discord server! [logo](https://armosec.github.io/kubescape/) ![discord](https://img.shields.io/discord/893048809884643379) @@ -74,7 +75,7 @@ Want to contribute? Want to discuss something? Have an issue? # Options and examples -[Kubescape docs](https://hub.armosec.io/docs) +[Kubescape docs](https://hub.armosec.io/docs?utm_source=github&utm_medium=repository) ## Playground * [Kubescape playground](https://killercoda.com/saiyampathak/scenario/kubescape) @@ -89,6 +90,8 @@ Want to contribute? Want to discuss something? Have an issue? * [Configure and run customized frameworks](https://youtu.be/12Sanq_rEhs) * Customize controls configurations. [Kubescape CLI](https://youtu.be/955psg6TVu4), [Kubescape SaaS](https://youtu.be/lIMVSVhH33o) +
Windows + ## Install on Windows **Requires powershell v5.0+** @@ -102,6 +105,9 @@ Note: if you get an error you might need to change the execution policy (i.e. en ``` powershell Set-ExecutionPolicy RemoteSigned -scope CurrentUser ``` +
+ +
MacOS ## Install on macOS @@ -111,6 +117,9 @@ Set-ExecutionPolicy RemoteSigned -scope CurrentUser 2. ```sh brew install kubescape ``` +
+ +
Nix/NixOS ## Install on NixOS or with nix (Community) @@ -144,32 +153,33 @@ home-manager: Or to your profile (not preferred): `nix-env --install -A nixpkgs.kubescape` +
## Usage & Examples ### Examples -#### Scan a running Kubernetes cluster and submit results to the [Kubescape SaaS version](https://portal.armo.cloud/) +#### Scan a running Kubernetes cluster and submit results to the [Kubescape SaaS version](https://cloud.armosec.io?utm_source=github&utm_medium=repository) ``` kubescape scan --submit --enable-host-scan --verbose ``` -> Read [here](https://hub.armosec.io/docs/host-sensor) more about the `enable-host-scan` flag +> Read [here](https://hub.armosec.io/docs/host-sensor?utm_source=github&utm_medium=repository) more about the `enable-host-scan` flag -#### Scan a running Kubernetes cluster with [`nsa`](https://www.nsa.gov/Press-Room/News-Highlights/Article/Article/2716980/nsa-cisa-release-kubernetes-hardening-guidance/) framework and submit results to the [Kubescape SaaS version](https://portal.armo.cloud/) +#### Scan a running Kubernetes cluster with [`nsa`](https://www.nsa.gov/Press-Room/News-Highlights/Article/Article/2716980/nsa-cisa-release-kubernetes-hardening-guidance/) framework and submit results to the [Kubescape SaaS version](https://cloud.armosec.io?utm_source=github&utm_medium=repository) ``` kubescape scan framework nsa --submit ``` -#### Scan a running Kubernetes cluster with [`MITRE ATT&CK®`](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/) framework and submit results to the [Kubescape SaaS version](https://portal.armo.cloud/) +#### Scan a running Kubernetes cluster with [`MITRE ATT&CK®`](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/) framework and submit results to the [Kubescape SaaS version](https://cloud.armosec.io?utm_source=github&utm_medium=repository) ``` kubescape scan framework mitre --submit ``` -#### Scan a running Kubernetes cluster with a specific control using the control name or control ID. [List of controls](https://hub.armosec.io/docs/controls) +#### Scan a running Kubernetes cluster with a specific control using the control name or control ID. [List of controls](https://hub.armosec.io/docs/controls?utm_source=github&utm_medium=repository) ``` kubescape scan control "Privileged container" ``` @@ -184,12 +194,12 @@ kubescape scan --include-namespaces development,staging,production kubescape scan --exclude-namespaces kube-system,kube-public ``` -#### Scan local `yaml`/`json` files before deploying. [Take a look at the demonstration](https://youtu.be/Ox6DaR7_4ZI) Submit the results in case the directory is a git repo. [docs](https://hub.armosec.io/docs/repository-scanning) +#### Scan local `yaml`/`json` files before deploying. [Take a look at the demonstration](https://youtu.be/Ox6DaR7_4ZI) Submit the results in case the directory is a git repo. [docs](https://hub.armosec.io/docs/repository-scanning?utm_source=github&utm_medium=repository) ``` kubescape scan *.yaml --submit ``` -#### Scan kubernetes manifest files from a git repository [and submit the results](https://hub.armosec.io/docs/repository-scanning) +#### Scan kubernetes manifest files from a git repository [and submit the results](https://hub.armosec.io/docs/repository-scanning?utm_source=github&utm_medium=repository) ``` kubescape scan https://github.com/armosec/kubescape --submit ``` @@ -270,35 +280,10 @@ kubescape scan framework nsa --use-from /path/nsa.json ``` -## Scan Periodically using Helm - Contributed by [@yonahd](https://github.com/yonahd) -[Please follow the instructions here](https://hub.armosec.io/docs/installation-of-armo-in-cluster) +## Scan Periodically using Helm +[Please follow the instructions here](https://hub.armosec.io/docs/installation-of-armo-in-cluster?utm_source=github&utm_medium=repository) [helm chart repo](https://github.com/armosec/armo-helm) -## Scan using docker image - -Official Docker image `quay.io/armosec/kubescape` - -``` -docker run -v "$(pwd)/example.yaml:/app/example.yaml quay.io/armosec/kubescape scan /app/example.yaml -``` - -If you wish, you can [build the docker image on your own](build/README.md) - -# Submit data manually - -Use the `submit` command if you wish to submit data manually - -## Submit scan results manually - -> Support forward compatibility by using the `--format-version v2` flag - -First, scan your cluster using the `json` format flag: `kubescape scan framework --format json --format-version v2 --output path/to/results.json`. - -Now you can submit the results to the Kubescape SaaS version - -``` -kubescape submit results path/to/results.json -``` - # Integrations ## VS Code Extension @@ -314,13 +299,15 @@ View Kubescape scan results directly in [Lens IDE](https://k8slens.dev/) using k # Building Kubescape +
Windows + ## Windows 1. Install MSYS2 & build libgit _(needed only for the first time)_ -``` -build.bat all -``` + ``` + build.bat all + ``` > You can install MSYS2 separately by running `build.bat install` and build libgit2 separately by running `build.bat build` @@ -335,11 +322,14 @@ build.bat all ``` go build -tags=static . ``` +
-## Linux / macOS +
Linux / MacOS + +## Linux / MacOS 1. Install libgit2 dependency _(needed only for the first time)_ - + ``` make libgit2 ``` @@ -364,11 +354,15 @@ build.bat all make test ``` +
+ ## VS code configuration samples You can use the samples files below to setup your VS code environment for building and debugging purposes. +
.vscode/settings.json + ```json5 // .vscode/settings.json { @@ -379,6 +373,9 @@ You can use the samples files below to setup your VS code environment for buildi } } ``` +
+ +
.vscode/launch.json ```json5 // .vscode/launch.json @@ -401,13 +398,14 @@ You can use the samples files below to setup your VS code environment for buildi ] } ``` +
# Under the hood ## Technology Kubescape based on OPA engine: https://github.com/open-policy-agent/opa and ARMO's posture controls. -The tools retrieves Kubernetes objects from the API server and runs a set of [rego's snippets](https://www.openpolicyagent.org/docs/latest/policy-language/) developed by [ARMO](https://www.armosec.io/). +The tools retrieves Kubernetes objects from the API server and runs a set of [rego's snippets](https://www.openpolicyagent.org/docs/latest/policy-language/) developed by [ARMO](https://www.armosec.io?utm_source=github&utm_medium=repository). The results by default printed in a pretty "console friendly" manner, but they can be retrieved in JSON format for further processing. diff --git a/core/pkg/registryadaptors/README.md b/core/pkg/registryadaptors/README.md index ea5ea4d3..d07509e2 100644 --- a/core/pkg/registryadaptors/README.md +++ b/core/pkg/registryadaptors/README.md @@ -7,7 +7,7 @@ For these controls to work properly, it is necessary to # Integrate With Armosec Server -1. Navigate to the [armosec.io](https://portal.armo.cloud/) +1. Navigate to the [armosec.io](https://cloud.armosec.io?utm_source=github&utm_medium=repository) 2. Click Profile(top right icon)->"User Management"->"API Tokens" and Generate a token 3. Copy the clientID and secretKey and run: ``` diff --git a/core/pkg/resourcehandler/k8sresources.go b/core/pkg/resourcehandler/k8sresources.go index ee8c0e7c..75fa55f8 100644 --- a/core/pkg/resourcehandler/k8sresources.go +++ b/core/pkg/resourcehandler/k8sresources.go @@ -86,7 +86,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(sessionObj *cautils.OPASessio if len(imgVulnResources) > 0 { if err := k8sHandler.registryAdaptors.collectImagesVulnerabilities(k8sResourcesMap, allResources, armoResourceMap); err != nil { logger.L().Warning("failed to collect image vulnerabilities", helpers.Error(err)) - cautils.SetInfoMapForResources(fmt.Sprintf("failed to pull image scanning data: %s", err.Error()), imgVulnResources, sessionObj.InfoMap) + cautils.SetInfoMapForResources(fmt.Sprintf("failed to pull image scanning data: %s. for more information: https://hub.armosec.io/docs/configuration-of-image-vulnerabilities", err.Error()), imgVulnResources, sessionObj.InfoMap) } else { if isEmptyImgVulns(*armoResourceMap) { cautils.SetInfoMapForResources("image scanning is not configured. for more information: https://hub.armosec.io/docs/configuration-of-image-vulnerabilities", imgVulnResources, sessionObj.InfoMap) diff --git a/core/pkg/resourcehandler/registrydata.go b/core/pkg/resourcehandler/registrydata.go index 20f452b0..847e2ea4 100644 --- a/core/pkg/resourcehandler/registrydata.go +++ b/core/pkg/resourcehandler/registrydata.go @@ -38,6 +38,16 @@ func NewRegistryAdaptors() (*RegistryAdaptors, error) { func (registryAdaptors *RegistryAdaptors) collectImagesVulnerabilities(k8sResourcesMap *cautils.K8SResources, allResources map[string]workloadinterface.IMetadata, armoResourceMap *cautils.ArmoResources) error { logger.L().Debug("Collecting images vulnerabilities") + if len(registryAdaptors.adaptors) == 0 { + return fmt.Errorf("credentials are not configured for any registry adaptor") + } + + for i := range registryAdaptors.adaptors { // login and and get vulnerabilities + if err := registryAdaptors.adaptors[i].Login(); err != nil { + return fmt.Errorf("failed to login, adaptor: '%s', reason: '%s'", registryAdaptors.adaptors[i].DescribeAdaptor(), err.Error()) + } + } + // list cluster images images := listImagesTags(k8sResourcesMap, allResources) imagesIdentifiers := imageTagsToContainerImageIdentifier(images) @@ -45,11 +55,6 @@ func (registryAdaptors *RegistryAdaptors) collectImagesVulnerabilities(k8sResour imagesVulnerability := map[string][]registryvulnerabilities.Vulnerability{} for i := range registryAdaptors.adaptors { // login and and get vulnerabilities - if err := registryAdaptors.adaptors[i].Login(); err != nil { - if err != nil { - return fmt.Errorf("failed to login, adaptor: '%s', reason: '%s'", registryAdaptors.adaptors[i].DescribeAdaptor(), err.Error()) - } - } vulnerabilities, err := registryAdaptors.adaptors[i].GetImagesVulnerabilities(imagesIdentifiers) if err != nil { return err diff --git a/httphandler/Makefile b/httphandler/Makefile new file mode 100644 index 00000000..1fd42de0 --- /dev/null +++ b/httphandler/Makefile @@ -0,0 +1,20 @@ +.PHONY: test all build libgit2 + +# default task invoked while running make +all: libgit2 build + +export CGO_ENABLED=1 + +# build and install libgit2 +libgit2: + git submodule update --init --recursive + cd git2go; make install-static + +# go build tags +TAGS = "static" + +build: + go build -v -tags=$(TAGS) . + +test: + go test -v -tags=$(TAGS) ./... diff --git a/httphandler/README.md b/httphandler/README.md index 18fc0871..28201936 100644 --- a/httphandler/README.md +++ b/httphandler/README.md @@ -1,6 +1,6 @@ # Kubescape HTTP Handler Package -Running `kubescape` will start up a webserver on port `8080` which will serve the following API's: +Running `kubescape` will start up a web-server on port `8080` which will serve the following API's: ### Trigger scan @@ -153,6 +153,15 @@ curl --header "Content-Type: application/json" \ http://127.0.0.1:8080/v1/scan ``` +#### Data profiling +Analyze profiled data using [pprof](https://github.com/google/pprof/blob/main/doc/README.md). +[How ro use](https://pkg.go.dev/net/http/pprof) + +example: +```bash +go tool pprof http://localhost:6060/debug/pprof/heap +``` + ## Examples * [Prometheus](examples/prometheus/README.md) @@ -169,3 +178,5 @@ curl --header "Content-Type: application/json" \ * `KS_FORMAT`: Output file format. default is json * `KS_ENABLE_HOST_SCANNER`: Enable the host scanner feature * `KS_DOWNLOAD_ARTIFACTS`: Download the artifacts every scan +* `KS_LOGGER_NAME`: Set logger name +* `KS_LOGGER_LEVEL`: Set logger level diff --git a/httphandler/handlerequests/v1/requestshandler.go b/httphandler/handlerequests/v1/requestshandler.go index f4689306..49b2d7ee 100644 --- a/httphandler/handlerequests/v1/requestshandler.go +++ b/httphandler/handlerequests/v1/requestshandler.go @@ -3,6 +3,7 @@ package v1 import ( "fmt" "net/http" + _ "net/http/pprof" utilsapisv1 "github.com/armosec/opa-utils/httpserver/apis/v1" utilsmetav1 "github.com/armosec/opa-utils/httpserver/meta/v1" diff --git a/httphandler/listener/init.go b/httphandler/listener/init.go index 0cea1e08..5b1d2bad 100644 --- a/httphandler/listener/init.go +++ b/httphandler/listener/init.go @@ -5,16 +5,39 @@ import ( "github.com/armosec/kubescape/v2/core/cautils/getter" logger "github.com/dwertent/go-logger" + "github.com/dwertent/go-logger/helpers" "github.com/dwertent/go-logger/zaplogger" ) func initialize() error { - logger.InitLogger(zaplogger.LoggerName) - + initializeLoggerName() + initializeLoggerLevel() initializeSaaSEnv() return nil } +// initialize logger name +func initializeLoggerName() { + loggerName := zaplogger.LoggerName + if l := os.Getenv("KS_LOGGER_NAME"); l != "" { + loggerName = l + } + logger.InitLogger(loggerName) +} + +// initialize logger level +func initializeLoggerLevel() { + loggerLevel := helpers.DebugLevel.String() + if l := os.Getenv("KS_LOGGER_LEVEL"); l != "" { + loggerLevel = l + } + if err := logger.L().SetLevel(loggerLevel); err != nil { + logger.L().SetLevel(helpers.DebugLevel.String()) + logger.L().Error("failed to set logger level", helpers.String("level", loggerLevel), helpers.Error(err), helpers.String("default", helpers.DebugLevel.String())) + } +} + +// SetupHTTPListener set up listening http servers func initializeSaaSEnv() { saasEnv := os.Getenv("KS_SAAS_ENV") diff --git a/httphandler/listener/setup.go b/httphandler/listener/setup.go index 06002108..2d98153f 100644 --- a/httphandler/listener/setup.go +++ b/httphandler/listener/setup.go @@ -59,7 +59,9 @@ func SetupHTTPListener() error { server.Handler = rtr logger.L().Info("Started Kubescape server", helpers.String("port", getPort()), helpers.String("version", cautils.BuildNumber)) - server.ListenAndServe() + + servePprof() + if keyPair != nil { return server.ListenAndServeTLS("", "") } @@ -84,3 +86,13 @@ func getPort() string { } return "8080" } + +func servePprof() { + go func() { + // start pprof server -> https://pkg.go.dev/net/http/pprof + if logger.L().GetLevel() == helpers.DebugLevel.String() { + logger.L().Info("starting pprof server", helpers.String("port", "6060")) + logger.L().Error(http.ListenAndServe(":6060", nil).Error()) + } + }() +}