Skip to content

Commit

Permalink
feat(plugins): update kubernetes iac polices
Browse files Browse the repository at this point in the history
  • Loading branch information
ek1ng committed May 15, 2023
1 parent 8ff7842 commit 435ea4d
Show file tree
Hide file tree
Showing 37 changed files with 414 additions and 49 deletions.
4 changes: 2 additions & 2 deletions plugins/go/veinmind-iac/go.sum
Expand Up @@ -284,8 +284,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chaitin/libveinmind v1.5.2/go.mod h1:TXLYL6GeSAQ7pQ5IxPG4Tp0DuB1QvPPFhqdOjyiWxVU=
github.com/chaitin/libveinmind v1.5.5 h1:cd3aAc4v+p4ZTuzVPQQMqAgq4aboDoa1XAUxyl35hWg=
github.com/chaitin/libveinmind v1.5.5/go.mod h1:TXLYL6GeSAQ7pQ5IxPG4Tp0DuB1QvPPFhqdOjyiWxVU=
github.com/chaitin/libveinmind v1.5.6 h1:fyNq142a+uOfYZ68GTzElFXVB0dtEXvs+ffwk24+Vfg=
github.com/chaitin/libveinmind v1.5.6/go.mod h1:TXLYL6GeSAQ7pQ5IxPG4Tp0DuB1QvPPFhqdOjyiWxVU=
github.com/chaitin/veinmind-common-go v1.4.2 h1:+AK2lt/OI7/kGQpt3rkp1gVJvoxfosnxxFaBfi6nbGw=
github.com/chaitin/veinmind-common-go v1.4.2/go.mod h1:+dshrlmHiBtRV7ATyObBIg3SZoffpNCr1PdahT1LUQo=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
Expand Down
1 change: 1 addition & 0 deletions plugins/go/veinmind-iac/pkg/parser/parser.go
Expand Up @@ -101,6 +101,7 @@ type KubernetesInput struct {
Spec interface{} `yaml:"spec" json:"spec"`
RoleRef interface{} `yaml:"roleRef" json:"roleRef"`
Status interface{} `yaml:"status" json:"status"`
Subjects interface{} `yaml:"subjects" json:"subjects"`
Authentication interface{} `yaml:"authentication" json:"authentication"`
Authorization interface{} `yaml:"authorization" json:"authorization"`
Template interface{} `yaml:"template" json:"template"`
Expand Down
@@ -1,9 +1,6 @@
package brightMirror.kubernetes

import data.common
import future.keywords.in
import future.keywords.contains
import future.keywords.if

risks[res]{
input.authentication.anonymous.enabled==true
Expand Down
@@ -1,12 +1,10 @@
package brightMirror.kubernetes

import data.common
import future.keywords.in
import future.keywords.contains
import future.keywords.if

risks[res]{
input.metadata.name=="system:anonymous"
input.kind=="ClusterRoleBinding"
input.roleRef.name=="cluster-admin"
input.subjects[i].name=="system:anonymous"
res := common.result({"original":"UnSafeSettings:`metadata.name`,`roleRef.name`", "Path": input.Path}, "KN-006")
}
Expand Up @@ -9,10 +9,11 @@ risks[res]{
input.spec.containers[i].command[i]=="kube-apiserver"
version:=input.spec.containers[i].image
contains(version,"v1.1")
inner:=input.spec.containers[i].command
not contains(version,"v1.19")
inner:=input.spec.containers[i].args
some val in inner
contains(val,"insecure-port")
not contains(val,"insecure-port=0")
code:=val
res := common.result({"original":"UnSafeSettings:`spec.containers.command`", "Path": input.Path}, "KN-005")
}
}
@@ -1,11 +1,14 @@
package brightMirror.kubernetes

import data.common
import future.keywords.in
import future.keywords.contains
import future.keywords.if

risks[res]{
contains(input.spec.containers[0].args[i],"enable-skip-login")
contains(input.spec.containers[_].args[i],"enable-skip-login")
res := common.result({"original":"UnSafeSettings:`spec.containers.args`", "Path": input.Path}, "KN-008")
}

risks[res]{
contains(input.spec.template.spec.containers[_].args[i],"enable-skip-login")
res := common.result({"original":"UnSafeSettings:`spec.containers.args`", "Path": input.Path}, "KN-008")
}
Expand Up @@ -9,7 +9,7 @@ import future.keywords.if

risks[res]{
input.spec.containers[i].command[i]=="etcd"
every val in input.spec.containers[i].command{
every val in input.spec.containers[i].args{
not contains(val,"--client-cert-auth=true")
}
res := common.result({"original":"UnSafeSettings:`spec.containers.command missing --client-cert-auth=true`", "Path": input.Path}, "KN-009")
Expand Down
Expand Up @@ -9,7 +9,7 @@ import future.keywords.if

risks[res]{
input.spec.containers[i].command[i]=="etcd"
every val in input.spec.containers[i].command{
every val in input.spec.containers[i].args{
not contains(val,"--peer-client-cert-auth=true")
}
res := common.result({"original":"UnSafeSettings:`spec.containers.command missing --peer-client-cert-auth=true", "Path": input.Path}, "KN-010")
Expand Down
Expand Up @@ -3,7 +3,6 @@ package brightMirror.kubernetes
import data.common
import future.keywords.in


risks[res]{
inner := input.spec.containers[i].securityContext.capabilities.add
some val in inner
Expand Down
Expand Up @@ -3,9 +3,8 @@ package brightMirror.kubernetes
import data.common
import future.keywords.in


risks[res]{
input.spec.hostPID==true
input.spec.hostPID==true
inner := input.spec.containers[i].securityContext.capabilities.add
some val in inner
upper(val) == "SYS_PTRACE"
Expand Down
Expand Up @@ -3,8 +3,6 @@ package brightMirror.kubernetes
import data.common
import future.keywords.in



risks[res]{
inner := input.spec.containers[i].securityContext.capabilities.add
some val in inner
Expand All @@ -14,5 +12,4 @@ risks[res]{
Names=[Name]
Combine:=array.concat(Hints,Names)
res := common.result({"original":concat(":",Combine), "Path": input.Path}, "KN-012")

}
Expand Up @@ -3,9 +3,9 @@ package brightMirror.kubernetes
import data.common

risks[res] {
name := containers[_].name
key := sprintf("%s/%s", ["container.apparmor.security.beta.kubernetes.io", name])
val := annotations[i][key]
val != "runtime/default"
res := common.result({"original": val,"Path": input[i].Path}, "KN-003")
inner:= input.spec.containers[i]
key := sprintf("%s/%s", ["container.apparmor.security.beta.kubernetes.io", inner.name])
annotations:=input.metadata.annotations
annotations[key]!="runtime/default"
res := common.result({"original": annotations[key],"Path": input.Path}, "KN-003")
}
Expand Up @@ -3,14 +3,9 @@ package brightMirror.kubernetes
import data.common

risks[res] {
count(securityContexts) > 0
count(allowPrivilegeEscalations) > 0
allowPrivilegeEscalations[i] == true
res := common.result({"original": allowPrivilegeEscalations[i], "Path": input[i].Path}, "KN-002")
containers := input.spec.containers
securityContexts := containers[_].securityContext
allowPrivilegeEscalations := securityContexts.allowPrivilegeEscalations
allowPrivilegeEscalations == true
res := common.result({"original": "UnSafeSettings:set allowPrivilegeEscalation=true", "Path": input.Path}, "KN-002")
}

risks[res] {
count(securityContexts) > 0
count(allowPrivilegeEscalations) < 1
res := common.result({"original":"UnSafeSettings:`unset allowPrivilegeEscalation=false`", "Path": input[i].Path}, "KN-002")
}
Expand Up @@ -3,14 +3,14 @@ package brightMirror.kubernetes
import data.common

risks[res] {
image := containers[_].image
contains(image, "latest")
res := common.result({"original":image, "Path": input[i].Path}, "KN-001")
image := input.spec.containers[_].image
contains(image, "latest")
res := common.result({"original":input.spec.containers[_].image, "Path": input.Path}, "KN-001")
}

risks[res] {
image := containers[_].image
image := input.spec.containers[_].image
not contains(image, ":")
not equal(image, "scratch")
res := common.result({"original":image, "Path": input[i].Path}, "KN-001")
res := common.result({"original":input.spec.containers[_].image, "Path": input.Path}, "KN-001")
}
Expand Up @@ -13,5 +13,4 @@ risks[res]{
b=[d]
c:=array.concat(a,b)
res := common.result({"original":concat(":",c), "Path": input.Path}, "KN-011")

}
@@ -1,8 +1,17 @@
package brightMirror.kubernetes

import data.common
import future.keywords.every

#risks[res] {
# securityContexts
# res := kubernetes.result(securityContexts, "KN-004")
#}
default allow=false

allowValuesSeLinuxOptionsType:=["container_t","container_init_t","container_kvm_t"]

risks[res]{
inner := input.spec.containers[i]
type := inner.securityContext.seLinuxOptions.type
every val in allowValuesSeLinuxOptionsType {
val != type
}
res:= common.result({"original":"UnSafeSettings:`spec.containers.securityContext.seLinuxOptions.type`", "Path": input.Path},"KN-004")
}
8 changes: 8 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-001.yaml
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx:latest
20 changes: 20 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-002.yaml
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Pod
metadata:
name: hello-privileged
spec:
containers:
- command:
- sh
- "-c"
- echo 'Hello' && sleep 1h
image: busybox:v1.26.0
name: hello
securityContext:
seccompProfile:
type: Localhost
runAsNonRoot: true
capabilities:
drop:
- ALL
allowPrivilegeEscalations: true
21 changes: 21 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-003.yaml
@@ -0,0 +1,21 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/hello: custom
name: hello-apparmor
spec:
containers:
- command:
- sh
- "-c"
- echo 'Hello AppArmor!' && sleep 1h
image: busybox:v1.26.0
name: hello
securityContext:
seccompProfile:
type: Localhost
runAsNonRoot: true
capabilities:
drop:
- ALL
21 changes: 21 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-004.yaml
@@ -0,0 +1,21 @@
apiVersion: v1
kind: Pod
metadata:
name: hello-selinux
spec:
containers:
- command:
- sh
- "-c"
- echo 'Hello' && sleep 1h
image: busybox:v1.26.0
name: hello
securityContext:
seccompProfile:
type: Localhost
runAsNonRoot: true
capabilities:
drop:
- ALL
seLinuxOptions:
type: custom
13 changes: 13 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-005.yaml
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
spec:
containers:
- name: kube-apiserver
image: k8s.gcr.io/kube-apiserver:v1.17.0
command:
- kube-apiserver
args:
- --insecure-port=8080
- --insecure-bind-address=0.0.0.0
12 changes: 12 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-006.yaml
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: anonymous-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:anonymous
11 changes: 11 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-007.yaml
@@ -0,0 +1,11 @@
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: true
webhook:
enabled: false
x509:
clientCAFile: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
authorization:
mode: AlwaysAllow
33 changes: 33 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-008.yaml
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.2.0
args:
- --enable-skip-login
ports:
- containerPort: 8443
name: dashboard
protocol: TCP
volumeMounts:
- mountPath: /certs
name: kubernetes-dashboard-certs
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
26 changes: 26 additions & 0 deletions plugins/go/veinmind-iac/rules/test/kubernetes/KN-009.yaml
@@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: etcd
namespace: kube-system
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.4.15
command:
- etcd
args:
- --name=etcd-node
- --listen-client-urls=http://0.0.0.0:2379
- --advertise-client-urls=http://localhost:2379
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-advertise-peer-urls=http://localhost:2380
- --initial-cluster=etcd-node=http://localhost:2380
- --initial-cluster-token=etcd-cluster
- --initial-cluster-state=new
- --peer-client-cert-auth=true
ports:
- containerPort: 2379
name: client
- containerPort: 2380
name: peer

0 comments on commit 435ea4d

Please sign in to comment.