DevSecOps入门笔记
基于K8S的DevSecOps入门
前言
笔者近期在从事企业内部基于K8S的DevSecOps平台的搭建,本文对现在用到的和了解到的安全相关做一个总结,主要不是专业的安全人员,还是有很多没有涉及到的地方。
CI阶段
静态代码分析
SonarQube
官方链接SonarQube 10.3 (sonarsource.com)
SonarQube是一个开源的静态代码分析平台,它能够检测多种编程语言中的漏洞、代码异味、安全漏洞、以及不符合编码规范的问题。通过集成SonarQube到CI流程中,可以在代码合并前及时发现并修复潜在的安全风险。
以下是官方示意图,我们主要用到了sonarqube,至于sonarlint,可以让研发在IDE接入
针对安全,主要是这三个方面,sonaqube也提供了对应的问题说明和修复建议
BUG
漏洞
安全热点
以BUG为例展示部分扫描结果,它可以定位到git中的代码行和对应的提交者提交日期,更多使用建议读者自行安装并根据官方文档尝试
需要让研发根据扫描的结果,在代码迭代时逐步修复这些问题
异味
异味则主要是可维护性相关,严格来说不属于安全范畴,而是QA的范畴,这里暂时跳过
容器镜像安全
最小权限原则
DockerFile
业务容器
-
确保容器内运行命令遵循最小权限原则,避免以root用户运行不必要的服务,降低被攻击者利用的风险。
比如在DockerFile构建时加入
RUN addgroup -S nonroot \ && adduser -S nonroot -G nonroot USER nonroot CMD/ENTRYPOINT XXX
但这种方式可能会使其缺失部分文件系统的读写权限,可能还需要chown等,需要确定业务需要做的任务的OS权限
开源软件容器
-
针对引入的开源软件镜像,绝大部分云原生生态的较新的镜像都会默认把用户调整为非root用户
如果不能确定,具体读者可以使用
cat /etc/passwd #查看存在的用户列表 id -u #查看用户id 如果不是0则是非root用户
部分会在安全上下文中设置,所以上面的操作最好是在K8S的容器运行时再查看,而不仅仅是docker run镜像直接看
但也可能有部分容器必须有特权,建议咨询开发团队或自行查阅官方文档。
K8S
-
如果不想过早对的考虑权限问题,也可以在Kubernetes manifest文件(如Deployment或Pod)中指定合适的securityContext参数,限制容器运行时的用户和组ID,以及必要的capabilities。如很多开源软件并不会在DockerFile构建时确定用户,而是在K8S manifest的container和pod部分设置为一个os镜像预置的65534:65534的非特权nobody用户
-
limit和request设置避免异常行为,隐私配置放到secret
依赖包漏洞
-
Trivy: Trivy是一款适用于CI/CD流程的快速且全面的容器镜像漏洞扫描工具。它可以自动扫描容器镜像中的操作系统包(如Alpine、RHEL、Debian等)及其包含的应用程序依赖(如Bundler、Composer、npm、maven等),针对CVE数据库进行比对,报告出存在的已知安全漏洞,并提供漏洞严重等级及修复建议。
-
将容器镜像上传到harbor后,如果内置了镜像漏洞扫描,可以设置手动或者定时的扫描来查看当前镜像存在的问题,如下
可以点击CVE漏洞超链接查看具体的说明,或者直接查看trivy种给出的摘要,如果该漏洞已经可以通过升级修复,trivy会给出修复的依赖版本升级建议
PS:但其实很多的知名开源软件容器镜像的release都或多或少存在漏洞,尤其是选择稳定版或者一些古老的版本,有的甚至上百个,所以具体怎么用还是得看运维团队和安全团队怎么说。
容器签名
我们暂时没做,因为我们用到的都是一些常见的开源软件官方容器镜像和自己的应用镜像。如果想要确保供应链安全,CNCF生态之中也有很多相关的工具读者可以自行探索
CD/OPS阶段
权限管理
-
RBAC(Role-Based Access Control): 在部署应用到生产环境时,确保所有Kubernetes资源对象都遵循最小权限原则,使用RBAC机制为每个服务账户分配精确的角色和权限,防止因权限过大导致的安全隐患。
通常我们自己的业务应用的自动使用默认的ServiceAccount,不太和K8S集群的权限有关应用打交道(即通过service account访问apiserver),也不太需要关注。如果真要自己找事做也可以根据设置更小的权限,以避免问题。
需要关注的是一些开源软件,特别是一些要使用CRD和或自定义控制器或operator模式的的开源软件的权限相关问题。如kube-Prometheus,ArgoCD等,它们通常提供默认的权限设置就能正常工作,如果需要更小的权限审计,需要更多更深入的掌握这些开源软件。
正常来说管理和审计好集群内的RBAC相关资源(即上图存在的这些相关的)问题应该不大
容器运行时安全性
-
Falco: Falco是一个用于实时检测异常行为的eBPF-based容器和Kubernetes运行时安全工具。它可以监控系统调用、文件访问以及其他关键事件,识别潜在的安全威胁,如权限提升、非法文件访问、恶意进程执行等,并及时发出警报。
-
通过集成Prometheus+grafana或者日志系统来可视化它的功能并考虑进行告警。
mertics
logging
网络策略
-
Kubernetes Network Policies: 在Kubernetes环境中实施严格的网络策略,定义Pod间通信的允许规则,阻止未经授权的入站或出站流量,从而增强集群内部的安全隔离性,防止未授权的数据泄露或攻击传播。
详细可以参考官方文档
K8S
cilium
Overview of Network Policy — Cilium 1.16.0-dev documentation
我的理解是网络策略是在原有的转发规则下,对流量通过名字空间,label的标记和协议,方式的等做的白名单补充
以下是粘贴自K8S官方文档的部分内容
网络策略
如果你希望针对 TCP、UDP 和 SCTP 协议在 IP 地址或端口层面控制网络流量, 则你可以考虑为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy)。 NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类网络“实体” (我们这里使用实体以避免过度使用诸如“端点”和“服务”这类常用术语, 这些术语在 Kubernetes 中有特定含义)通信。 NetworkPolicy 适用于一端或两端与 Pod 的连接,与其他连接无关。
Pod 可以与之通信的实体是通过如下三个标识符的组合来辩识的:
-
其他被允许的 Pods(例外:Pod 无法阻塞对自身的访问)
-
被允许的名字空间
-
IP 组块(例外:与 Pod 运行所在的节点的通信总是被允许的, 无论 Pod 或节点的 IP 地址)
在定义基于 Pod 或名字空间的 NetworkPolicy 时, 你会使用选择算符来设定哪些流量可以进入或离开与该算符匹配的 Pod。 另外,当创建基于 IP 的 NetworkPolicy 时,我们基于 IP 组块(CIDR 范围)来定义策略。
前置条件
网络策略通过网络插件来实现。 要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。
Pod 隔离的两种类型
Pod 有两种隔离: 出口的隔离和入口的隔离。它们涉及到可以建立哪些连接。 这里的“隔离”不是绝对的,而是意味着“有一些限制”。 另外的,“非隔离方向”意味着在所述方向上没有限制。这两种隔离(或不隔离)是独立声明的, 并且都与从一个 Pod 到另一个 Pod 的连接有关。
默认情况下,一个 Pod 的出口是非隔离的,即所有外向连接都是被允许的。如果有任何的 NetworkPolicy 选择该 Pod 并在其 policyTypes
中包含 “Egress”,则该 Pod 是出口隔离的, 我们称这样的策略适用于该 Pod 的出口。当一个 Pod 的出口被隔离时, 唯一允许的来自 Pod 的连接是适用于出口的 Pod 的某个 NetworkPolicy 的 egress
列表所允许的连接。 这些 egress
列表的效果是相加的。
默认情况下,一个 Pod 对入口是非隔离的,即所有入站连接都是被允许的。如果有任何的 NetworkPolicy 选择该 Pod 并在其 policyTypes
中包含 “Ingress”,则该 Pod 被隔离入口, 我们称这种策略适用于该 Pod 的入口。当一个 Pod 的入口被隔离时,唯一允许进入该 Pod 的连接是来自该 Pod 节点的连接和适用于入口的 Pod 的某个 NetworkPolicy 的 ingress
列表所允许的连接。这些 ingress
列表的效果是相加的。
网络策略是相加的,所以不会产生冲突。如果策略适用于 Pod 某一特定方向的流量, Pod 在对应方向所允许的连接是适用的网络策略所允许的集合。 因此,评估的顺序不影响策略的结果。
要允许从源 Pod 到目的 Pod 的连接,源 Pod 的出口策略和目的 Pod 的入口策略都需要允许连接。 如果任何一方不允许连接,建立连接将会失败。
安全审计
-
宿主机与集群审计: 对Kubernetes节点的宿主机执行定期的安全审计,包括但不限于检查防火墙规则、系统补丁更新情况、敏感端口暴露情况、以及任何非标准配置变更。同时,监控集群层面的网络策略、Pod安全上下文、以及Pod间的通信审计记录。
-
以下是复制于K8S官方文档的主要内容,部分主要内容已经在上面提到过,详情请点击官方文档查看
认证和鉴权
-
在启动后
system:masters
组不用于用户或组件的身份验证。 -
kube-controller-manager 运行时要启用
--use-service-account-credentials
参数。 -
根证书要受到保护(或离线 CA,或一个具有有效访问控制的托管型在线 CA)。
-
中级证书和叶子证书的有效期不要超过未来 3 年。
-
存在定期访问审查的流程,审查间隔不要超过 24 个月。
-
遵循基于角色的访问控制良好实践,以获得与身份验证和授权相关的指导。
网络安全
-
使用的 CNI 插件可支持网络策略。
-
对集群中的所有工作负载应用入站和出站的网络策略。
-
落实每个名字空间内的默认网络策略,覆盖所有 Pod,拒绝一切访问。
-
如果合适,使用服务网格来加密集群内的所有通信。
-
不在互联网上公开 Kubernetes API、kubelet API 和 etcd。
-
过滤工作负载对云元数据 API 的访问。
-
限制使用 LoadBalancer 和 ExternalIP。
pod安全
-
仅在必要时才授予
create
、update
、patch
、delete
工作负载的 RBAC 权限。 -
对所有名字空间实施适当的 Pod 安全标准策略,并强制执行。
-
为工作负载设置内存限制值,并确保限制值等于或者不高于请求值。
-
对敏感工作负载可以设置 CPU 限制。
-
对于支持 Seccomp 的节点,可以为程序启用合适的系统调用配置文件。
-
对于支持 AppArmor 或 SELinux 的系统,可以为程序启用合适的配置文件。
日志和审计
-
审计日志(如果启用)将受到保护以防止常规访问。
-
/logs
API 被禁用(你所运行的 kube-apiserver 设置了--enable-logs-handler=false
)。Kubernetes 包含一个
/logs
API 端点,默认启用。 这个端点允许用户通过 HTTP 来请求 API 服务器的/var/log
目录的内容。 访问此端点需要身份验证。
Pod 布局
-
Pod 布局是根据应用程序的敏感级别来完成的。
-
敏感应用程序在节点上隔离运行或使用特定的沙箱运行时运行。
镜像
-
尽量减少容器镜像中不必要的内容。
-
容器镜像配置为以非特权用户身份运行。
-
对容器镜像的引用是通过 Sha256 摘要实现的,而不是标签(tags), 或者通过准入控制器在部署时验证镜像的数字签名来验证镜像的来源。
-
在创建和部署过程中定期扫描容器镜像,并对已知的漏洞软件进行修补。
Secrets
-
不用 ConfigMap 保存机密数据。
-
为 Secret API 配置静态加密。
-
如果合适,可以部署和使用一种机制,负责注入保存在第三方存储中的 Secret。
-
不应该将服务账号令牌挂载到不需要它们的 Pod 中。
-
使用绑定的服务账号令牌卷, 而不要使用不会过期的令牌。
推荐阅读
云原生安全
K8S官方文档
CNCF云原生安全白皮书
https://github.com/cncf/tag-security/blob/main/PUBLICATIONS.md
渗透
笔者更多是以运维的角度来说明可以用到的安全措施,读者可以参阅一些安全从业人员的渗透方案从它们的角度来了解K8S的安全如何加固。
【云攻防系列】从攻击者视角聊聊K8S集群安全(上) - FreeBuf网络安全行业门户
【云攻防系列】从攻击者视角聊聊K8S集群安全(下) - FreeBuf网络安全行业门户
更多推荐
所有评论(0)