Add Robot test for running kube-hunter 46/2246/1
authorJuha Kosonen <juha.kosonen@nokia.com>
Thu, 20 Feb 2020 14:21:12 +0000 (16:21 +0200)
committerJuha Kosonen <juha.kosonen@nokia.com>
Thu, 20 Feb 2020 14:21:12 +0000 (16:21 +0200)
Integrated to k8s layer as an optional test.

JIRA: VAL-96

Change-Id: I0d11a3aa9438a7fe3dbe52a1358af5ddcaabff61
Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
13 files changed:
.coafile
bluval/bluval-base.yaml
bluval/bluval-iec.yaml
bluval/bluval-kni.yaml
bluval/bluval-rec.yaml
bluval/bluval-unicycle.yaml
docker/k8s/pip-requirements.txt
docker/kube-hunter/Dockerfile [new file with mode: 0644]
docker/kube-hunter/Makefile [new file with mode: 0644]
docker/kube-hunter/pip-requirements.txt [new file with mode: 0644]
tests/k8s/kube-hunter/job.yaml [new file with mode: 0644]
tests/k8s/kube-hunter/kube-hunter.resource [new file with mode: 0644]
tests/k8s/kube-hunter/kube-hunter.robot [new file with mode: 0644]

index fd4a0cc..c472b5d 100644 (file)
--- a/.coafile
+++ b/.coafile
@@ -36,7 +36,8 @@ bears = YAMLLintBear
 files = **.yaml, **.yml
 use_spaces = true
 max_line_length = 120
-ignore = tests/k8s/conformance/custom_repos.yaml
+ignore = tests/k8s/conformance/custom_repos.yaml,
+    tests/k8s/kube-hunter/job.yaml
 
 [all.Python]
 bears = PyLintBear
index ab860f9..845a700 100644 (file)
@@ -54,6 +54,9 @@ blueprint:
         -
             name: ha
             what: ha
+        -
+            name: kube-hunter
+            what: kube-hunter
     k8s_networking: &k8s_networking
         -
             name: node_connectivity
index 1762e5e..1da0158 100644 (file)
@@ -25,3 +25,7 @@ blueprint:
             name: conformance
             what: conformance
             optional: "False"
+        -
+            name: kube-hunter
+            what: kube-hunter
+            optional: "True"
index 75f941b..c615ffb 100644 (file)
@@ -37,3 +37,7 @@ blueprint:
         -
             name: conformance
             what: conformance
+        -
+            name: kube-hunter
+            what: kube-hunter
+            optional: "True"
index 8bc3203..07df9da 100644 (file)
@@ -52,3 +52,7 @@ blueprint:
             name: etcd_ha
             what: etcd_ha
             optional: "True"
+        -
+            name: kube-hunter
+            what: kube-hunter
+            optional: "True"
index 02e6b31..2f0768d 100644 (file)
@@ -46,6 +46,10 @@ blueprint:
             name: etcd_ha
             what: etcd_ha
             optional: "True"
+        -
+            name: kube-hunter
+            what: kube-hunter
+            optional: "True"
     openstack: &openstack_unicycle
         -
             name: tempest
index 18b264c..59a75a8 100644 (file)
@@ -3,3 +3,4 @@ robotframework-httplibrary
 robotframework-jsonlibrary
 robotframework-requests
 robotframework-sshlibrary
