Kubernetes安全机制(一)

常见安全攻击面描述

安全攻击面

图片来源网络

image

外部访问攻击:核心组件非安全端口对外暴露,以及连接集群关键凭证泄漏。

平台组件攻击:  利用平台组件docker、kube-apiserver、etcd、kubelet 非安全端口对外暴露,以及集群组件间连接安全,以及组件的安全漏洞进行攻击。

POD层面攻击:利用运行在集群内的恶意POD进行攻击。

安全矩阵

图片来源网络
image

安全问题案例

图片来源网络image

2018年黑客入侵了特斯拉在亚马逊上的Kubernetes容器集群。由于该集群控制台未设置密码保护,黑客便得以在一个Kubernetes pod中获取到访问凭证,然后据此访问其网络存储桶S3,通过S3获取到了一些敏感数据,比如遥测技术,并且还在特斯拉的Kubernetes pod中进行挖矿。

安全攻击点—DockerDaemon公网暴露

image

Docker本身是C/S架构,Docker-client连接Docker-Daemon对docker进行操作。

Client连接Daemon有以下常见方式:
1、tcp://host:port
2、unix://path_to_socket
3、fd://socketfd。

若通过TCP方式将dockerDaemon对外暴露,攻击者可以通过Api接口接管本地Docker服务。

安全攻击点—包含恶意程序的镜像

图片来源网络

image

图片来源网络

image

安全攻击点—组件安全漏洞利用风险

图片来源网络

image

利用平台docker、k8s组件漏洞进行攻击如:
Docker Runc逃逸漏洞
此漏洞允许以root身份运行的容器以特权用户身份在主机上执行任意代码。这意味着容器可能会破坏Docker主机(覆盖Runc CLI),而所需要的只是能够使用root来运行容器。攻击者可以使用受感染的Docker镜像或对未受感染的正在运行的容器运行exec命令。

漏洞影响:
运行那些从不受信任的来源处获取到的镜像,那么其主机很有可能被攻击者所全面接收。

安全攻击点—容器特权模式逃逸

图片来源网络

image

特权模式容器允许允许容器内的root拥有外部物理机的root权限, ,可以直接获取宿主机设备文件访问权限。

可以通过mount命令将宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限。

安全攻击点—利用挂载目录逃逸

图片来源网络

image

将宿主机部分核心目录以写权限挂载进容器内,攻击者进入容器内可以对这些目录进行修改,如利用crontab定义一些执行脚本,来达到破坏目的。

安全攻击点—利用Linux Capabilities逃逸

图片来源网络

image

Linux Capabilities将root用户关联的特权拆分为一个个单元,每个单元可以独立启用和禁用,来达到细粒化权限控制。

容器通过cgroup和Namespace实现资源隔离同时也支持通过Capabilities进行细粒化权限管理,docker和k8s都是通过白名单方式添加Capabilities。如添加CAP_SYS_PTRACE特性在配合pid=host参数可以实现在容器内使用strance进行宿主机的进程追踪。

安全攻击点—利用Linux Capabilities逃逸

图片来源网络

image
图片来源网络

image

安全攻击点—凭证泄漏

图片来源网络

image

公有云上平台凭证泄漏,导致可以直接获取访问Kubernetes平台的连接信息,对Kubernetes进行控制和操作。

防范机制

平台安全框架

认证(Authenticating)是服务端对客户端请求的合法性鉴别。

授权(Authorization)是对访问资源的授权,当一个请求经过认证后,需要访问某一个资源(比如创建一个pod),授权检查都会通过访问策略比较该请求上下文的属性,(比如用户,资源和Namespace),根据授权规则判定该资源(比如某namespace下的pod)是否是该客户可访问的。

准入(Admission Control)机制是一种请求拦截机制,用于对请求的资源对象进行校验,修改。如Istio中的自动在对应namespace的POD中自动注入sidecar。

Kubernetes组件安全机制

图片来源网络

image

1、全部组件都需要连接Api-server,默认情况下使用 TLS 对集群中其他组件到 Api-server 通信进行加密。

