From 671a3e13442461316333e6e18edfe4b84f990a30 Mon Sep 17 00:00:00 2001 From: Max Erenberg Date: Thu, 23 Dec 2021 17:09:45 -0500 Subject: [PATCH] first commit --- README.md | 3 + csc-clusterroles.yaml | 105 +++++++++++++++++++++++++++ cscingressconstraint-constraint.yaml | 10 +++ cscingressconstraint-template.yaml | 47 ++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 README.md create mode 100644 csc-clusterroles.yaml create mode 100644 cscingressconstraint-constraint.yaml create mode 100644 cscingressconstraint-template.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..20db883 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Manifests + +A collection of miscellaneous Kubernetes manifests used by the Systems Committee. diff --git a/csc-clusterroles.yaml b/csc-clusterroles.yaml new file mode 100644 index 0000000..9a58abf --- /dev/null +++ b/csc-clusterroles.yaml @@ -0,0 +1,105 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csc-members-kubesystem +rules: +# This is necessary for "kubectl cluster-info" to work +- apiGroups: [""] + resources: ["services"] + verbs: ["list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: csc-members-kubesystem + namespace: kube-system +subjects: +- kind: Group + name: csc-members + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: csc-members-kubesystem + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csc-members-unnamespaced +rules: +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["networking.k8s.io"] + resources: ["ingressclasses"] + verbs: ["get", "list", "watch"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + resourceNames: + - csc-members-kubesystem + - csc-members-unnamespaced + - csc-members-default + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csc-members-unnamespaced +subjects: +- kind: Group + name: csc-members + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: csc-members-unnamespaced + apiGroup: rbac.authorization.k8s.io +--- +# This ClusterRole must be referenced by a RoleBinding in each member's namespace. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csc-members-default +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +rules: +- apiGroups: [""] + resources: + - configmaps + - endpoints + - events + - limitranges + - persistentvolumeclaims + - pods + - pods/attach + - pods/log + - podtemplates + - replicationcontrollers + - secrets + - services + verbs: ["*"] +- apiGroups: [""] + resources: ["resourcequotas"] + verbs: ["get", "list", "watch"] +- apiGroups: ["apps"] + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: ["*"] +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["*"] +- apiGroups: ["batch"] + resources: ["cronjobs", "jobs"] + verbs: ["*"] +- apiGroups: ["extensions", "networking.k8s.io"] + resources: ["ingresses"] + # use Open Policy Agent to restrict which domains can be used + verbs: ["*"] +- apiGroups: ["networking.k8s.io"] + resources: ["networkpolicies"] + verbs: ["*"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["roles", "rolebindings"] + verbs: ["get", "list", "watch"] diff --git a/cscingressconstraint-constraint.yaml b/cscingressconstraint-constraint.yaml new file mode 100644 index 0000000..739bf26 --- /dev/null +++ b/cscingressconstraint-constraint.yaml @@ -0,0 +1,10 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: CSCIngressConstraint +metadata: + name: cscingressconstraint +spec: + match: + kinds: + - apiGroups: ["networking.k8s.io"] + kinds: ["Ingress"] + namespaces: ["csc-*"] diff --git a/cscingressconstraint-template.yaml b/cscingressconstraint-template.yaml new file mode 100644 index 0000000..8107d84 --- /dev/null +++ b/cscingressconstraint-template.yaml @@ -0,0 +1,47 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: cscingressconstraint +spec: + crd: + spec: + names: + kind: CSCIngressConstraint + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package cscingressconstraint + + operations = {"CREATE", "UPDATE"} + subdomain = ".k8s.csclub.cloud" + + violation[{"msg": msg, "details": {}}] { + input.review.kind.kind == "Ingress" + operations[input.review.operation] + not is_admin_user(input.review.userInfo) + username := input.review.userInfo.username + host := input.review.object.spec.rules[_].host + not is_valid_domain(username, host) + msg := "Invalid domain name, please contact the Systems Committee for assistance" + } + + is_admin_user(userInfo) { + userInfo.groups[_] == "system:masters" + } + + is_valid_domain(username, host) { + endswith(host, subdomain) + prefix := trim_suffix(host, subdomain) + parts := split(prefix, ".") + last_part := parts[count(parts) - 1] + is_valid_last_part_of_prefix(username, last_part) + } + + is_valid_last_part_of_prefix(username, last_part) { + username == last_part + } + + is_valid_last_part_of_prefix(username, last_part) { + suffix := concat("", ["-", username]) + endswith(last_part, suffix) + }