容器正在改变软件开发。作为CI/CD的新基础,容器为你提供了一种快速,灵活的方式来部署应用程序,API和微服务,而数字化成功与否取决于可扩展性和性能。但是,容器和容器编排工具(例如Kubernetes)也是黑客们的热门目标,如果它们没有得到有效的保护,它们可能会使你的整个环境面临风险。在本文中,我们将讨论容器堆栈每一层安全的最佳实践。
了解容器安全的含义很重要。作为依赖共享内核的应用程序层构造,容器可以比VM更快地启动。在配置方面,容器也比VM灵活得多,并且可以执行挂载存储卷到禁用安全功能的所有操作。
如果绕过容器隔离机制并在主机上获得特权时,该容器甚至可以在黑客的控制下以root用户身份运行,然后你就陷入了真正的麻烦。
你可以采取一些措施,将坏蛋拒之门外。
第0层–内核
Kubernetes是一个开源平台,旨在自动执行容器的部署,扩展和编排,正确配置它可以帮助你增强安全性。在内核级别,你可以:
- 查看允许的系统调用,并删除所有不必要或不需要的系统调用
- 使用gVisor或Kata Containers等容器沙箱进一步限制系统调用
- 验证你的内核版本已打补丁并且不包含任何现有漏洞
第1层–容器
静态
静态的容器安全性侧重于将用于构建容器的Docker镜像。首先,通过删除不必要的组件,程序包和网络实用程序来减少容器的攻击面-精简越多越好。考虑使用仅包含应用程序及其运行时依赖项的 distroless镜像。
Distroless (https://github.com/GoogleCloudPlatform/distroless) 是谷歌内部使用的镜像构建文件,包括 Java 镜像,Node,Python 等镜像构建文件,Distroless 仅仅只包含运行服务所需要的最小镜像,不包含包管理工具,shell 命令行等其他功能。
接下来,确保仅从已知可信任的来源中提取镜像,然后扫描它们中的漏洞和配置错误。在你的CI/CD流水线和构建过程中检查它们的完整性,并在运行之前进行验证和批准,以确保黑客未安装任何后门程序。
运行
打包镜像后,就该进行调试了。临时容器将使你可以交互式地调试运行中的容器。监视异常和可疑的系统级事件,这些事件可能是破坏的迹象,例如,产生了意外的子进程,在容器内运行的shell或意外读取了敏感文件。
开源运行时安全工具Falco可以为你提供帮助,它通过以下方式使用系统调用来保护和监视系统:
- 在运行时从内核解析Linux系统调用
- 针对强大的规则引擎声明流
- 违反规则时发出警报
第2层–工作负载(Pod)
Pod是Kubernetes内的部署单位,是容器的集合,可以共享常见的安全定义和对安全敏感的配置。Pod安全上下文可以设置给定Pod的特权和访问控制,例如:
- 容器内的特权容器
- 进程和卷的组和用户ID
- 细粒度的Linux功能(删除或添加),例如Sys.time
- 沙箱和强制访问控制(seccomp,AppArmor,SELinux)
- 文件系统权限
- 特权升级
为了加强Pod级别的防御能力,你可以实施严格的Pod安全策略,以防止危险的工作负载在集群中运行。要获得对Pod安全性的更大灵活性和更精细的控制,请考虑使用OPA Gatekeeper项目实施的开放策略代理(OPA)。
第3层–网络
默认情况下,所有Pod都可以不受限制地与集群中的所有其他Pod对话,这从攻击者的角度来看非常有利。如果工作负载受到威胁,攻击者可能会尝试探测网络并查看他们还可以访问什么。Kubernetes API也可以从Pod内部访问,从而提供了另一个丰富的目标。
严格的网络控制是容器安全的关键部分-pod到pod,集群到集群,由内而外和由内而外。使用内置的网络策略来隔离工作负载通信并构建精细的规则集。考虑实现服务网格以控制工作负载之间的流量以及入口/出口,例如通过定义namespace到namespace的流量。
应用层(L7)攻击–服务器端请求伪造(SSRF)
最近,我们已经听到很多关于SSRF攻击的消息,这也就不足为奇了。在API与其他API对话的云原生环境中,SSRF尤其难以防御。webhooks尤其臭名昭著。一旦找到目标,就可以使用SSRF升级特权并扫描本地Kubernetes网络和组件,甚至在Kubernetes指标端点上转储数据,以了解有关环境的有价值的信息-并有可能将其完全接管。
应用层(L7)攻击–远程执行代码(RCE)
RCE在云原生环境中也非常危险,这使得在容器内运行系统级命令来抓取文件,访问Kubernetes API,运行镜像处理工具以及破坏整个机器成为可能。
应用层(L7)防御
保护的第一条规则是遵守安全的编码和体系结构实践,这可以减轻你的大部分风险。除此之外,你还可以沿两个方向对网络防御进行分层:南北方向,以监视和阻止针对你的应用程序和API的恶意外部流量;东西方向,以监视从一个容器到另一个容器,从一个集群到另一个集群以及从云到云的流量,以确保你不会受到受损的Pod的伤害。
第4层-节点
节点级安全性同样重要。为防止容器在VM或其他节点上爆发,请限制对节点以及控制平面的外部管理访问,并注意开放的端口和服务。使基本操作系统保持最少,并使用CIS基准对其进行加固。最后,确保像其他任何VM一样扫描和修补节点。
第5层–集群组件
Kubernetes集群中发生了各种各样的事情,并且没有保护它的多合一工具或策略。在较高的级别上,你应该专注于:
- API服务器–检查你的访问控制和身份验证机制,并对动态Webhooks,Pod安全策略以及对Kubernetes API的公共网络访问执行其他安全检查;
- 访问控制-使用基于角色的访问控制(RBAC)对API服务器和Kubernetes secret实施最低特权原则
- 服务帐户令牌–为了防止未经授权的访问,请限制对服务帐户以及存储服务帐户令牌的所有secret的权限
- 审核日志记录-确保已启用
- 第三方组件–注意带入集群中的内容,以便知道集群中正在运行的内容以及原因
- Kubernetes版本– Kubernetes可以像任何其他系统一样具有漏洞,并且必须及时进行更新和修补。
- Kubelet配置错误–负责容器编排以及与容器运行时的交互,Kubelet可能会被滥用和攻击,以试图提升特权。
Kubernetes的安全性似乎令人望而生畏,但是通过在堆栈的每一层上遵循最佳实践,可以使容器与环境达到相同的高级别保护。因此,你可以享受快速,敏捷的开发带来的好处。