Using PSP

The Linkerd control plane comes with its own minimally privilegedPod Security Policyand the associated RBAC resources. This Pod Security Policy is enforced only ifthe PodSecurityPolicy admission controller is enabled.

To view the definition of the control plane’s Pod Security Policy, run:

  1. kubectl describe psp -l linkerd.io/control-plane-ns=linkerd

Adjust the value of the above label to match your control plane’s namespace.

Notice that to minimize attack surface, all Linux capabilities are dropped fromthe control plane’s Pod Security Policy, with the exception of the NET_ADMINand NET_RAW capabilities. These capabilties provide the proxy-init initcontainer with runtime privilege to rewrite the pod’s iptable. Note that addingthese capabilities to the Pod Security Policy doesn’t make the container aprivilegedcontainer. The control plane’s Pod Security Policy prevents container privilegeescalation with the allowPrivilegeEscalation: false policy. To understand thefull implication of the NET_ADMIN and NET_RAW capabilities, refer to theLinux capabilities manual.

More information on the iptables rules used by the proxy-init initcontainer can be found on the Architecturepage.

If your environment disallows the operation of containers with escalated Linuxcapabilities, Linkerd can be installed with its CNI plugin,which doesn’t require the NET_ADMIN and NET_RAW capabilities.

Linkerd doesn’t provide any default Pod Security Policy for the data planebecause the policies will vary depending on the security requirements of yourapplication. The security context requirement for the Linkerd proxy sidecarcontainer will be very similar to that defined in the control plane’s PodSecurity Policy.

For example, the following Pod Security Policy and RBAC will work with the injectedemojivoto demo application:

  1. apiVersion: policy/v1beta1
  2. kind: PodSecurityPolicy
  3. metadata:
  4. name: linkerd-emojivoto-data-plane
  5. spec:
  6. allowPrivilegeEscalation: false
  7. fsGroup:
  8. ranges:
  9. - max: 65535
  10. min: 10001
  11. rule: MustRunAs
  12. readOnlyRootFilesystem: true
  13. allowedCapabilities:
  14. - NET_ADMIN
  15. - NET_RAW
  16. - NET_BIND_SERVICE
  17. requiredDropCapabilities:
  18. - ALL
  19. runAsUser:
  20. rule: RunAsAny
  21. seLinux:
  22. rule: RunAsAny
  23. supplementalGroups:
  24. ranges:
  25. - max: 65535
  26. min: 10001
  27. rule: MustRunAs
  28. volumes:
  29. - configMap
  30. - emptyDir
  31. - projected
  32. - secret
  33. - downwardAPI
  34. - persistentVolumeClaim
  35. ---
  36. apiVersion: rbac.authorization.k8s.io/v1
  37. kind: Role
  38. metadata:
  39. name: emojivoto-psp
  40. namespace: emojivoto
  41. rules:
  42. - apiGroups: ['policy','extensions']
  43. resources: ['podsecuritypolicies']
  44. verbs: ['use']
  45. resourceNames: ['linkerd-emojivoto-data-plane']
  46. ---
  47. apiVersion: rbac.authorization.k8s.io/v1
  48. kind: RoleBinding
  49. metadata:
  50. name: emojivoto-psp
  51. namespace: emojivoto
  52. roleRef:
  53. apiGroup: rbac.authorization.k8s.io
  54. kind: Role
  55. name: emojivoto-psp
  56. subjects:
  57. - kind: ServiceAccount
  58. name: default
  59. namespace: emojivoto
  60. - kind: ServiceAccount
  61. name: emoji
  62. namespace: emojivoto
  63. - kind: ServiceAccount
  64. name: voting
  65. namespace: emojivoto
  66. - kind: ServiceAccount
  67. name: web
  68. namespace: emojivoto

Note that the Linkerd proxy only requires the NET_ADMIN and NET_RAWcapabilities, and it’s run with UID 2102. The NET_BIND_SERVICE capability isneeded by the web application because its container binds to port 80.