2、组件通过对应的ServiceAccount运行,通过RBAC进行授权限制。

3、限制etcd访问,集群中只有api-server能够访问ETCD,并且对于etcd的访问采用TLS客户端证书相互认证。

4、kubelet做为apiserver获取节点pod信息的入口,启用身份验证和授权。

认证机制

  • X509 Client Certs

  • Static Token File

  • Bootstrap Tokens

  • Static Password File

  • Service Account Tokens

  • OpenID Connect Tokens

X509 Client Certs

图片来源网络

image

双向数字证书认证,HTTPS证书认证,是基于CA根证书签名的双向数字证书认证方式,是所有认证方式中最严格的认证。也是Kubernetes默认认证方式,组件之间以及外部客户端认证方式。

Api-Server相关的三个启动参数:

  • client-ca-file: 指定CA根证书文件为/etc/kubernetes/pki/ca.pem
  • tls-private-key-file: 指定ApiServer私钥文件为/etc/kubernetes/pki/apiserver-key.pem
  • tls-cert-file:指定ApiServer证书文件为/etc/kubernetes/pki/apiserver.pem

Service Account Tokens

图片来源网络

image

用于控制集群内部POD对象访问API-server.

Kubernetes会为每个namespace自动创建一个默认的service account资源,并命名为”default”。

创建POD时没有明确指定ServiceAccount,将会以default的ServiceAccount挂载到POD中。

授权机制

ABAC: ABAC(基于属性的访问控制):ABAC控制权限的粒度非常细,非常灵活;属性通常来说分为四类:用户属性、环境属性、操作属性、对象属性;ABAC通过动态的控制一组属性是否满足条件来进行授权判断。优点:权限控制的粒度非常细,非常灵活。缺点:太过于复杂。例如规则:“禁止所有学生在上课时间进出校门”这条规则,其中,“学生”是用户的角色属性,“上课时间”是环境属性,“进出”是操作属性,而“校门”就是对象属性了。

RBAC:引入角色概念,通过将权限和角色关联,来实现用户根权限的解耦,角色可以看做是权限的一个集合。通过权限与角色关联,角色与用户的关联可以实现用户和角色多对多的对应关系。

RBAC的模型
Who是否可以对What进行How的访问操作
kubernetes之前的版本都是使用ABAC做为权限管理控制,在kubernetes1.3发布alpha版本RBAC,在kubernetes1.6版本RBAC提升为Beta版,kubernetes1.8版本正式提升为GA版,为什么用RBAC取代ABAC是因为在kubernetes中ABAC过于复杂,不好管理,难以理解,RBAC相对功能和可管理性来说更加合适kubernetes。所以说没有更好,只有更合适。

image

RBAC(Role base access control): k8s上发展过程:
1.3 Alpha,1.6 Beta 1.8 GA

概念:
引入角色概念,通过将权限和角色关联,来实现用户根权限的解耦,角色可以看做是权限的一个集合。通过权限与角色关联,角色与用户的关联可以实现用户和角色多对多的对应关系。

优点 :
将权限与角色关联,用户关联角色,根传统用户关联权限相比这样权限控制更加灵活 。

控制粒度更细,可以对单个资源对象的做权限的分配。
缺点:
复杂度较高,有一定学习成本。

角色:
Kubernetes中的RBAC定义了两类角色

Role:
role是一组权限的集合, 例如一个角色可以包含读取 Pod 的权限和列出 Pod 的权限。Role 只能用来给某个特定 namespace 中的资源作鉴权 。

ClusterRole:
clusterrole根role一样也是一组权限的集合,cluster范围的Role,但clusterrole的有效范围是整个集群的权限和一些集群级别的资源如:集群的node节点、非资源类型endpoint、跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods –all-namespaces来查询集群中所有的pod)。

image

Role:
Resource:表示控制的资源对象,可以是pod,当然也可以是namespace级别的其他资源如:Service,secrets,pvc,configmap等。

Verbs:表示控制的权限操作,因为安全认证是通过api-server来完成的,api-server支持的10种权限操作为”get”, “ list “, “watch “,”create”,”update”, “patch”, “delete”,”deletecollection”,”redirect”,”proxy”]

