WEBKT

大规模 Kubernetes 集群安全实战:如何应对未授权访问、容器逃逸与恶意镜像?

22 0 0 0

未授权访问:权限管理是第一道防线

容器逃逸:限制容器能力是关键

恶意镜像:镜像安全扫描不可或缺

作为一名 Kubernetes 管理员,我深知在生产环境中维护大型微服务集群安全的重要性。Kubernetes 本身虽然提供了许多安全机制,但默认配置往往不足以应对复杂的安全威胁。在实际工作中,我踩过不少坑,也积累了一些经验,今天就来分享一下我是如何通过配置网络策略、RBAC 权限控制、镜像安全扫描等手段,来解决 Kubernetes 安全挑战的。希望我的经验能帮助你更好地保护你的 Kubernetes 集群。

未授权访问:权限管理是第一道防线

Kubernetes 的 RBAC(Role-Based Access Control,基于角色的访问控制)是控制集群访问权限的关键。如果 RBAC 配置不当,就可能导致未授权用户访问敏感资源,甚至控制整个集群。我见过一些团队,为了方便开发,直接给所有用户授予 cluster-admin 权限,这简直就是把集群的钥匙拱手让人!

案例:权限膨胀导致的事故

曾经有个开发人员,因为需要频繁调试线上服务,就被授予了 cluster-admin 权限。后来,这位开发人员离职了,但他的账号却没有及时回收。结果,几个月后,有人利用这个账号,删除了生产环境的几个关键 Deployment,导致服务中断了好几个小时。事后调查发现,攻击者就是通过扫描 GitHub 找到这个泄露的 Kubernetes 配置文件,从而获得了集群的控制权。

如何避免权限膨胀?

  1. 最小权限原则: 只授予用户完成工作所需的最小权限。例如,只允许开发人员查看特定命名空间的 Pod 日志,不允许他们修改 Deployment。可以使用 Kubernetes 内置的 viewedit 等角色,也可以自定义角色,以满足更精细的权限控制需求。

  2. 权限分级: 将用户分为不同的角色,例如管理员、开发人员、测试人员等,并为每个角色分配不同的权限。可以使用 Kubernetes 的 RoleClusterRole 对象来定义角色,并使用 RoleBindingClusterRoleBinding 对象将角色绑定到用户或组。

  3. 定期审查: 定期审查 RBAC 配置,确保权限设置仍然合理。可以使用 kubectl get rolebindings --all-namespaces -o yamlkubectl get clusterrolebindings -o yaml 命令来查看 RBAC 配置,并手动检查是否存在不合理的权限授予。

  4. 使用 OIDC 集成: 将 Kubernetes 集群与 OIDC(OpenID Connect)身份提供商集成,例如 Google Identity Platform、Azure Active Directory 等。这样,用户就可以使用自己的组织账号登录 Kubernetes 集群,而无需创建额外的 Kubernetes 用户。OIDC 集成还可以实现更精细的权限控制,例如基于用户组的权限控制。

  5. 使用 Kubernetes Admission Controller: 使用 Kubernetes Admission Controller 来强制执行 RBAC 策略。Admission Controller 是 Kubernetes 的一个扩展点,可以在对象被创建、更新或删除之前,对对象进行验证和修改。可以使用 Gatekeeper、Kyverno 等工具来配置 Admission Controller,以强制执行 RBAC 策略,例如禁止创建具有 cluster-admin 权限的 RoleBinding。

示例:使用 Kyverno 强制执行 RBAC 策略

以下是一个使用 Kyverno 禁止创建具有 cluster-admin 权限的 RoleBinding 的策略:

apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: disallow-cluster-admin
annotations:
policies.kyverno.io/title: Disallow Cluster Admin
policies.kyverno.io/category: RBAC
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: RoleBinding
policies.kyverno.io/description: >-
Prevents the creation of RoleBindings which grant the cluster-admin
ClusterRole to any subject.
spec:
validationFailureAction: enforce
background: true
rules:
- name: check-cluster-admin
match:
any:
- resources:
kinds:
- RoleBinding
validate:
message: >-
Assigning the cluster-admin role is not allowed. Refer to internal
security guidelines for details.
deny:
conditions:
all:
- key: "{{ request.object.roleRef.name }}"
operator: Equals
value: cluster-admin

