Skip to content

Commit

Permalink
Merge branch 'master' into fix-typo
Browse files Browse the repository at this point in the history
  • Loading branch information
ttousai committed May 15, 2018
2 parents aa9da13 + c136323 commit b10b2bd
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 58 deletions.
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
---
language: go

sudo: required

services:
- docker

notifications:
email: false

Expand All @@ -16,6 +21,10 @@ install:

script:
- go test ./...
- docker build --tag kube-bench .
- docker run -v `pwd`:/host kube-bench install
- test -d cfg
- test -f kube-bench

after_success:
- test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash
Expand Down
27 changes: 18 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
FROM golang:1.9
WORKDIR /kube-bench
RUN go get github.com/aquasecurity/kube-bench
FROM golang:1.9 AS build
WORKDIR /go/src/github.com/aquasecurity/kube-bench/
ADD glide.lock glide.yaml ./
RUN go get github.com/Masterminds/glide && glide install
ADD main.go .
ADD check/ check/
ADD cmd/ cmd/
RUN CGO_ENABLED=0 go install -a -ldflags '-w'

FROM alpine:latest
WORKDIR /
COPY --from=0 /go/bin/kube-bench /kube-bench
COPY --from=0 /go/src/github.com/aquasecurity/kube-bench/cfg /cfg
COPY --from=0 /go/src/github.com/aquasecurity/kube-bench/entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
FROM alpine:3.7 AS run
WORKDIR /opt/kube-bench/
# add GNU ps for -C, -o cmd, and --no-headers support
# https://github.com/aquasecurity/kube-bench/issues/109
RUN apk --no-cache add procps
COPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench
ADD entrypoint.sh .
ADD cfg/ cfg/
ENTRYPOINT ["./entrypoint.sh"]
CMD ["install"]