image

ClusterRole:

Resource:ClusterRole定义的资源对象是集群层面的或需要进行跨多个namespace的资源控制

Verbs:根role一样

image

有了角色后,需要将这些角色根对应对象绑定起来,这样才能完成一次权限的分配,根Role和ClusterRole是对应的角色的棒定也分两种RoleBinding和ClusterRoleBinding 。

RoleBinding & ClusterRoleBinding :

Subjects:关联的对象类型,在k8s主要分为三种user,group,ServiceAccount

roleRef:为bind的对象,如果你是role,kind就写role是Clusterrolekind就写ClusterRole,name为对象的名字。

image

image

默认的Role和ClusterRole

api-service会默认创建一些role和rolebinding 和clusterrole和clusterrolebind,他们默认都是以system开头的,以system开头的都是为kubernetes系统使用而保留。

clusterrole里面cluster-admin、admin、edit、view这几个clusterrole,直接参考https://v1-8.docs.kubernetes.io/docs/admin/authorization/rbac/ cluster-admin、admin、edit、view这几个角色是不包含system前缀的,他们是面向用户的角色,可以直接使用rolebind直接使用。

User和ServiceAccount

Kubernetes 集群中包含两类用户:一类是由 Kubernetes 管理的 service account,另一类是普通用户。
普通用户
假定为由外部独立服务管理。管理员分发私钥,用户存储(如 Keystone 或 Google 帐户),甚至包含用户名和密码列表的文件。在这方面,Kubernetes 没有代表普通用户帐户的对象。无法通过 API 调用的方式向集群中添加普通用户。

Service Account
是由 Kubernetes API 管理的帐户。是用于POD中的进程访问API-Service的,为POD中的进程提供一个身份标识。

为什么用ServiceAccount?
通过ServiceAccount可以更精确控制POD内应用访问集群权限。

User和ServiceAccount

kubernetes在每个namespace内都有一个默认的service account,当在创建pod或其他资源时,没有手工指定Service account时会默认使用namespace里面这个default这个Service account

image

一般来说为了安全起见,建议一个应用使用一个独立的Service account运行,这样RoleBindings就不会无意中授予其他应用程序的权限,如果需要这样使用的话在部署yaml文件中添加

准入控制机制—Admission Control

image

准入(Admission Control)机制是一种请求拦截机制,用于对请求的资源对象进行校验。

包含两个控制器:
变更(Mutating)准入控制:修改请求的对象
验证(Validating)准入控制:验证请求的对象

当请求到达 API Server 的时候首先执行变更准入控制,然后再执行验证准入控制。

默认的控制策略

image

OPA介绍
image

开源的通用策略引擎,可以统一进行请求策略控制。OPA通过一种高级声明性语言(Rego)来定义策略配置规则,实现对请求的控制。

在Kubernetes中,admission在创建,更新和删除操作期间强制执行对象的语义验证,需要重新编译或重新配置Kubernetes API服务器。但使用OPA,直接可以在Kubernetes对象上实施自定义策略

配合强大的声明式策略语言Rego,直接通过K8S对象配置规则。

Service可以是以下任意:

  • Kubernetes API server
  • API gateway
  • Custom service
  • CI/CD pipeline


OPA介绍—Gatekeeper
image

Gatekeeper的创建是为了让用户能够通过配置(而不是代码)定制许可控制。

  • 通过CRD和模板定义,
  • 可分享,可重复使用,
  • 参数化配置

集群当前状态的可知和反馈,并非仅仅操作或下发策略的人员知晓
更方便与其他系统集成,如CI/CD

POD安全策略

image

POD直接运行在宿主机上可以映射宿主机的端口和使用宿主机网络,共享宿主机的内核,这样情况下会一定的安全风险,可以通过配置POD安全策略限制并约束POD的一些行为。PodSecurityPolicy对象定义了一组条件,指示 Pod 必须按系统所能接受的设定运行。

image

网络安全策略

image

概述:

