summaryrefslogtreecommitdiff
path: root/wg-security-audit/ancillary-data/dataflow
diff options
context:
space:
mode:
authorDavid Hovey <david@hoveytech.com>2019-09-25 16:48:08 -0700
committerDavid Hovey <david@hoveytech.com>2019-09-25 16:48:08 -0700
commit72c7370548a65efcea9a9ba57c59cd10fa6e7530 (patch)
treef549d6eb1ea92ea3eb11c062c4aa5c485206c567 /wg-security-audit/ancillary-data/dataflow
parent1250c9771e9a5f0cb6aab40e746612d5c5a670bb (diff)
parent0b070cdc882e6b8f38aae95fcf4c18a983a61f36 (diff)
Merge branch 'master' of github.com:kubernetes/community
Diffstat (limited to 'wg-security-audit/ancillary-data/dataflow')
-rw-r--r--wg-security-audit/ancillary-data/dataflow/original dataflow.dot47
-rw-r--r--wg-security-audit/ancillary-data/dataflow/original dataflow.pngbin0 -> 102692 bytes
-rw-r--r--wg-security-audit/ancillary-data/dataflow/process.sh3
-rw-r--r--wg-security-audit/ancillary-data/dataflow/requirements.txt1
-rw-r--r--wg-security-audit/ancillary-data/dataflow/tm.py106
-rw-r--r--wg-security-audit/ancillary-data/dataflow/updated-dataflow.dot217
-rw-r--r--wg-security-audit/ancillary-data/dataflow/updated-dataflow.pngbin0 -> 321280 bytes
7 files changed, 374 insertions, 0 deletions
diff --git a/wg-security-audit/ancillary-data/dataflow/original dataflow.dot b/wg-security-audit/ancillary-data/dataflow/original dataflow.dot
new file mode 100644
index 00000000..02d2f830
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/original dataflow.dot
@@ -0,0 +1,47 @@
+digraph K8S {
+ subgraph cluster_apiserverinternal {
+ node [style=filled];
+ color=green;
+ etcd[label="etcd"];
+ label = "API Server Data Layer";
+ }
+
+ subgraph cluster_apiserver {
+ node [style=filled];
+ color=blue;
+ kubeapiserver[label="kube-apiserver"];
+ kubeapiserver->etcd[label="HTTPS"]
+ label = "API Server";
+ }
+
+ subgraph cluster_mastercomponents {
+ node [style=filled];
+ label = "Master Control Plane Components";
+ scheduler[label="Scheduler"];
+ controllers[label="Controllers"]
+ scheduler->kubeapiserver[label="Callback/HTTPS"];
+ controllers->kubeapiserver[label="Callback/HTTPS"];
+ color=black;
+ }
+
+ subgraph cluster_worker {
+ label="Worker"
+ color="blue"
+ kubelet->kubeapiserver[label="authenticated HTTPS"]
+ kubeproxy[label="kube-proxy"]
+ iptables->kubeproxy->iptables
+ pods[label="pods with various containers"]
+ pods->kubeproxy->pods
+ }
+
+ subgraph cluster_internet {
+ label="Internet"
+ authuser[label="Authorized User via kubebctl"]
+ generaluser[label="General User"]
+ authuser->kubeapiserver[label="Authenticated HTTPS"]
+ generaluser->pods[label="application-specific connection protocol"]
+ }
+ kubeapiserver->kubelet[label="HTTPS"]
+ kubeapiserver->pods[label="HTTP",color=red]
+}
+
diff --git a/wg-security-audit/ancillary-data/dataflow/original dataflow.png b/wg-security-audit/ancillary-data/dataflow/original dataflow.png
new file mode 100644
index 00000000..62c6680e
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/original dataflow.png
Binary files differ
diff --git a/wg-security-audit/ancillary-data/dataflow/process.sh b/wg-security-audit/ancillary-data/dataflow/process.sh
new file mode 100644
index 00000000..0a446eb3
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/process.sh
@@ -0,0 +1,3 @@
+python3 tm.py --dfd > updated-dataflow.dot
+dot -Tpng < updated-dataflow.dot > updated-dataflow.png
+open updated-dataflow.png
diff --git a/wg-security-audit/ancillary-data/dataflow/requirements.txt b/wg-security-audit/ancillary-data/dataflow/requirements.txt
new file mode 100644
index 00000000..f65609d4
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/requirements.txt
@@ -0,0 +1 @@
+pytm==0.4
diff --git a/wg-security-audit/ancillary-data/dataflow/tm.py b/wg-security-audit/ancillary-data/dataflow/tm.py
new file mode 100644
index 00000000..245501ff
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/tm.py
@@ -0,0 +1,106 @@
+# !/usr/bin/env python3
+
+from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda, Process
+
+tm = TM("Kubernetes Threat Model")
+tm.description = "a deep-dive threat model of Kubernetes"
+
+# Boundaries
+
+inet = Boundary("Internet")
+mcdata = Boundary("Master Control Data")
+apisrv = Boundary("API Server")
+mcomps = Boundary("Master Control Components")
+worker = Boundary("Worker")
+contain = Boundary("Container")
+
+# Actors
+
+miu = Actor("Malicious Internal User")
+ia = Actor("Internal Attacker")
+ea = Actor("External Actor")
+admin = Actor("Administrator")
+dev = Actor("Developer")
+eu = Actor("End User")
+
+# Server & OS Components
+
+etcd = Datastore("N-ary etcd servers")
+apiserver = Server("kube-apiserver")
+kubelet = Server("kubelet")
+kubeproxy = Server("kube-proxy")
+scheduler = Server("kube-scheduler")
+controllers = Server("CCM/KCM")
+pods = Server("Pods")
+iptables = Process("iptables")
+
+# Component <> Boundary Relations
+etcd.inBoundary = mcdata
+mcdata.inBoundary = apisrv
+apiserver.inBoundary = apisrv
+kubelet.inBoundary = worker
+kubeproxy.inBoundary = worker
+pods.inBoundary = contain
+scheduler.inBoundary = mcomps
+controllers.inBoundary = mcomps
+pods.inBoundary = contain
+iptables.inBoundary = worker
+miu.inBoundary = apisrv
+ia.inBoundary = contain
+ea.inBoundary = inet
+admin.inBoundary = apisrv
+dev.inBoundary = inet
+eu.inBoundary = inet
+
+# Dataflows
+
+apiserver2etcd = Dataflow(apiserver, etcd, "All kube-apiserver data")
+apiserver2etcd.isEncrypted = True
+apiserver2etcd.protocol = "HTTPS"
+
+apiserver2kubelet = Dataflow(apiserver, kubelet, "kubelet Health, Status, &amp;c.")
+apiserver2kubelet.isEncrypted = False
+apiserver2kubelet.protocol = "HTTP"
+
+apiserver2kubeproxy = Dataflow(apiserver, kubeproxy, "kube-proxy Health, Status, &amp;c.")
+apiserver2kubeproxy.isEncrypted = False
+apiserver2kubeproxy.protocol = "HTTP"
+
+apiserver2scheduler = Dataflow(apiserver, scheduler, "kube-scheduler Health, Status, &amp;c.")
+apiserver2scheduler.isEncrypted = False
+apiserver2scheduler.protocol = "HTTP"
+
+apiserver2controllers = Dataflow(apiserver, controllers, "{kube, cloud}-controller-manager Health, Status, &amp;c.")
+apiserver2controllers.isEncrypted = False
+apiserver2controllers.protocol = "HTTP"
+
+kubelet2apiserver = Dataflow(kubelet, apiserver, "HTTP watch for resources on kube-apiserver")
+kubelet2apiserver.isEncrypted = True
+kubelet2apiserver.protocol = "HTTPS"
+
+kubeproxy2apiserver = Dataflow(kubeproxy, apiserver, "HTTP watch for resources on kube-apiserver")
+kubeproxy2apiserver.isEncrypted = True
+kubeproxy2apiserver.protocol = "HTTPS"
+
+controllers2apiserver = Dataflow(controllers, apiserver, "HTTP watch for resources on kube-apiserver")
+controllers2apiserver.isEncrypted = True
+controllers2apiserver.protocol = "HTTPS"
+
+scheduler2apiserver = Dataflow(scheduler, apiserver, "HTTP watch for resources on kube-apiserver")
+scheduler2apiserver.isEncrypted = True
+scheduler2apiserver.protocol = "HTTPS"
+
+kubelet2iptables = Dataflow(kubelet, iptables, "kubenet update of iptables (... ipvs, &amp;c) to setup Host-level ports")
+kubelet2iptables.protocol = "IPC"
+
+kubeproxy2iptables = Dataflow(kubeproxy, iptables, "kube-prxy update of iptables (... ipvs, &amp;c) to setup all pod networking")
+kubeproxy2iptables.protocol = "IPC"
+
+kubelet2pods = Dataflow(kubelet, pods, "kubelet to pod/CRI runtime, to spin up pods within a host")
+kubelet2pods.protocol = "IPC"
+
+eu2pods = Dataflow(eu, pods, "End-user access of Kubernetes-hosted applications")
+ea2pods = Dataflow(ea, pods, "External Attacker attempting to compromise a trust boundary")
+ia2cnts = Dataflow(ia, pods, "Internal Attacker with access to a compromised or malicious pod")
+
+tm.process()
diff --git a/wg-security-audit/ancillary-data/dataflow/updated-dataflow.dot b/wg-security-audit/ancillary-data/dataflow/updated-dataflow.dot
new file mode 100644
index 00000000..671e2dde
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/updated-dataflow.dot
@@ -0,0 +1,217 @@
+digraph tm {
+ graph [
+ fontname = Arial;
+ fontsize = 14;
+ ]
+ node [
+ fontname = Arial;
+ fontsize = 14;
+ rankdir = lr;
+ ]
+ edge [
+ shape = none;
+ fontname = Arial;
+ fontsize = 12;
+ ]
+ labelloc = "t";
+ fontsize = 20;
+ nodesep = 1;
+
+subgraph cluster_bfaefefcfbeeafeefac {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>Internet</i>>;
+ ]
+
+bfbeacdafaceebdccfdffcdfcedfec [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>External Actor</b></td></tr></table>>;
+]
+abaadcacbbafdffbcffffbeedef [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>Developer</b></td></tr></table>>;
+]
+adafdaeaedeedcafe [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>End User</b></td></tr></table>>;
+]
+
+}
+
+subgraph cluster_bbfdadaacbdaedcebfec {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>Master Control Data</i>>;
+ ]
+
+bfffcaeeeeedccabfaaeff [
+ shape = none;
+ color = black;
+ label = <<table sides="TB" cellborder="0" cellpadding="2"><tr><td><font color="black"><b>N-ary etcd servers</b></font></td></tr></table>>;
+]
+
+}
+
+subgraph cluster_afeffbbfdbeeefcabddacdba {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>API Server</i>>;
+ ]
+
+bdfbefabdbefeacdfcabaac [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>Malicious Internal User</b></td></tr></table>>;
+]
+fabeebdadbcdffdcdec [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>Administrator</b></td></tr></table>>;
+]
+eadddadcfbabebaed [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>kube-apiserver</b></td></tr></table>>;
+]
+
+}
+
+subgraph cluster_cebcbebffccbfedcaffbb {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>Master Control Components</i>>;
+ ]
+
+ffceacecdbcacdddddffbfa [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>kube-scheduler</b></td></tr></table>>;
+]
+adffdceecfcfbcfdaefca [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>CCM/KCM</b></td></tr></table>>;
+]
+
+}
+
+subgraph cluster_baaffdafbdceebaaafaefeea {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>Worker</i>>;
+ ]
+
+dbddcfaeaacebaecba [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>kubelet</b></td></tr></table>>;
+]
+ddcaffdfdebdaeff [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>kube-proxy</b></td></tr></table>>;
+]
+bcdcebabbdaadffeaeddcce [
+ shape = circle;
+ color = black;
+
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color="black"><b>iptables</b></font></td></tr></table>>;
+]
+
+}
+
+subgraph cluster_fdcecbcfbeadaccab {
+ graph [
+ fontsize = 10;
+ fontcolor = firebrick2;
+ style = dashed;
+ color = firebrick2;
+ label = <<i>Container</i>>;
+ ]
+
+bdfadfbeeaedceab [
+ shape = square;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>Internal Attacker</b></td></tr></table>>;
+]
+eefbffbeaaeecaceaaabe [
+ shape = circle
+ color = black
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><b>Pods</b></td></tr></table>>;
+]
+
+}
+
+ eadddadcfbabebaed -> bfffcaeeeeedccabfaaeff [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>All kube-apiserver data</b></font></td></tr></table>>;
+ ]
+ eadddadcfbabebaed -> dbddcfaeaacebaecba [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kubelet Health, Status, &amp;c.</b></font></td></tr></table>>;
+ ]
+ eadddadcfbabebaed -> ddcaffdfdebdaeff [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kube-proxy Health, Status, &amp;c.</b></font></td></tr></table>>;
+ ]
+ eadddadcfbabebaed -> ffceacecdbcacdddddffbfa [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kube-scheduler Health, Status, &amp;c.</b></font></td></tr></table>>;
+ ]
+ eadddadcfbabebaed -> adffdceecfcfbcfdaefca [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>{kube, cloud}-controller-manager Health, Status, &amp;c.</b></font></td></tr></table>>;
+ ]
+ dbddcfaeaacebaecba -> eadddadcfbabebaed [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>HTTP watch for resources on kube-apiserver</b></font></td></tr></table>>;
+ ]
+ ddcaffdfdebdaeff -> eadddadcfbabebaed [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>HTTP watch for resources on kube-apiserver</b></font></td></tr></table>>;
+ ]
+ adffdceecfcfbcfdaefca -> eadddadcfbabebaed [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>HTTP watch for resources on kube-apiserver</b></font></td></tr></table>>;
+ ]
+ ffceacecdbcacdddddffbfa -> eadddadcfbabebaed [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>HTTP watch for resources on kube-apiserver</b></font></td></tr></table>>;
+ ]
+ dbddcfaeaacebaecba -> bcdcebabbdaadffeaeddcce [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kubenet update of iptables (... ipvs, &amp;c) to setup Host-level ports</b></font></td></tr></table>>;
+ ]
+ ddcaffdfdebdaeff -> bcdcebabbdaadffeaeddcce [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kube-prxy update of iptables (... ipvs, &amp;c) to setup all pod networking</b></font></td></tr></table>>;
+ ]
+ dbddcfaeaacebaecba -> eefbffbeaaeecaceaaabe [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>kubelet to pod/CRI runtime, to spin up pods within a host</b></font></td></tr></table>>;
+ ]
+ adafdaeaedeedcafe -> eefbffbeaaeecaceaaabe [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>End-user access of Kubernetes-hosted applications</b></font></td></tr></table>>;
+ ]
+ bfbeacdafaceebdccfdffcdfcedfec -> eefbffbeaaeecaceaaabe [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>External Attacker attempting to compromise a trust boundary</b></font></td></tr></table>>;
+ ]
+ bdfadfbeeaedceab -> eefbffbeaaeecaceaaabe [
+ color = black;
+ label = <<table border="0" cellborder="0" cellpadding="2"><tr><td><font color ="black"><b>Internal Attacker with access to a compromised or malicious pod</b></font></td></tr></table>>;
+ ]
+}
diff --git a/wg-security-audit/ancillary-data/dataflow/updated-dataflow.png b/wg-security-audit/ancillary-data/dataflow/updated-dataflow.png
new file mode 100644
index 00000000..c86cd09e
--- /dev/null
+++ b/wg-security-audit/ancillary-data/dataflow/updated-dataflow.png
Binary files differ