# Build-time metadata as defined at http://label-schema.org
ARG BUILD_DATE
Expand Down
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
[![Docker image](https://images.microbadger.com/badges/image/aquasec/kube-bench.svg)](https://microbadger.com/images/aquasec/kube-bench "Get your own image badge on microbadger.com")
[![Source commit](https://images.microbadger.com/badges/commit/aquasec/kube-bench.svg)](https://microbadger.com/images/aquasec/kube-bench)

# kube-bench
<img src="images/kube-bench.png" width="200" alt="kube-bench logo">

The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark.
kube-bench is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark.

Tests are configured with YAML files, making this tool easy to update as test specifications evolve.

Expand All @@ -17,12 +17,37 @@ kube-bench supports the tests for multiple versions of Kubernetes (1.6, 1.7 and

## Installation

You can either install kube-bench through a dedicated container, or compile it from source:
You can choose to
* run kube-bench from inside a container (sharing PID namespace with the host)
* run a container that installs kube-bench on the host, and then run kube-bench directly on the host
* install the latest binaries from the [Releases page](https://github.com/aquasecurity/kube-bench/releases),
* compile it from source.

1. Container installation:
Run ```docker run --rm -v `pwd`:/host aquasec/kube-bench:latest```. This will copy the kube-bench binary and configuration to you host. You can then run ```./kube-bench <master|node>```.
### Running inside a container

You can avoid installing kube-bench on the host by running it inside a container using the host PID namespace.

```
docker run --pid=host aquasec/kube-bench:latest <master|node>
```

You can even use your own configs by mounting them over the default ones in `/opt/kube-bench/cfg/`

```
docker run --pid=host -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yaml aquasec/kube-bench:latest <master|node>
```

### Installing from a container

This command copies the kube-bench binary and configuration files to your host from the Docker container:
```
docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
```

You can then run `./kube-bench <master|node>`.

### Installing from sources

2. Install from sources:
If Go is installed on the target machines, you can simply clone this repository and run as follows (assuming your [$GOPATH is set](https://github.com/golang/go/wiki/GOPATH)):

```go get github.com/aquasecurity/kube-bench
Expand Down
2 changes: 1 addition & 1 deletion cfg/1.8/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ groups:
remediation: |
Edit the API server pod specification file $apiserverconf
and set the below parameter as appropriate and if needed. For example,
--request-timeout=300
--request-timeout=300s
scored: true

- id: 1.2
Expand Down
67 changes: 40 additions & 27 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ func runChecks(t check.NodeType) {
nodetype = "federated"
}

ver := getKubeVersion()
var ver string
if kubeVersion != "" {
ver = kubeVersion
} else {
ver = getKubeVersion()
}

switch ver {
case "1.9", "1.10":
continueWithError(nil, fmt.Sprintf("No CIS spec for %s - using tests from CIS 1.2.0 spec for Kubernetes 1.8\n", ver))
Expand Down Expand Up @@ -131,41 +137,48 @@ func colorPrint(state check.State, s string) {

// prettyPrint outputs the results to stdout in human-readable format
func prettyPrint(r *check.Controls, summary check.Summary) {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", r.ID, r.Text))
for _, g := range r.Groups {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text))
for _, c := range g.Checks {
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
// Print check results.
if !noResults {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", r.ID, r.Text))
for _, g := range r.Groups {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text))
for _, c := range g.Checks {
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
}
}
}

fmt.Println()
fmt.Println()
}

// Print remediations.
if summary.Fail > 0 || summary.Warn > 0 {
colors[check.WARN].Printf("== Remediations ==\n")
for _, g := range r.Groups {
for _, c := range g.Checks {
if c.State != check.PASS {
fmt.Printf("%s %s\n", c.ID, c.Remediation)
if !noRemediations {
if summary.Fail > 0 || summary.Warn > 0 {
colors[check.WARN].Printf("== Remediations ==\n")
for _, g := range r.Groups {
for _, c := range g.Checks {
if c.State != check.PASS {
fmt.Printf("%s %s\n", c.ID, c.Remediation)
}
}
}
fmt.Println()
}
fmt.Println()
}

// Print summary setting output color to highest severity.
var res check.State
if summary.Fail > 0 {
res = check.FAIL
} else if summary.Warn > 0 {
res = check.WARN
} else {
res = check.PASS
}
if !noSummary {
var res check.State
if summary.Fail > 0 {
res = check.FAIL
} else if summary.Warn > 0 {
res = check.WARN
} else {
res = check.PASS
}

colors[res].Printf("== Summary ==\n")
fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n",
summary.Pass, summary.Fail, summary.Warn,
)
colors[res].Printf("== Summary ==\n")
fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n",
summary.Pass, summary.Fail, summary.Warn,
)
}
}
13 changes: 12 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ import (

var (
envVarsPrefix = "KUBE_BENCH"
cfgDir = "./cfg"
defaultKubeVersion = "1.6"
kubeVersion string
cfgFile string
cfgDir string
jsonFmt bool
pgSQL bool
checkList string
groupList string
masterFile string
nodeFile string
federatedFile string
noResults bool
noSummary bool
noRemediations bool
)

// RootCmd represents the base command when called without any subcommands
Expand All @@ -60,8 +64,13 @@ func Execute() {
func init() {
cobra.OnInitialize(initConfig)

// Output control
RootCmd.PersistentFlags().BoolVar(&noResults, "noresults", false, "Disable prints of results section")
RootCmd.PersistentFlags().BoolVar(&noSummary, "nosummary", false, "Disable printing of summary section")
RootCmd.PersistentFlags().BoolVar(&noRemediations, "noremediations", false, "Disable printing of remediations section")
RootCmd.PersistentFlags().BoolVar(&jsonFmt, "json", false, "Prints the results as JSON")
RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL")

RootCmd.PersistentFlags().StringVarP(
&checkList,
"check",
Expand All @@ -77,6 +86,8 @@ func init() {
`Run all the checks under this comma-delimited list of groups. Example --group="1.1"`,
)
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./cfg/config.yaml)")
RootCmd.PersistentFlags().StringVarP(&cfgDir, "config-dir", "D", "./cfg/", "config directory")
RootCmd.PersistentFlags().StringVar(&kubeVersion, "version", "", "Manually specify Kubernetes version, automatically detected if unset")

goflag.CommandLine.VisitAll(func(goflag *goflag.Flag) {
RootCmd.PersistentFlags().AddGoFlag(goflag)
Expand Down
4 changes: 2 additions & 2 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func getKubeVersion() string {
if err != nil {
_, err = exec.LookPath("kubelet")
if err != nil {
exitWithError(fmt.Errorf("Version check failed: need kubectl or kubelet binaries to get kubernetes version"))
exitWithError(fmt.Errorf("Version check failed: need kubectl or kubelet binaries to get kubernetes version.\nAlternately, you can specify the version with --version"))
}
return getKubeVersionFromKubelet()
}
Expand All @@ -240,7 +240,7 @@ func getKubeVersionFromKubectl() string {
func getKubeVersionFromKubelet() string {
cmd := exec.Command("kubelet", "--version")
out, err := cmd.CombinedOutput()

if err != nil {
continueWithError(fmt.Errorf("%s", out), "")
}
Expand Down
29 changes: 17 additions & 12 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#!/bin/sh
if [ -d /host ]; then
mkdir -p /host/cfg/
yes | cp -rf /cfg/* /host/cfg/
yes | cp -rf /kube-bench /host/
echo "==============================================="
echo "kube-bench is now installed on your host "
echo "Run ./kube-bench to perform a security check "
echo "==============================================="
#!/bin/sh -e
if [ "$1" == "install" ]; then
if [ -d /host ]; then
mkdir -p /host/cfg/
yes | cp -rf cfg/* /host/cfg/
yes | cp -rf /usr/local/bin/kube-bench /host/
echo "==============================================="
echo "kube-bench is now installed on your host "
echo "Run ./kube-bench to perform a security check "
echo "==============================================="
else
echo "Usage:"
echo " install: docker run --rm -v \`pwd\`:/host aquasec/kube-bench install"
echo " run: docker run --rm --pid=host aquasec/kube-bench [command]"
exit
fi
else
echo "Usage:"
echo " docker run --rm -v \`pwd\`:/host aquasec/kube-bench"
exit
exec kube-bench "$@"
fi
Empty file modified hooks/build
100644 → 100755
Empty file.
Binary file added images/kube-bench.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b10b2bd

Please sign in to comment.