kube-psp-advisor
kube-psp-advisor copied to clipboard
WIP: Setting default psp
I want to set default PSP when converting.
kube-psp-advisor is very cool tool!! We use this tool for creating psp.
kube-psp-advisor convert
however makes some fields which are not defined in a manifest loose rules.
EX) Default setting of runAsUser is "RunAsAny".
We want to change these default settings. Therefore I have tried to make prototype which read default psp setting form a file.
If this idea is accepted, I do rest work to do.(Apply all fields, make tests...) How do you think?
I write example in following.
This is sample deployment manifest.
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2020-05-23T12:12:08Z"
generation: 1
labels:
k8s-app: kube-dns
name: coredns
namespace: kube-system
resourceVersion: "14048"
selfLink: /apis/apps/v1/namespaces/kube-system/deployments/coredns
uid: c0bb78cc-fbb3-4ede-9f95-1a54b87b8775
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kube-dns
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
k8s-app: kube-dns
spec:
containers:
- args:
- -conf
- /etc/coredns/Corefile
image: k8s.gcr.io/coredns:1.6.2
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 5
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
name: coredns
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /ready
port: 8181
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/coredns
name: config-volume
readOnly: true
dnsPolicy: Default
nodeSelector:
beta.kubernetes.io/os: linux
priorityClassName: system-cluster-critical
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: coredns
serviceAccountName: coredns
terminationGracePeriodSeconds: 30
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/master
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns
name: config-volume
status:
availableReplicas: 2
conditions:
- lastTransitionTime: "2020-05-23T12:12:15Z"
lastUpdateTime: "2020-05-23T12:12:24Z"
message: ReplicaSet "coredns-5644d7b6d9" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2020-05-30T07:17:32Z"
lastUpdateTime: "2020-05-30T07:17:32Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 1
readyReplicas: 2
replicas: 2
updatedReplicas: 2
This is sample default psp file.
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
seLinux:
rule: RunAsAny
runAsUser:
rule: MustRunAs
ranges:
- min: 1
max: 65535
fsGroup:
rule: RunAsAny
volumes:
- '*'
Without default psp file.
./kube-psp-advisor convert --podFile test-deploy.yaml --pspFile output-psp.yaml && cat output-psp.yaml [~/go/src/kube-psp-advisor]
INFO[2020-05-31T10:12:23+09:00] Wrote generated psp to output-psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
creationTimestamp: null
name: pod-security-policy-default-20200531101223
spec:
allowPrivilegeEscalation: false
defaultAddCapabilities:
- NET_BIND_SERVICE
fsGroup:
rule: RunAsAny
hostPorts:
- max: 0
min: 0
readOnlyRootFilesystem: true
requiredDropCapabilities:
- all
runAsGroup:
rule: RunAsAny
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- configMap
- secret
with default psp file
$ ./kube-psp-advisor convert --podFile test-deploy.yaml --pspFile output-psp.yaml --defaultPspFile ./test-psp.yaml && cat output-psp.yaml [~/go/src/kube-psp-advisor]
INFO[2020-05-31T10:13:05+09:00] Wrote generated psp to output-psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
creationTimestamp: null
name: pod-security-policy-default-20200531101305
spec:
allowPrivilegeEscalation: false
defaultAddCapabilities:
- NET_BIND_SERVICE
fsGroup:
rule: RunAsAny
hostPorts:
- max: 0
min: 0
readOnlyRootFilesystem: true
requiredDropCapabilities:
- all
runAsGroup:
rule: RunAsAny
runAsUser: <= replaced by default setting
ranges:
- max: 65535
min: 1
rule: MustRunAs
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- configMap
- secret
@paper2 thanks for PR, let me think about it and get back to you soon.
I have difficulty in making a psp because kube-psp-advisor sets required fields as loose policy automatically.
Therefore I want to set default psp firstly for only fsGroup, runAsUser, seLinux, supplementalGroups. If another want to set other fields, I make it.
in making a psp because kube-psp-advisor sets required fields as loose policy automatically.
I don't think that's the case. The default settings follow the psp default value. To me, your use case is having a customized default settings.
I don't think that's the case. The default settings follow the psp default value. To me, your use case is having a customized default settings.
That makes sense.
I originally thought this was about a customized default settings will take the priority over the suggested one. However, If you look at your example:
- the
runAsUser
in the customized default takes the precedence - the
volumes
in the customized default DID NOT takes the precedence.
This is some confusion I have. Probably you want to rethink about this PR as well as the customized default settings.
I originally thought this was about a customized default settings will take the priority over the suggested one.
My prototype uses the default psp when it can't suggest fields. Please let me show example following.
This is default psp file.
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
seLinux:
rule: RunAsAny
runAsUser:
rule: MustRunAs
ranges:
- min: 1
max: 65535
fsGroup:
rule: RunAsAny
volumes:
- '*'
This is a sample Deployment which has runAsUser
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
spec:
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
containers:
- args:
- -conf
- /etc/coredns/Corefile
image: k8s.gcr.io/coredns:1.6.2
imagePullPolicy: IfNotPresent
name: coredns
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
In this case, kube-psp-advisor can suggest RunAsUser
.
Even if I give a default psp file, kube-psp-advisor ignores the one.
$ ./kube-psp-advisor convert --podFile test-deploy.yaml --pspFile output-psp.yaml --defaultPspFile ./test-psp.yaml && cat output-psp.yaml [~/go/src/kube-psp-advisor]
INFO[2020-06-05T06:53:07+09:00] Wrote generated psp to output-psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
creationTimestamp: null
name: pod-security-policy-default-20200605065307
spec:
allowPrivilegeEscalation: false
defaultAddCapabilities:
- NET_BIND_SERVICE
fsGroup:
rule: RunAsAny
readOnlyRootFilesystem: true
requiredDropCapabilities:
- all
runAsGroup:
rule: RunAsAny
runAsUser:
ranges: <= kube-psp-advisor can suggest this and ignore default psp.
- max: 1000
min: 1000
rule: MustRunAs
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- secret
On the other hand, kube-psp-advisor uses the default psp settings when deployment has not RunAsUser
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
spec:
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
containers:
- args:
- -conf
- /etc/coredns/Corefile
image: k8s.gcr.io/coredns:1.6.2
imagePullPolicy: IfNotPresent
name: coredns
securityContext: <= Delete RunAsUser
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
$ ./kube-psp-advisor convert --podFile test-deploy.yaml --pspFile output-psp.yaml --defaultPspFile ./test-psp.yaml && cat output-psp.yaml [~/go/src/kube-psp-advisor]
INFO[2020-06-05T06:53:28+09:00] Wrote generated psp to output-psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
creationTimestamp: null
name: pod-security-policy-default-20200605065328
spec:
allowPrivilegeEscalation: false
defaultAddCapabilities:
- NET_BIND_SERVICE
fsGroup:
rule: RunAsAny
readOnlyRootFilesystem: true
requiredDropCapabilities:
- all
runAsGroup:
rule: RunAsAny
runAsUser: <= kube-psp-advisor uses the default psp.
ranges:
- max: 65535
min: 1
rule: MustRunAs
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- secret
Sorry for the confusion :(
securityContext: <= Delete RunAsUser
This is using the default value which is root user.
Let discuss the use case here, assuming there is a customized default psp (please allow me to add customized
), for individual constraint (runAsRoot, runAsGroup, volume etc.):
- If a constraint is more loose in the customized default psp, do you plan to stick with the original one suggested by psp-advisor?
- What if there are mismatches between the customized default psp and the original one suggested by psp-advisor: a. volumes: secret, configmap in default pap b. volumes: hostpath, secret in the original one suggested by psp-advisor
If a constraint is more loose in the customized default psp, do you plan to stick with the original one suggested by psp-advisor?
Yes. In my case, I basically want to use more restricted policy as much as possible.
What if there are mismatches between the customized default psp and the original one suggested by psp-advisor:
I want the result includes only the original suggested by psp-advisor. I assume this default settings is used when psp-advisor can't find explicit fields.
I want the result includes only the original suggested by psp-advisor. I assume this default settings is used when psp-advisor can't find explicit fields.
I don't understand. Please take a look:
//PodSecurityPolicy Recommendation System help in the following attributes:
// 1. allowPrivilegeEscalation - done
// 2. allowedCapabilities - done
// 3. allowedHostPaths - done
// 4. hostIPC - done
// 5. hostNetwork - done
// 6. hostPID - done
// 7. hostPorts - done
// 8. privileged - done
// 9. readOnlyRootFilesystem - done
// 10. runAsUser - done
// 11. runAsGroup - done
// 12. Volume - done
// 13. seLinux and others - need further investigation
type ContainerSecuritySpec struct {
Metadata Metadata `json:"parentMetadata"`
ContainerID string `json:"containerID"`
ContainerName string `json:"containerName"`
PodName string `json:"podName"`
Namespace string `json:"namespace"`
ImageName string `json:"imageName"`
ImageSHA string `json:"imageSHA"`
HostName string `json:"hostName"`
Capabilities []string `json:"effectiveCapabilities,omitempty"`
DroppedCap []string `json:"droppedCapabilities,omitempty"`
AddedCap []string `json:"addedCapabilities,omitempty"`
Privileged bool `json:"privileged,omitempty"`
ReadOnlyRootFS bool `json:"readOnlyRootFileSystem,omitempty"`
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty"`
RunAsUser *int64 `json:"runAsUser,omitempty"`
RunAsGroup *int64 `json:"runAsGroup,omitempty"`
HostPorts []int32 `json:"hostPorts,omitempty"`
ServiceAccount string `json:"serviceAccount,omitempty"`
}
If a manifest read by psp-advisor has no volume field, psp-advisor set psp customized default psp. If a manifest read by psp-advisor has one or more volume field, psp-advisor set psp these volume and ignroe customized default psp.
a. volumes: secret, configmap in (customized) default pap b. volumes: hostpath, secret in the original one suggested by psp-advisor
Above case, psp-advisor ignores customized default psp and suggest only hostpath and secret only.
Convert command creates a psp using a source manifest. If source manifest has not explicit fields(e.g. runAsUser), psp-advisor use default value of securityContext. In this case only, I want to use customized default psp. If source manifest has an explicit fields(e.g. runAsUser), psp-advisor suggests psp which fit to the fields. In this case, I want to use suggested one and ignore customized default psp.
Convert command creates a psp using a source manifest. If source manifest has not explicit fields(e.g. runAsUser), psp-advisor use default value of securityContext. In this case only, I want to use customized default psp. If source manifest has an explicit fields(e.g. runAsUser), psp-advisor suggests psp which fit to the fields. In this case, I want to use suggested
Now I understand what you suggested. This may complicates the use case. I need to think about it.