Kubernetes的一个重要特性就是要把不同node节点的pod(container)连接起来,无视物理节点的限制。但是在某些应用环境中,比如公有云,不同租户的pod不应该互通,这个时候就需要网络隔离。Kubernetes提供了NetworkPolicy,支持按Namespace级别的网络隔离。Network Policy提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量

先决条件
kubernetes NetworkPolicy是通过调用对应的网络组件的policy功能来实现的,像weave和calico、cilium自带policy组件来实现功能,但flannel本身是没有这个的,但flannel可以通过直接使用calico的calico-controler组件来实现这个功能

网络策略是用来约束pod组与彼此和其他网络端点通信的规范
通过标签来筛选pods
定义Ingress与Egress流量与规则
应用场景:
1、多租户网络隔离、不同级别业务系统策略控制
2、内外部业务系统请求细粒化控制限制

镜像安全扫描

image

  • 镜像仓库集成镜像漏洞扫描,镜像仓库内镜像进行CVE漏洞扫描

  • 配置扫描策略,上传后立刻扫描,超过定义的高风险漏洞就禁止pull镜像。

  • 定期同步外网漏洞仓库

镜像签名

image

通过在容器镜像中可以对镜像进行加密签名用来保证镜像件来源和镜像内容防篡改。

ca证书进行镜像的签发密钥和验证。

最小镜像原则,降低攻击面

image

最小镜像原则,使用体积小的base镜像降低攻击面
Google发布的Distroless镜像仅包含应用程序及其运行时依赖项。不包含程序包管理器,shell和在标准Linux发行版中找到的任何其他程序。

Distroless提供java、python、Nodejs、dotnet等开发语言的基础镜像

优点:
1、降低镜像体积、减少磁盘空间占用。
2、只安装应用所依赖的组件,无其他组件降低攻击面。

缺点:
1、没有shell和一些调试工具,出故障时无法方便调试,但可以通过临时容器进行调试

集群CIS安全扫描

image

互联网安全中心(CIS)发布的全面的Kubernetes Benchmark 建立Kubernetes 的安全配置规范

1、集群组件配置检查(Api-server、controller-manager、scheduler、etcd)是否符合安全配置参数。

2、集群组件配置文件权限检查。

3、策略检查(pod安全策略、网络安全策略检查)。

使用Rootless Container提升容器的安全性

image

image

Docker Daemon因为需要创建Namespace和挂载分层文件系统等所以一直以来是以root用户来运行的。这也导致了有Docker访问权限的用户可以通过连接Docker Engine获取root权限,而且可以绕开系统的审计能力对系统进行攻击。

Rootless Container实现使用非特权用户运行docker engine。

Docker 19.03中发布了“Rootless Container”特性

实现原理:
1、通过user Namespace实现docker demon运行的用户重映射

2、利用用户态的网络SLiRP通过一个TAP设备连接到非特权用户名空间,为容器提供外网连接能力

集群及运行安全 – 实践

https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/
image

容器和应用安全 – 实践

限制对Kubernetes API的访问

  • 对所有API通讯使用TLS加密
  • API认证
  • API授权
    限制对Kubelet的访问
  • 关闭匿名访问
  • 限制运行时Workload和用户具备的能力
  • 限制资源使用
  • 限制特权容器
  • 限制容器加载特定内核模块
  • 限制容器网络访问
  • 限制云元数据API访问
  • 限制Pod能够使用的node
    保护集群组件不受侵害
  • 限制对etcd的访问
  • 启用审计日志
  • 限制对无关特性或alpha/beta特性的使用
  • 定期更新基础设施credential
  • 评估第三方集成安全性
  • 加密Secrets资源
  • 接收安全更新和漏洞报告

限制资源使用

  • 配置Namespace配额
  • 配置容器默认资源限制
    镜像安全
  • 最小镜像原则,减少攻击面
  • 基础镜像规划化避免乱使用
  • 镜像内使用非特权用户
  • 镜像漏洞扫描,定义风险阈值
  • 代码安全
  • 通过TLS访问,对传输内容加密
  • 限制通信端口范围
  • 确保第三方依赖安全性
  • 静态代码分析
  • 动态探测攻击