【问题标题】:Pod Security Policy not working as intendedPod 安全策略未按预期工作
【发布时间】:2019-07-30 20:59:12
【问题描述】:

我正在创建 Pod 安全策略以阻止所有用户将 Pod 创建为 Root 用户。我的集群在 GKE 上。 到目前为止,我执行的步骤是

1) 在我的集群中启用 PodSecurityPolicy

gcloud beta container clusters update standard-cluster-11  --enable-pod-security-policy

2) 定义策略。该策略很简单,并且限制了 root 用户。

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: a-restrict-root
spec:
  privileged: false
  runAsUser:
    rule: MustRunAsNonRoot  # <------ Root user restricted.
  seLinux:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - '*'

3) 然后当然要实施正确的 RBAC 规则,以便可以为所有用户实施。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gce:podsecuritypolicy:a-restrict-root
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/cluster-service: "true"
rules:
- apiGroups:
  - policy
  resourceNames:
  - a-restrict-root
  resources:
  - podsecuritypolicies
  verbs:
  - use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gce:podsecuritypolicy:a-restrict-root
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/cluster-service: "true"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: gce:podsecuritypolicy:a-restrict-root
subjects:
- kind: Group
  apiGroup: rbac.authorization.k8s.io
  name: system:serviceaccounts

现在是我尝试启动 Pod 的部分。 pod 定义如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 0
    fsGroup: 0
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: gcr.io/google-samples/node-hello:1.0
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      allowPrivilegeEscalation: false

如您所见,runAsUser 设置为 0,意思是 root

当我运行kubectl create -f pod.yaml 时,pod 正在创建并进入Running 状态。

当我执行到 Pod 中时,我可以看到所有进程都以 root 身份运行

$ kubectl exec -it security-context-demo -- sh
# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   4336   812 ?        Ss   19:25   0:00 /bin/sh -c node server.js
root           6  0.4  0.5 772124 22656 ?        Sl   19:25   0:00 node server.js
root          11  0.0  0.0   4336   724 ?        Ss   19:26   0:00 sh
root          16  0.0  0.0  17500  2072 ?        R+   19:26   0:00 ps aux

但根据我的 PodSecurityPolicy,这不应该被允许。有什么我错过的吗?

更新:

我启动了一个默认的 nginx pod,我知道它总是以 root 用户身份启动。它的清单是:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx

当我创建它时,它也成功启动了。

$ kubectl get po
NAME                    READY     STATUS    RESTARTS   AGE
nginx                   1/1       Running   0          2m

由于 PSP 的原因,它不应该启动。

【问题讨论】:

    标签: kubernetes google-kubernetes-engine


    【解决方案1】:

    如果您从 API 获取创建的 pod,它将包含一个注释,指示哪个 PSP 允许该 pod。我希望有一个不同的 PSP 允许 pod

    【讨论】:

    • 感谢您的指示。你确实给了我一个线索。它返回kubernetes.io/psp: gce.privileged。由于这是一个 GKE 集群,因此还有很多其他 psps,例如 gce.privilegedgce.persistent-volume-bindergce.unprivileged-addon 等。当我尝试删除它们时,它们会自动重新创建。知道如何永久禁用它们吗?
    • 特权策略被授予 kube-system 命名空间中的特定服务帐户。在不同的命名空间或使用专用服务帐户运行您的 pod 将避免继承 gce.privileged 权限
    【解决方案2】:

    我得到了你所缺少的,只需在你的 pod 配置文件中添加这个:

    在此之前,请确保在 Docker 容器中使用 create the user (say, appuser) uid -&gt; say, 999group (say, appgroup) gid -&gt;say, 999,然后尝试使用该用户启动容器并添加:

    securityContext:
      runAsUser: 999
    

    这可能是一个很好的阅读:SecurityContext

    另外,当你这样做时:

    apiVersion: v1
    kind: Pod
    metadata:
      name: security-context-demo
    spec:
      securityContext:
        runAsUser: 0
        fsGroup: 0
    

    您正在覆盖 PodSecurityPolicy 请参阅 here

    更新:1

    如何解决这个问题:

    apiVersion: extensions/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: a-restrict-root
    spec:
      privileged: false
      defautlAllowPrivilegeEscalation: false
      # This is redundant with non-root + disallow privilege escalation,
      # but we can provide it for defense in depth.
      requiredDropCapabilities:
        - ALL
      hostIPC: false
      hostPID: false
      runAsUser:
        # Require the container to run without root privileges.
        rule: 'MustRunAsNonRoot'
      seLinux:
        # This policy assumes the nodes are using AppArmor rather than SELinux.
        rule: 'RunAsAny'
      supplementalGroups:
        rule: 'MustRunAs'
        ranges:
          # Forbid adding the root group.
          - min: 1
            max: 65535
      fsGroup:
        rule: 'MustRunAs'
        ranges:
          # Forbid adding the root group.
          - min: 1
            max: 65535
    

    【讨论】:

    • 这将允许 Pod 以非 root 身份运行,这很好。我想要做的是阻止 root 在我的集群中运行。您的解决方案不会帮助我做到这一点。我要停止的 Pod 应该有 runAsUser: 0。我的 psp 方面缺少一些东西。
    • runAsUser ,它适用于所有容器,因此如果您想将其添加到该特定 pod 的所有容器中,则只需将其添加到 pod 规范中。根据文档:kubernetes.io/docs/tasks/configure-pod-container/… 这样您就可以强制执行没有以 root 开头的进程来强化容器。
    • 你需要看看这个未解决的问题 - github.com/kubernetes/enhancements/issues/213。我知道,设置 guid 听起来像是一种解决方法,但目前没有其他方法。
    • 当您将 runAsUser:0fsGroup:0 放入为容器指定的安全设置时,您将覆盖 pod 安全上下文。请查看更新后的答案。
    • 我提供的SecurityContext 是针对 Pod 而不是容器。我没有覆盖容器的任何上下文。我的目标不是以 NonRoot 或用户 999 的身份启动 Pod。我的目标是以 root 身份启动一个 pod,并让 PodSecurityPolicy 介入并阻止该 pod 运行,因为该 pod 是以 root 身份启动的。
    猜你喜欢
    • 2019-05-12
    • 2021-07-09
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 2021-10-03
    相关资源
    最近更新 更多