+kube-hunter
diff --git a/docker/kube-hunter/Dockerfile b/docker/kube-hunter/Dockerfile
new file mode 100644 (file)
index 0000000..7e65f93
--- /dev/null
@@ -0,0 +1,40 @@
+##############################################################################
+# Copyright (c) 2020 AT&T, ENEA AB, Nokia and others                         #
+#                                                                            #
+# Licensed under the Apache License, Version 2.0 (the "License");            #
+# you maynot use this file except in compliance with the License.            #
+#                                                                            #
+# You may obtain a copy of the License at                                    #
+#       http://www.apache.org/licenses/LICENSE-2.0                           #
+#                                                                            #
+# Unless required by applicable law or agreed to in writing, software        #
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
+# See the License for the specific language governing permissions and        #
+# limitations under the License.                                             #
+##############################################################################
+
+FROM python:3.6-alpine3.9 as build
+
+# Install dependencies
+COPY pip-requirements.txt /wheels/requirements/pip-requirements.txt
+
+RUN apk --no-cache add --update \
+       linux-headers \
+       build-base
+
+# Build binaries
+WORKDIR /wheels
+RUN pip3 install wheel
+RUN pip3 wheel -r /wheels/requirements/pip-requirements.txt
+
+# Copy binaries in the final container
+FROM python:3.6-alpine3.9
+COPY --from=build /wheels /wheels
+
+RUN pip3 install -r /wheels/requirements/pip-requirements.txt \
+                 -f /wheels && \
+     rm -rf /wheels && \
+     rm -rf /root/.cache/pip/*
+
+ENTRYPOINT ["kube-hunter"]
diff --git a/docker/kube-hunter/Makefile b/docker/kube-hunter/Makefile
new file mode 100644 (file)
index 0000000..4a059ba
--- /dev/null
@@ -0,0 +1,26 @@
+##############################################################################
+# Copyright (c) 2020 AT&T, ENEA AB, Nokia and others                         #
+#                                                                            #
+# Licensed under the Apache License, Version 2.0 (the "License");            #
+# you maynot use this file except in compliance with the License.            #
+#                                                                            #
+# You may obtain a copy of the License at                                    #
+#       http://www.apache.org/licenses/LICENSE-2.0                           #
+#                                                                            #
+# Unless required by applicable law or agreed to in writing, software        #
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
+# See the License for the specific language governing permissions and        #
+# limitations under the License.                                             #
+##############################################################################
+
+.PHONY: all
+all: push-image .push_manifest
+
+.PHONY: build
+build: .build
+
+.PHONY: push-image
+push-image: .push_image
+
+include ../build.mk
diff --git a/docker/kube-hunter/pip-requirements.txt b/docker/kube-hunter/pip-requirements.txt
new file mode 100644 (file)
index 0000000..6052d92
--- /dev/null
@@ -0,0 +1 @@
+kube-hunter
diff --git a/tests/k8s/kube-hunter/job.yaml b/tests/k8s/kube-hunter/job.yaml
new file mode 100644 (file)
index 0000000..62079c5
--- /dev/null
@@ -0,0 +1,31 @@
+##############################################################################
+# Copyright (c) 2020 AT&T Intellectual Property.                             #
+# Copyright (c) 2020 Nokia.                                                  #
+#                                                                            #
+# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
+# not use this file except in compliance with the License.                   #
+#                                                                            #
+# You may obtain a copy of the License at                                    #
+#       http://www.apache.org/licenses/LICENSE-2.0                           #
+#                                                                            #
+# Unless required by applicable law or agreed to in writing, software        #
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
+# See the License for the specific language governing permissions and        #
+# limitations under the License.                                             #
+##############################################################################
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: kube-hunter
+spec:
+  template:
+    spec:
+      containers:
+      - name: kube-hunter
+        image: {{ image }}
+        command: ["kube-hunter"]
+        args: ["--pod"]
+      restartPolicy: Never
+  backoffLimit: 4
diff --git a/tests/k8s/kube-hunter/kube-hunter.resource b/tests/k8s/kube-hunter/kube-hunter.resource
new file mode 100644 (file)
index 0000000..561dea2
--- /dev/null
@@ -0,0 +1,123 @@
+##############################################################################
+# Copyright (c) 2020 AT&T Intellectual Property.                             #
+# Copyright (c) 2020 Nokia.                                                  #
+#                                                                            #
+# Licensed under the Apache License, Version 2.0 (the "License");            #
+# you maynot use this file except in compliance with the License.            #
+#                                                                            #
+# You may obtain a copy of the License at                                    #
+#       http://www.apache.org/licenses/LICENSE-2.0                           #
+#                                                                            #
+# Unless required by applicable law or agreed to in writing, software        #
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
+# See the License for the specific language governing permissions and        #
+# limitations under the License.                                             #
+##############################################################################
+
+
+*** Settings ***
+Library             Collections
+Library             OperatingSystem
+Library             Process
+Library             SSHLibrary
+Library             String
+
+
+*** Variables ***
+${REPORTDIR}        ${LOG_PATH}/${SUITE_NAME.replace(' ','_')}
+&{KUBE_HUNTER}      path=akraino
+...                 name=validation:kube-hunter-latest
+
+
+*** Keywords ***
+Open Connection And Log In
+    Open Connection  ${HOST}
+    Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}
+
+Get Cluster Address
+    ${result}=        Run Process  kubectl  config  view  --minify
+    ...                            -o  jsonpath\={.clusters[0].cluster.server}
+    Should Be Equal As Integers  ${result.rc}  0
+    ${addr}=          Fetch From Right  ${result.stdout}  ://
+    ${addr}=          Fetch From Left  ${addr}  :
+    Should Not Be Empty  ${addr}
+    [Return]          ${addr}
+
+Get Remote Addresses
+    ${result}=        Run Process  kubectl  get  nodes
+    ...                   -o  jsonpath\={.items[*].status.addresses[?(@.type\=\="ExternalIP")].address}
+    Should Be Equal As Integers  ${result.rc}  0
+    Pass Execution If  '${result.stdout}' == '${EMPTY}'  No external node IPs exposed
+    @{addrs}=         Split String  ${result.stdout}
+    [Return]          ${addrs}
+
+Upload To Internal Registry
+    [Arguments]       ${path}  ${name}
+    ${rc}=            Execute Command
+    ...               docker pull ${path}/${name}
+    ...                 return_stdout=False  return_rc=True
+    Should Be Equal As Integers  ${rc}  0
+    ${rc}=            Execute Command
+    ...               docker tag ${path}/${name} ${INT_REG}/bluval/${name}
+    ...                 return_stdout=False  return_rc=True
+    Should Be Equal As Integers  ${rc}  0
+    ${rc}=            Execute Command
+    ...               docker push ${INT_REG}/bluval/${name}
+    ...                 return_stdout=False  return_rc=True
+    Should Be Equal As Integers  ${rc}  0
+
+Onboard Image
+    ${INT_REG}=       Get Variable Value  ${INTERNAL_REGISTRY}  ${EMPTY}
+    Set Test Variable  ${INT_REG}
+    Return From Keyword If  $INT_REG == '${EMPTY}'
+    Open Connection And Log In
+    Upload To Internal Registry  ${KUBE_HUNTER['path']}  ${KUBE_HUNTER['name']}
+    Set To Dictionary  ${KUBE_HUNTER}  path=${INT_REG}/bluval
+
+Prepare Job Manifest
+    Run Process       sed  -i  s|{{ image }}|${KUBE_HUNTER['path']}/${KUBE_HUNTER['name']}|g
+    ...               ${CURDIR}/job.yaml
+
+Set Scan Status
+    [Arguments]       ${log}
+    ${STATUS}=        Evaluate  "No vulnerabilities were found" in """${log}"""
+    Set Test Variable  ${STATUS}
+
+Delete Scan Job
+    ${result}=        Run Process  kubectl  delete  job  kube-hunter
+    Should Be Equal As Integers  ${result.rc}  0
+
+Should Discover No Vulnerabilities
+    Should Be True    ${STATUS}
+
+Run Scan Within Pod
+    ${result}=        Run Process  kubectl  apply  -f  job.yaml
+    Should Be Equal As Integers  ${result.rc}  0
+    ${result}=        Run Process  kubectl  wait  --for\=condition\=complete
+    ...                            --timeout\=15m  job/kube-hunter
+    Should Be Equal As Integers  ${result.rc}  0
+    ${result}=        Run Process  kubectl  get  pods  --selector\=job-name\=kube-hunter
+    ...                            -o  jsonpath\={.items[*].metadata.name}
+    Should Be Equal As Integers  ${result.rc}  0
+    ${result}=        Run Process  kubectl  logs  ${result.stdout}
+    ...                 stdout=pod.log
+    Copy File         pod.log  ${REPORTDIR}/
+    Should Be Equal As Integers  ${result.rc}  0
+    Set Scan Status  ${result.stdout}
+
+Run Node Scan
+    ${addrs}=         Get Remote Addresses
+    ${result}=        Run Process  kube-hunter  --remote  @{addrs}
+    ...                 stdout=node.log
+    Copy File         node.log  ${REPORTDIR}/
+    Should Be Equal As Integers  ${result.rc}  0
+    Set Scan Status  ${result.stdout}
+
+Run Cluster Scan
+    ${addr}=          Get Cluster Address
+    ${result}=        Run Process  kube-hunter  --remote  ${addr}
+    ...                 stdout=cluster.log
+    Copy File         cluster.log  ${REPORTDIR}/
+    Should Be Equal As Integers  ${result.rc}  0
+    Set Scan Status  ${result.stdout}
diff --git a/tests/k8s/kube-hunter/kube-hunter.robot b/tests/k8s/kube-hunter/kube-hunter.robot
new file mode 100644 (file)
index 0000000..4ef9bf6
--- /dev/null
@@ -0,0 +1,39 @@
+##############################################################################
+# Copyright (c) 2020 AT&T Intellectual Property.                             #
+# Copyright (c) 2020 Nokia.                                                  #
+#                                                                            #
+# Licensed under the Apache License, Version 2.0 (the "License");            #
+# you maynot use this file except in compliance with the License.            #
+#                                                                            #
+# You may obtain a copy of the License at                                    #
+#       http://www.apache.org/licenses/LICENSE-2.0                           #
+#                                                                            #
+# Unless required by applicable law or agreed to in writing, software        #
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
+# See the License for the specific language governing permissions and        #
+# limitations under the License.                                             #
+##############################################################################
+
+
+*** Settings ***
+Documentation     Hunt for security weaknesses in Kubernetes cluster
+Resource          kube-hunter.resource
+
+
+*** Test Cases ***
+Cluster Remote Scanning
+    Run Cluster Scan
+    Should Discover No Vulnerabilities
+
+Node Remote Scanning
+    Run Node Scan
+    Should Discover No Vulnerabilities
+
+Inside-a-Pod Scanning
+    [Setup]  Run Keywords  Onboard Image
+    ...                    Prepare Job Manifest
+    Run Scan Within Pod
+    Should Discover No Vulnerabilities
+    [Teardown]  Run Keywords  Delete Scan Job
+    ...                       Close All Connections