这个策略会拦截所有尝试创建将 cluster-admin 角色绑定到任何用户的 RoleBinding 请求,并拒绝该请求。

容器逃逸:限制容器能力是关键

容器逃逸是指攻击者从容器内部突破容器的隔离,获得宿主机的控制权。容器逃逸的危害非常大,攻击者可以利用宿主机的控制权,窃取敏感数据、破坏系统,甚至攻击其他容器。

案例:利用 Docker Socket 逃逸

我曾经遇到过一个案例,攻击者利用一个存在漏洞的 Web 应用,获得了容器的执行权限。然后,攻击者通过挂载宿主机的 Docker Socket,获得了宿主机的控制权。Docker Socket 是 Docker 守护进程的 Unix 域套接字,用于与 Docker 守护进程进行通信。如果容器可以访问 Docker Socket,就可以执行 Docker 命令,从而控制宿主机。

如何防止容器逃逸?

  1. 限制容器能力: 使用 Kubernetes 的 SecurityContext 对象来限制容器的能力。可以禁止容器执行特权操作、挂载敏感目录等。例如,可以设置 allowPrivilegeEscalation: false 来禁止容器提升权限,设置 readOnlyRootFilesystem: true 来将容器的根文件系统设置为只读。

  2. 使用 AppArmor 或 SELinux: 使用 AppArmor 或 SELinux 来限制容器的系统调用。AppArmor 和 SELinux 是 Linux 内核的安全模块,可以限制进程的系统调用,从而防止容器执行恶意操作。可以使用 Kubernetes 的 container.apparmor.security.beta.kubernetes.io 注解或 container.security.alpha.kubernetes.io/seccomp профиль 注解来配置 AppArmor 或 SELinux。

  3. 定期扫描容器镜像: 定期扫描容器镜像,发现潜在的安全漏洞。可以使用 Aqua Security、Trivy 等工具来扫描容器镜像,并及时修复发现的漏洞。

  4. 使用 Kubernetes Pod Security Admission: 使用 Kubernetes Pod Security Admission 来强制执行 Pod 安全策略。Pod Security Admission 是 Kubernetes 的一个内置特性,可以根据预定义的策略,限制 Pod 的配置。可以使用 Pod Security Admission 来禁止创建具有特权权限的 Pod,或者限制 Pod 的能力。

示例:使用 Pod Security Admission 限制 Pod 权限

以下是一个使用 Pod Security Admission 限制 Pod 权限的示例:

apiVersion: v1
kind: Namespace
metadata:
name: restricted-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted

这个配置会将 restricted-namespace 命名空间的 Pod 安全级别设置为 restrictedrestricted 级别是最严格的 Pod 安全级别,会禁止创建具有特权权限的 Pod,或者限制 Pod 的能力。

恶意镜像:镜像安全扫描不可或缺

容器镜像的安全问题日益突出,恶意镜像可能会包含病毒、木马、后门等恶意代码,一旦被部署到 Kubernetes 集群中,就会对整个集群造成威胁。

案例:Docker Hub 上的恶意镜像

我曾经在 Docker Hub 上发现过一些恶意镜像,这些镜像伪装成流行的软件,例如 Nginx、Redis 等,但实际上却包含了恶意代码。如果用户不小心下载并使用了这些镜像,就可能会被植入木马,导致数据泄露或系统被控制。

