Skip to content

Suggesting more restrictive k8s RBAC and PSP #662

Open
@bygui86

Description

@bygui86

Describe the bug:
I think that RBAC and PSP applied to logging-operator, fluent-bit and fluentd are too permissive.

Proposal:
I propose following RBAC and PSP to restrict as much as possible permissions to components, without jeopardizing or influencing normal functionalities:

operator RBAC + PSP:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: logging-restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  runtime/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName:  runtime/default
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - configMap
    - secret
    - persistentVolumeClaim
    - emptyDir
    - projected
    - downwardAPI
  hostPID: false
  hostIPC: false
  hostNetwork: false
  runAsUser:
    rule: MustRunAsNonRoot
  runAsGroup:
    rule: MustRunAs
    ranges:
      - min: 100
        max: 65535
  supplementalGroups:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  seLinux:
    rule: RunAsAny
  readOnlyRootFilesystem: true
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: logging-operator
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: logging-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: logging-operator
subjects:
  - kind: ServiceAccount
    name: logging-operator
    namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: logging-operator
rules:
  - apiGroups:
      - policy
    resources:
      - podsecuritypolicies
    verbs:
      - use
    resourceNames:
      - logging-restricted
  - apiGroups:
      - batch
    resources:
      - jobs
    verbs:
      - "*"
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: logging-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: logging-operator
subjects:
  - kind: ServiceAccount
    name: logging-operator
    namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: logging-operator
rules:
  - apiGroups:
      - policy
    resources:
      - podsecuritypolicies
    verbs:
      - use
    resourceNames:
      - logging-restricted
  - apiGroups:
      - monitoring.coreos.com
    resources:
      - servicemonitors
      - podmonitors
      - prometheusrules
    verbs:
      - "*"
  - apiGroups:
      - apiextensions.k8s.io
    resources:
      - customresourcedefinitions
    verbs:
      - list
      - watch
  - apiGroups:
      - logging.banzaicloud.io
    resources:
      - "*"
    verbs:
      - "*"
  - apiGroups:
      - ""
    resources:
      - nodes
      - namespaces
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - pods
      - services
      - endpoints
      - configmaps
      - secrets
      - persistentvolumeclaims
    verbs:
      - "*"
  - apiGroups:
      - apps
    resources:
      - deployments
      - daemonsets
      - statefulsets
    verbs:
      - "*"
  - apiGroups:
      - ""
      - rbac.authorization.k8s.io
    resources:
      - serviceaccounts
      - roles
      - rolebindings
      - clusterroles
      - clusterrolebindings
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - policy
    resources:
      - podsecuritypolicies
    verbs:
      - get
      - list
      - watch

fluent-bit RBAC + PSP:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: logging-fluentbit-restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  runtime/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName:  runtime/default
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  hostPID: false
  hostIPC: false
  hostNetwork: false
  runAsGroup:
    rule: MustRunAs
    ranges:
      - min: 100
        max: 65535
  supplementalGroups:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  seLinux:
    rule: RunAsAny
  readOnlyRootFilesystem: true
  # DIFFERENCES from logging-restricted
  volumes:
    - configMap
    - secret
    - emptyDir
    - hostPath
  allowedHostPaths:
    # why this folder even considering it's empty? anyway read only...
    - pathPrefix: /var/lib/docker/containers
      readOnly: true
    - pathPrefix: /var/log
      readOnly: false
  runAsUser:
    rule: RunAsAny
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: logging-fluentbit
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: logging-fluentbit
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: logging-fluentbit
subjects:
- kind: ServiceAccount
  name: logging-fluentbit
  namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: logging-fluentbit
rules:
  - apiGroups:
      - policy
    resources:
      - podsecuritypolicies
    verbs:
      - use
    resourceNames:
      - logging-fluentbit-restricted
  - apiGroups:
    - ""
    resources:
    - pods
    - namespaces
    verbs:
    - get
    - list
    - watch

fluentd RBAC + PSP:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: logging-fluentd-restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  runtime/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName:  runtime/default
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  hostPID: false
  hostIPC: false
  hostNetwork: false
  runAsUser:
    rule: MustRunAsNonRoot
  runAsGroup:
    rule: MustRunAs
    ranges:
      - min: 100
        max: 65535
  supplementalGroups:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: MustRunAs
    ranges:
      - min: 1
        max: 65535
  seLinux:
    rule: RunAsAny
  # DIFFERENCES from logging-restricted
  volumes:
    - configMap
    - secret
    - persistentVolumeClaim
    - emptyDir
    - hostPath
  # readOnlyRootFilesystem: true
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: logging-fluentd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: logging-fluentd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: logging-fluentd
subjects:
  - kind: ServiceAccount
    name: logging-fluentd
    namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: logging-fluentd
rules:
  - apiGroups:
      - policy
    resources:
      - podsecuritypolicies
    verbs:
      - use
    resourceNames:
      - logging-fluentd-restricted
  - apiGroups:
      - ""
    resources:
      - configmaps
      - secrets
    verbs:
      - "*"

logging usage example:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Logging
metadata:
  name: logging-components
spec:
  enableRecreateWorkloadOnImmutableFieldChange: true
  controlNamespace: logging
  fluentbit:
    metrics:
      serviceMonitor: true
    tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      - operator: Exists
        effect: NoExecute
      - operator: Exists
        effect: NoSchedule
    security:
      roleBasedAccessControlCreate: false
      podSecurityPolicyCreate: false
      serviceAccount: logging-fluentbit
      podSecurityContext:
        fsGroup: 101
  fluentd:
    scaling:
      replicas: 3
    metrics:
      serviceMonitor: true
    livenessDefaultCheck: true
    security:
      roleBasedAccessControlCreate: false
      podSecurityPolicyCreate: false
      serviceAccount: logging-fluentd
      securityContext:
        readOnlyRootFilesystem: false
      podSecurityContext:
        runAsUser: 100
        runAsGroup: 100
        fsGroup: 101

Environment details:
Above proposal were tested on an environment with following details:

  • Kubernetes version: v1.17.14
  • Cloud-provider/provisioner: GKE
  • logging-operator version: 3.8.3
  • Install method: static manifests

Looking forward your feedback!!

/kind bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions