1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2024-12-18 20:58:10 +00:00

Merge branch 'master' into fixBooleansComparaison-issue125

This commit is contained in:
Liz Rice 2018-05-15 11:42:21 +01:00 committed by GitHub
commit 97e5bc9b97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 313 additions and 81 deletions

View File

@ -9,10 +9,11 @@ builds:
# Archive customization
archive:
format: tar.gz
fpm:
nfpm:
vendor: Aqua Security
description: "The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed according to security best practices"
license: Apache-2.0
homepage: https://github.com/aquasecurity/kube-bench
formats:
- deb
- rpm

View File

@ -1,6 +1,11 @@
---
language: go
sudo: required
services:
- docker
notifications:
email: false
@ -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

View File

@ -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

View File

@ -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.
@ -17,12 +17,50 @@ 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>
```
### Running in a kubernetes cluster
Run the master check
```
kubectl run --rm -i -t kube-bench-master --image=aquasec/kube-bench:latest --restart=Never --overrides="{ \"apiVersion\": \"v1\", \"spec\": { \"hostPID\": true, \"nodeSelector\": { \"kubernetes.io/role\": \"master\" }, \"tolerations\": [ { \"key\": \"node-role.kubernetes.io/master\", \"operator\": \"Exists\", \"effect\": \"NoSchedule\" } ] } }" -- master --version 1.8
```
Run the node check
```
kubectl run --rm -i -t kube-bench-node --image=aquasec/kube-bench:latest --restart=Never --overrides="{ \"apiVersion\": \"v1\", \"spec\": { \"hostPID\": true } }" -- node --version 1.8
```
### 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
@ -30,25 +68,13 @@ go get github.com/Masterminds/glide
cd $GOPATH/src/github.com/aquasecurity/kube-bench
$GOPATH/bin/glide install
go build -o kube-bench .
./kube-bench <master|node>
```
## Usage
```./kube-bench [command]```
# See all supported options
./kube-bench --help
```
Available Commands:
federated Run benchmark checks for a Kubernetes federated deployment.
help Help about any command
master Run benchmark checks for a Kubernetes master node.
node Run benchmark checks for a Kubernetes node.
# Run the all checks on a master node
./kube-bench master
Flags:
-c, --check string A comma-delimited list of checks to run as specified in CIS document. Example --check="1.1.1,1.1.2"
--config string config file (default is ./cfg/config.yaml)
-g, --group string Run all the checks under this comma-delimited list of groups. Example --group="1.1"
--json Prints the results as JSON
-v, --verbose verbose output (default false)
```
## Configuration

View File

@ -418,7 +418,7 @@ groups:
- id: 1.1.26
text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as
appropriate (Scored"
appropriate (Scored)"
audit: "ps -ef | grep $apiserverbin | grep -v grep"
tests:
bin_op: and
@ -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
@ -666,7 +666,7 @@ groups:
scored: true
- id: 1.3.3
text: "Ensure that the --use-service-account-credentials argument is set"
text: "Ensure that the --use-service-account-credentials argument is set (Scored)"
audit: "ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:

View File

@ -17,6 +17,7 @@ package cmd
import (
"fmt"
"io/ioutil"
"path/filepath"
"github.com/aquasecurity/kube-bench/check"
"github.com/golang/glog"
@ -46,10 +47,22 @@ func runChecks(t check.NodeType) {
nodetype = "federated"
}
ver := getKubeVersion()
path := fmt.Sprintf("%s/%s", cfgDir, ver)
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))
ver = "1.8"
}
path := filepath.Join(cfgDir, ver)
def := filepath.Join(path, file)
def := fmt.Sprintf("%s/%s", path, file)
in, err := ioutil.ReadFile(def)
if err != nil {
exitWithError(fmt.Errorf("error opening %s controls file: %v", t, err))
@ -124,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))
}
}
fmt.Println()
// Print remediations.
if summary.Fail > 0 || summary.Warn > 0 {
colors[check.WARN].Printf("== Remediations ==\n")
// 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 {
if c.State != check.PASS {
fmt.Printf("%s %s\n", c.ID, c.Remediation)
}
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
}
}
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
// Print remediations.
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()
}
}
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,
)
// Print summary setting output color to highest severity.
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,
)
}
}