如何防范恶意镜像?

  1. 使用可信的镜像仓库: 尽量使用官方的镜像仓库,例如 Docker Hub 官方镜像、Google Container Registry 等。这些镜像仓库通常会对镜像进行安全扫描,并及时修复发现的漏洞。

  2. 验证镜像签名: 使用 Docker Content Trust 来验证镜像的签名。Docker Content Trust 可以确保镜像的完整性和来源,防止恶意用户篡改镜像。

  3. 定期扫描镜像: 定期扫描容器镜像,发现潜在的安全漏洞。可以使用 Aqua Security、Trivy 等工具来扫描容器镜像,并及时修复发现的漏洞。

  4. 构建自己的镜像: 尽量自己构建镜像,避免使用未经授权的第三方镜像。在构建镜像时,要遵循最佳实践,例如使用最小镜像、避免安装不必要的软件等。

  5. 使用 Kubernetes ImagePolicyWebhook: 使用 Kubernetes ImagePolicyWebhook 来强制执行镜像安全策略。ImagePolicyWebhook 是 Kubernetes 的一个扩展点,可以在镜像被拉取之前,对镜像进行验证。可以使用 ImagePolicyWebhook 来禁止拉取未经授权的镜像,或者强制拉取具有特定标签的镜像。

示例:使用 ImagePolicyWebhook 强制执行镜像安全策略

以下是一个使用 ImagePolicyWebhook 强制执行镜像安全策略的示例:

  1. 配置 ImagePolicyWebhook:

    首先,需要配置 Kubernetes 集群的 kube-apiserver,启用 ImagePolicyWebhook。需要在 kube-apiserver 的配置文件中添加以下配置:

    admission-control:
    plugin-names:
    - ImagePolicyWebhook
    imagePolicyWebhook:
    kubeconfig: /etc/kubernetes/imagepolicywebhook/config
    timeout: 30s

    其中,/etc/kubernetes/imagepolicywebhook/config 是 ImagePolicyWebhook 的配置文件,需要根据实际情况进行修改。

  2. 实现 ImagePolicyWebhook 服务:

    需要实现一个 ImagePolicyWebhook 服务,用于对镜像进行验证。该服务需要实现一个 HTTP endpoint,接收 Kubernetes 集群发送的镜像验证请求,并返回验证结果。验证结果可以是允许拉取镜像,也可以是拒绝拉取镜像。

    以下是一个简单的 ImagePolicyWebhook 服务示例:

    from flask import Flask, request, jsonify
    app = Flask(__name__)
    @app.route("/validate", methods=["POST"])
    def validate_image():
    request_json = request.get_json()
    image = request_json["request"]["object"]["spec"]["containers"][0]["image"]
    # 在这里进行镜像验证
    if image.startswith("my-registry.example.com/"):
    # 允许拉取来自 my-registry.example.com 的镜像
    return jsonify({"apiVersion": "admission.k8s.io/v1",
    "kind": "AdmissionReview",
    "response": {"uid": request_json["request"]["uid"],
    "allowed": True}})
    else:
    # 拒绝拉取其他镜像
    return jsonify({"apiVersion": "admission.k8s.io/v1",
    "kind": "AdmissionReview",
    "response": {"uid": request_json["request"]["uid"],
    "allowed": False,
    "status": {"reason": "Image not allowed"}}})
    if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

    这个示例服务会验证镜像是否来自 my-registry.example.com,如果不是,则拒绝拉取镜像。

  3. 配置 ImagePolicyWebhook 策略:

    需要在 Kubernetes 集群中配置 ImagePolicyWebhook 策略,指定使用哪个 ImagePolicyWebhook 服务进行镜像验证。可以使用 kubectl create 命令创建一个 MutatingWebhookConfigurationValidatingWebhookConfiguration 对象,指定 ImagePolicyWebhook 服务的地址。

总结:安全是持续的过程

Kubernetes 安全是一个持续的过程,需要不断地学习、实践和改进。我今天分享的只是一些基本的安全措施,还有很多其他的安全技术和方法可以应用到 Kubernetes 集群中。希望我的经验能帮助你更好地保护你的 Kubernetes 集群,让你的应用安全可靠地运行。

最后,我想强调几点:

  • 安全意识是第一位的。 只有所有人都意识到安全的重要性,才能真正做好 Kubernetes 安全。
  • 自动化安全策略。 使用工具来自动化安全策略的实施,可以减少人为错误,提高安全效率。
  • 持续监控和审计。 定期监控和审计 Kubernetes 集群的安全状态,及时发现和解决安全问题。

希望这些经验对你有所帮助!

K8s安全老司机 Kubernetes安全容器安全RBAC权限控制

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/9980