blob: 0f8d3d858873d7745215dab9515d4ffd0b0034fe [file] [log] [blame]
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +02001local kube = import "kube.libsonnet";
2
3{
4 local policies = self,
5
6 policyNameAllowInsecure: "policy:allow-insecure",
7 policyNameAllowSecure: "policy:allow-secure",
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +02008 policyNameAllowMostlySecure: "policy:allow-mostlysecure",
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +02009
Sergiusz Bazanski35d43782020-06-24 22:18:13 +020010 # egrep 'define CAP_[A-Z_]+.+[0-9]+$' include/linux/capability.h | cut -d' ' -f 2 | tr '\n' ','
11 local allCapsStr = 'CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_DAC_READ_SEARCH,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_SETGID,CAP_SETUID,CAP_SETPCAP,CAP_LINUX_IMMUTABLE,CAP_NET_BIND_SERVICE,CAP_NET_BROADCAST,CAP_NET_ADMIN,CAP_NET_RAW,CAP_IPC_LOCK,CAP_IPC_OWNER,CAP_SYS_MODULE,CAP_SYS_RAWIO,CAP_SYS_CHROOT,CAP_SYS_PTRACE,CAP_SYS_PACCT,CAP_SYS_ADMIN,CAP_SYS_BOOT,CAP_SYS_NICE,CAP_SYS_RESOURCE,CAP_SYS_TIME,CAP_SYS_TTY_CONFIG,CAP_MKNOD,CAP_LEASE,CAP_AUDIT_WRITE,CAP_AUDIT_CONTROL,CAP_SETFCAP,CAP_MAC_OVERRIDE,CAP_MAC_ADMIN,CAP_SYSLOG,CAP_WAKE_ALARM,CAP_BLOCK_SUSPEND,CAP_AUDIT_READ',
12 // Split by `,`, remove CAP_ prefix, turn into unique set.
13 local allCaps = std.set(std.map(function(el) std.substr(el, 4, std.length(el)-4), std.split(allCapsStr, ','))),
14
15
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020016 Cluster: {
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +020017 local cluster = self,
18
19 // Insecure: allowing creation of these pods allows you to pwn the entire cluster.
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020020 insecure: kube._Object("policy/v1beta1", "PodSecurityPolicy", "insecure") {
21 spec: {
22 privileged: true,
23 allowPrivilegeEscalation: true,
24 allowedCapabilities: ['*'],
25 volumes: ['*'],
26 hostNetwork: true,
Serge Bazanskic33ebcc2019-11-01 18:43:45 +010027 hostPorts: [
28 { max: 40000, min: 1 },
29 ],
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020030 hostIPC: true,
31 hostPID: true,
32 runAsUser: {
33 rule: 'RunAsAny',
34 },
35 seLinux: {
36 rule: 'RunAsAny',
37 },
38 supplementalGroups: {
39 rule: 'RunAsAny',
40 },
41 fsGroup: {
42 rule: 'RunAsAny',
43 },
44 },
45 },
46 insecureRole: kube.ClusterRole(policies.policyNameAllowInsecure) {
47 rules: [
48 {
49 apiGroups: ['policy'],
50 resources: ['podsecuritypolicies'],
51 verbs: ['use'],
52 resourceNames: ['insecure'],
53 }
54 ],
55 },
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +020056
57 // Secure: very limited subset of security policy, everyone is allowed
58 // to spawn containers of this kind.
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020059 secure: kube._Object("policy/v1beta1", "PodSecurityPolicy", "secure") {
60 spec: {
61 privileged: false,
62 # Required to prevent escalations to root.
63 allowPrivilegeEscalation: false,
64 # This is redundant with non-root + disallow privilege escalation,
65 # but we can provide it for defense in depth.
66 requiredDropCapabilities: ["ALL"],
67 # Allow core volume types.
68 volumes: [
69 'configMap',
70 'emptyDir',
71 'projected',
72 'secret',
73 'downwardAPI',
74 'persistentVolumeClaim',
75 ],
76 hostNetwork: false,
77 hostIPC: false,
78 hostPID: false,
79 runAsUser: {
80 # Allow to run as root - docker, we trust you here.
81 rule: 'RunAsAny',
82 },
83 seLinux: {
84 rule: 'RunAsAny',
85 },
86 supplementalGroups: {
87 rule: 'MustRunAs',
88 ranges: [
89 {
90 # Forbid adding the root group.
91 min: 1,
92 max: 65535,
93 }
94 ],
95 },
96 fsGroup: {
97 rule: 'MustRunAs',
98 ranges: [
99 {
100 # Forbid adding the root group.
101 min: 1,
102 max: 65535,
103 }
104 ],
105 },
106 readOnlyRootFilesystem: false,
Sergiusz Bazanski35d43782020-06-24 22:18:13 +0200107
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200108 },
109 },
110 secureRole: kube.ClusterRole(policies.policyNameAllowSecure) {
111 rules: [
112 {
113 apiGroups: ['policy'],
114 resources: ['podsecuritypolicies'],
115 verbs: ['use'],
116 resourceNames: ['secure'],
117 },
118 ],
119 },
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +0200120
Sergiusz Bazanski35d43782020-06-24 22:18:13 +0200121 // MostlySecure: like secure, but allows for setuid inside containers
122 // and enough filesystem access to run apt.
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +0200123 mostlySecure: cluster.secure {
124 metadata+: {
125 name: "mostlysecure",
126 },
127 spec+: {
Sergiusz Bazanski35d43782020-06-24 22:18:13 +0200128 requiredDropCapabilities: std.setDiff(allCaps, [
129 // Drop everything apart from:
130 "CHOWN",
131 "DAC_OVERRIDE",
132 "FOWNER",
133 "LEASE",
134 "SETGID",
135 "SETUID",
136 ]),
137 supplementalGroups: {
138 // Allow running as root gid - we allow running as root
139 // uid anyway, as we trust our container runtime.
140 rule: 'MustRunAs',
141 ranges: [
142 { min: 0, max: 65535, },
143 ],
144 },
145 fsGroup: {
146 // Allow setting the fsGroup to 0, as all filesystem mounts
147 // are trusted anyway.
148 rule: 'MustRunAs',
149 ranges: [
150 { min: 0, max: 65535, },
151 ],
152 },
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +0200153 },
154 },
155 mostlySecureRole: kube.ClusterRole(policies.policyNameAllowMostlySecure) {
156 rules: [
157 {
158 apiGroups: ['policy'],
159 resources: ['podsecuritypolicies'],
160 verbs: ['use'],
161 resourceNames: ['mostlysecure'],
162 },
163 ],
164 },
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200165 },
166
167 # Allow insecure access to all service accounts in a given namespace.
168 AllowNamespaceInsecure(namespace): {
169 rb: kube.RoleBinding("policy:allow-insecure-in-" + namespace) {
170 metadata+: {
171 namespace: namespace,
172 },
173 roleRef_: policies.Cluster.insecureRole,
174 subjects: [
175 {
176 kind: "Group",
177 apiGroup: "rbac.authorization.k8s.io",
178 name: "system:serviceaccounts",
179 }
180 ],
181 },
182 },
Sergiusz Bazanskie3432ee2020-05-11 20:16:44 +0200183
184 # Allow mostlysecure access to all service accounts in a given namespace.
185 AllowNamespaceMostlySecure(namespace): {
186 rb: kube.RoleBinding("policy:allow-mostlysecure-in-" + namespace) {
187 metadata+: {
188 namespace: namespace,
189 },
190 roleRef_: policies.Cluster.mostlySecureRole,
191 subjects: [
192 {
193 kind: "Group",
194 apiGroup: "rbac.authorization.k8s.io",
195 name: "system:serviceaccounts",
196 }
197 ],
198 },
199 },
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200200}