View File

@ -26,9 +26,10 @@ import (
var (
envVarsPrefix = "KUBE_BENCH"
cfgDir = "./cfg"
defaultKubeVersion = "1.6"
kubeVersion string
cfgFile string
cfgDir string
jsonFmt bool
pgSQL bool
checkList string
@ -36,13 +37,16 @@ var (
masterFile string
nodeFile string
federatedFile string
noResults bool
noSummary bool
noRemediations bool
)
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: os.Args[0],
Short: "Run CIS Benchmarks checks against a Kubernetes deployment",
Long: `This tool runs the CIS Kubernetes 1.6 Benchmark v1.0.0 checks.`,
Long: `This tool runs the CIS Kubernetes Benchmark (http://www.cisecurity.org/benchmark/kubernetes/)`,
}
// Execute adds all child commands to the root command sets flags appropriately.
@ -60,8 +64,13 @@ func Execute() {
func init() {
cobra.OnInitialize(initConfig)
// Output control
RootCmd.PersistentFlags().BoolVar(&noResults, "noresults", false, "Disable printing 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",
@ -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)

View File

@ -215,10 +215,19 @@ func multiWordReplace(s string, subname string, sub string) string {
func getKubeVersion() string {
// These executables might not be on the user's path.
_, err := exec.LookPath("kubectl")
if err != nil {
exitWithError(fmt.Errorf("kubernetes version check failed: %v", err))
_, err = exec.LookPath("kubelet")
if err != nil {
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()
}
return getKubeVersionFromKubectl()
}
func getKubeVersionFromKubectl() string {
cmd := exec.Command("kubectl", "version", "--short")
out, err := cmd.CombinedOutput()
if err != nil {
@ -228,6 +237,17 @@ func getKubeVersion() string {
return getVersionFromKubectlOutput(string(out))
}
func getKubeVersionFromKubelet() string {
cmd := exec.Command("kubelet", "--version")
out, err := cmd.CombinedOutput()
if err != nil {
continueWithError(fmt.Errorf("%s", out), "")
}
return getVersionFromKubeletOutput(string(out))
}
func getVersionFromKubectlOutput(s string) string {
serverVersionRe := regexp.MustCompile(`Server Version: v(\d+.\d+)`)
subs := serverVersionRe.FindStringSubmatch(s)
@ -238,6 +258,16 @@ func getVersionFromKubectlOutput(s string) string {
return subs[1]
}
func getVersionFromKubeletOutput(s string) string {
serverVersionRe := regexp.MustCompile(`Kubernetes v(\d+.\d+)`)
subs := serverVersionRe.FindStringSubmatch(s)
if len(subs) < 2 {
printlnWarn(fmt.Sprintf("Unable to get kubelet version, using default version: %s", defaultKubeVersion))
return defaultKubeVersion
}
return subs[1]
}
func makeSubstitutions(s string, ext string, m map[string]string) string {
for k, v := range m {
subst := "$" + k + ext

View File

@ -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

0
hooks/build Normal file → Executable file
View File

BIN
images/kube-bench.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

121
images/kube-bench.svg Normal file
View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 831.49597 755.90533"
height="755.90533"
width="831.49597"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath22"
clipPathUnits="userSpaceOnUse"><path
id="path20"
d="M 0,566.929 H 623.622 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,755.90533)"
id="g10"><g
transform="translate(314.8111,521.959)"
id="g12"><path
id="path14"
style="fill:#0ab1d5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 -106.784,-145.31 0,-280.384 105.477,-147.025 Z" /></g><g
id="g16"><g
clip-path="url(#clipPath22)"
id="g18"><g
transform="translate(51.8912,72.061)"
id="g24"><path
id="path26"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 71.061 c 0,3.629 2.86,6.6 6.6,6.6 3.74,0 6.6,-2.971 6.6,-6.6 V 32.45 h 2.97 c 1.32,0 2.42,0.551 3.52,1.981 L 33.44,52.69 c 1.43,1.981 3.081,3.3 5.72,3.3 3.63,0 6.271,-2.969 6.271,-6.599 0,-1.87 -0.881,-3.411 -1.981,-4.731 L 29.59,27.5 44.44,3.96 C 45.32,2.641 45.76,1.21 45.76,0 c 0,-3.63 -2.97,-6.6 -6.6,-6.6 -2.309,0 -4.4,1.54 -5.5,3.411 L 19.8,19.25 c -0.88,1.431 -1.98,2.091 -3.52,2.091 H 13.2 L 13.2,0 C 13.2,-3.63 10.34,-6.6 6.6,-6.6 2.86,-6.6 0,-3.63 0,0" /></g><g
transform="translate(104.9547,86.8013)"
id="g28"><path
id="path30"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 34.65 c 0,3.63 2.97,6.6 6.6,6.6 3.629,0 6.6,-2.97 6.6,-6.6 V 2.86 c 0,-8.47 3.409,-11.44 9.57,-11.44 4.73,0 9.24,2.86 11.33,4.95 v 38.28 c 0,3.63 2.97,6.6 6.6,6.6 3.63,0 6.6,-2.97 6.6,-6.6 v -50.16 c 0,-3.3 -2.53,-5.83 -5.72,-5.83 -2.97,0 -5.06,2.09 -5.72,4.95 l -0.55,2.42 C 32.12,-17.16 26.18,-21.34 18.149,-21.34 5.06,-21.34 0,-11.99 0,0" /></g><g
transform="translate(197.5084,90.4312)"
id="g32"><path
id="path34"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 12.65 c 0,8.47 -2.971,12.54 -10.341,12.54 -4.069,0 -8.029,-2.2 -10.559,-4.839 V -7.59 c 2.53,-2.639 6.49,-4.95 10.559,-4.95 C -2.971,-12.54 0,-8.47 0,0 m -34.101,-19.14 v 71.83 c 0,3.63 2.861,6.601 6.6,6.601 3.74,0 6.601,-2.971 6.601,-6.601 V 31.57 c 3.08,3.191 8.359,6.05 14.299,6.05 13.09,0 19.8,-8.8 19.8,-23.54 V -1.319 c 0,-14.741 -6.819,-23.651 -20.13,-23.651 -6.16,0 -11.88,2.97 -14.96,6.491 l -0.66,-2.201 c -0.769,-2.53 -3.08,-4.29 -5.72,-4.29 -3.299,0 -5.83,2.75 -5.83,5.83" /></g><g
transform="translate(251.7047,102.311)"
id="g36"><path
id="path38"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,9.57 -1.87,14.301 -9.9,14.301 -7.92,0 -9.9,-4.181 -9.9,-14.301 z M -33,-15.069 V 2.2 c 0,14.521 7.479,23.54 23.1,23.54 15.95,0 22.77,-8.689 22.77,-23.54 v -7.37 c 0,-2.859 -2.309,-5.17 -5.17,-5.17 h -27.5 v -5.939 c 0,-4.62 2.86,-9.13 10.89,-9.13 5.72,0 8.8,0.88 13.09,2.97 0.66,0.33 1.54,0.66 2.42,0.66 2.97,0 5.39,-2.42 5.39,-5.391 0,-2.309 -1.429,-3.96 -3.52,-5.17 -5.17,-2.97 -10.23,-4.51 -17.93,-4.51 -15.73,0 -23.54,8.25 -23.54,21.781" /></g><g
transform="translate(271.7564,99.4517)"
id="g40"><path
id="path42"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,3.3 2.53,5.83 5.721,5.83 h 19.91 c 3.3,0 5.83,-2.53 5.83,-5.83 0,-3.19 -2.53,-5.72 -5.83,-5.72 H 5.721 C 2.53,-5.72 0,-3.19 0,0" /></g><g
transform="translate(345.776,90.4312)"
id="g44"><path
id="path46"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 12.65 c 0,8.47 -2.971,12.54 -10.341,12.54 -4.069,0 -8.029,-2.2 -10.559,-4.839 V -7.59 c 2.53,-2.639 6.49,-4.95 10.559,-4.95 C -2.971,-12.54 0,-8.47 0,0 m -34.101,-19.14 v 71.83 c 0,3.63 2.861,6.601 6.6,6.601 3.74,0 6.601,-2.971 6.601,-6.601 V 31.57 c 3.08,3.191 8.359,6.05 14.299,6.05 13.09,0 19.8,-8.8 19.8,-23.54 V -1.319 c 0,-14.741 -6.819,-23.651 -20.13,-23.651 -6.16,0 -11.88,2.97 -14.96,6.491 l -0.66,-2.201 c -0.769,-2.53 -3.08,-4.29 -5.72,-4.29 -3.299,0 -5.83,2.75 -5.83,5.83" /></g><g
transform="translate(399.9723,102.311)"
id="g48"><path
id="path50"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,9.57 -1.87,14.301 -9.9,14.301 -7.92,0 -9.9,-4.181 -9.9,-14.301 z M -33,-15.069 V 2.2 c 0,14.521 7.479,23.54 23.1,23.54 15.95,0 22.77,-8.689 22.77,-23.54 v -7.37 c 0,-2.859 -2.309,-5.17 -5.17,-5.17 h -27.5 v -5.939 c 0,-4.62 2.86,-9.13 10.89,-9.13 5.72,0 8.8,0.88 13.09,2.97 0.66,0.33 1.54,0.66 2.42,0.66 2.97,0 5.39,-2.42 5.39,-5.391 0,-2.309 -1.429,-3.96 -3.52,-5.17 -5.17,-2.97 -10.23,-4.51 -17.93,-4.51 -15.73,0 -23.54,8.25 -23.54,21.781" /></g><g
transform="translate(421.8512,72.061)"
id="g52"><path
id="path54"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 50.16 c 0,3.301 2.53,5.83 5.72,5.83 2.97,0 5.06,-2.09 5.72,-4.949 l 0.55,-2.421 c 3.19,3.191 9.13,7.37 17.16,7.37 13.09,0 18.15,-9.349 18.15,-21.34 V 0 c 0,-3.63 -2.97,-6.6 -6.6,-6.6 -3.63,0 -6.599,2.97 -6.599,6.6 v 31.79 c 0,8.471 -3.411,11.44 -9.571,11.44 -4.73,0 -9.24,-2.86 -11.33,-4.95 L 13.2,0 C 13.2,-3.63 10.23,-6.6 6.6,-6.6 2.97,-6.6 0,-3.63 0,0" /></g><g
transform="translate(478.358,89.1118)"
id="g56"><path
id="path58"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 15.29 c 0,14.52 8.36,23.649 24.31,23.649 8.36,0 14.08,-3.08 18.15,-8.029 1.21,-1.54 1.87,-2.75 1.87,-4.511 0,-3.299 -2.53,-5.83 -5.83,-5.83 -1.76,0 -3.08,0.66 -4.4,1.981 -2.75,2.75 -5.39,4.62 -9.79,4.62 -8.69,0 -11.11,-5.83 -11.11,-12.981 L 13.2,1.1 c 0,-7.151 2.75,-12.981 11.44,-12.981 4.4,0 7.04,1.87 9.79,4.62 1.32,1.321 2.31,1.981 4.29,1.981 3.3,0 5.94,-2.531 5.94,-5.83 0,-1.76 -0.66,-2.97 -1.87,-4.51 C 38.72,-20.57 33,-23.65 24.64,-23.65 8.689,-23.65 0,-14.521 0,0" /></g><g
transform="translate(530.5396,72.061)"
id="g60"><path
id="path62"
style="fill:#464648;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 71.061 c 0,3.629 2.86,6.6 6.6,6.6 3.74,0 6.6,-2.971 6.6,-6.6 v -21.34 c 3.41,2.969 9.02,6.269 16.17,6.269 13.09,0 18.26,-9.349 18.26,-21.34 V 0 c 0,-3.63 -2.859,-6.6 -6.6,-6.6 -3.74,0 -6.6,2.97 -6.6,6.6 v 31.79 c 0,8.471 -3.52,11.44 -9.68,11.44 -4.729,0 -9.46,-2.86 -11.55,-4.95 V 0 C 13.2,-3.63 10.34,-6.6 6.6,-6.6 2.86,-6.6 0,-3.63 0,0" /></g><g
transform="translate(249.2096,192.0259)"
id="g64"><path
id="path66"
style="fill:#f1df36;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h 0.008 l 131.211,0.031 h 0.013 c 3.063,0 6.107,0.66 8.916,1.863 L 65.602,49.549 -8.531,1.7 C -5.83,0.6 -2.923,0 0,0" /></g><g
transform="translate(420.2877,374.9341)"
id="g68"><path
id="path70"
style="fill:#faaf42;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 -105.477,-133.359 74.547,-47.655 c 3.392,1.452 6.439,3.697 8.747,6.559 l 75.104,93.431 6.686,8.317 c 1.38,1.714 2.479,3.637 3.289,5.675 0.384,0.965 0.701,1.954 0.95,2.962 z" /></g><g
transform="translate(145.3785,311.2251)"
id="g72"><path
id="path74"
style="fill:#faaf42;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0.583,-2.568 1.609,-5.036 3.054,-7.245 0.401,-0.614 0.83,-1.209 1.285,-1.783 l 81.823,-101.735 c 2.396,-2.975 5.588,-5.289 9.138,-6.736 L 169.433,-69.65 62.648,65.424 Z" /></g><g
transform="translate(179.4977,457.7324)"
id="g76"><path
id="path78"
style="fill:#9ad7ec;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -2.408,-2.762 -4.144,-6.1 -4.985,-9.762 l -29.149,-126.8 c -0.65,-2.826 -0.715,-5.774 -0.239,-8.633 0.073,-0.44 0.155,-0.878 0.254,-1.312 l 62.648,65.424 z" /></g><g
transform="translate(484.1334,310.8643)"
id="g80"><path
id="path82"
style="fill:#9ad7ec;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 0.837,3.378 0.913,6.943 0.131,10.337 L -29.076,137.21 c -0.791,3.437 -2.374,6.586 -4.566,9.236 L -63.846,64.07 Z" /></g><g
transform="translate(317.7506,366.4487)"
id="g84"><path
id="path86"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 40.622,41.329 H 14.038 L -18.791,6.272 V 77.598 H -39.47 V -56.101 h 20.679 v 40.069 l 3.269,3.181 33.46,-43.25 h 27.03 z" /></g><g
transform="translate(275.7818,468.8486)"
id="g88"><path
id="path90"
style="fill:#1280c4;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 39.028,53.109 c -0.01,0 -0.022,10e-4 -0.033,10e-4 -0.047,0 -0.094,-0.003 -0.141,-0.003 C 38.521,53.105 38.187,53.099 37.853,53.082 37.814,53.08 37.776,53.072 37.738,53.07 34.783,52.909 31.86,52.166 29.192,50.889 L -89.022,-5.593 c -2.809,-1.342 -5.266,-3.235 -7.262,-5.523 L -67.755,-92.199 0,0.03 Z" /></g><g
transform="translate(442.8853,463.2578)"
id="g92"><path
id="path94"
style="fill:#1280c4;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 -118.288,56.48 c -3.039,1.455 -6.412,2.215 -9.785,2.22 L -22.598,-88.324 7.606,-5.947 C 5.558,-3.467 2.978,-1.422 0,0" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 10 KiB