kube-scan 和 KCCSS
在 Kubernetes 中使用声明式 API 来定义工作负载,因为工作负载的灵活多变,这种定义的随意性是很大的,很容易因为复制黏贴、手工运维等原因给 Pod 分配不需要的特权,造成安全隐患。kube-scan 就是针对这种情况而出现的一个工具,它根据内置的二十几个检查项目,对工作负载描述的安全性进行打分,从最安全的 0 分,到最危险的 10 分。
kube-scan 所使用的计分项和算法,被称为 Kubernetes Common Configuration Scoring System (KCCSS),是一套仿造 CVSS 的 Kubernetes 配置评分系统,它从对完整性、可用性和保密性三个方面的威胁来评价安全漏洞,评分标准对降低工作负载安全性的评价,如果在同样方面已经做出了合适的补救措施,还可以挽回这部分的扣减。
快速开始
老一套的部署方式:
$ kubectl apply -f \
https://raw.githubusercontent.com/octarinesec/kube-scan/master/kube-scan.yaml
namespace/kube-scan created
configmap/kube-scan created
serviceaccount/kube-scan created
clusterrole.rbac.authorization.k8s.io/kube-scan created
clusterrolebinding.rbac.authorization.k8s.io/kube-scan created
deployment.apps/kube-scan created
service/kube-scan-ui created
可以看到创建了一个新的命名空间 kube-scan
,其中有一个 kube-scan-ui:80
的服务。尝试访问一下,页面会显示出当前集群中运行的有风险载荷,例如使用 Helm 缺省安装的 Traefik:
点击 show more
,会显示对应问题的详细信息:
往前一步
通过对部署文件的观察,会发现这个 Pod 里有两个容器,分别命名为 kube-scan-ui
和 kube-scan
,粗浅判断这是一个前后端分离的任务。在浏览器中打开调试工具,会发现对 <host-name>/api/risks
的访问,直接访问这个地址,会拿到一个 JSON 响应:
{
"data": [{
"kind": "Deployment",
"name": "traefik-1583034161",
"namespace": "infra",
"domain": "",
"risk": {
"riskScore": 7,
"riskCategory": "Medium",
"riskItems": [{
"name": "AllowPrivilegeEscalation",
"riskCategory": "Low",
"type": "Basic",
"title": "Workload allows privilege escalation",
"shortDescription": "Privilege escalation allows programs inside the container to run as root",
"description": "Privilege escalation allows programs inside the container to run as root, even if the main process is not root, which can give those programs control over that container, host and even cluster",
"confidentiality": "Low",
"confidentialityDescription": "Root processes that can escape the containers have the ability to read secrets from Kubernetes, Docker and other applications",
这样一来,我们就可以考虑,将 UI 部分去掉,仅留下后端服务。如此一来,就可以通过简单的代码,把扫描过程集成到日常运维工作之中了。
另外一些小秘密
kube-scan
的文档非常贫瘠,因此只能从 YAML 和源码中找到一些东西。
刷新时间
YAML 中有一个环境变量 KUBESCAN_REFRESH_STATE_INTERVAL_MINUTES
,原定的刷新时间是 1440 分钟也就是 24 小时。修改这一变量就能进行更快的刷新了。
KCCSS 配置
安装过程中生成了一个 Configmap 对象 kube-scan
,其中保存了 kube-scan 的评价标准,在他的代码中可以看到已经支持的各种威胁和补救措施。basic
节点中列出了目前能够判断的威胁列表,例如下面的定义:
- name: "privileged"
title: "Workload is privileged"
shortDescription: "Processes inside a privileged containers get full access to the host"
description: "..."
confidentiality: "High"
confidentialityDescription: "..."
integrity: "Low"
integrityDescription: "..."
availability: "Low"
availabilityDescription: "..."
exploitability: "Moderate"
attackVector: "Local"
scope: "Host"
handler: "IsPrivileged"
其中有一些非常易读的关键信息,例如问题的名称、标题、描述,以及对完整性、可用性和保密性的影响级别,最后是攻击来源、难度和范围。
评分方法
定时对工作负载进行检查,然后调用源码 formula.go
中实现的评分过程,整体流程如下:
GetHandler
根据配置文件中的handler
字段获取处理方法。- 用查询到的 Handler 函数对工作负载进行检查,如果存在该问题,则根据问题涉及范围,检查该工作负载是否已经有针对性的进行了加固,以此来调整该项目得分。
- 根据 Risk 和 Remediation 生成结果列表。
注意如下命名空间是硬编码忽略的 {“octarine”, “kube-system”, “kube-public”, “octarine-tiller”, “istio-system”, “octarine-dataplane”, “kube-scan”}
结论
- KCCSS 和 kube-scan 两个项目的文档都非常稀少,很不友好。
- 特征库更新困难,需要同时更新源码和配置。
- 仅提供了对全集群进行扫描,实际应用的情况下,如果能加入单个对象进行检查的手段可能会更加实用。