K8S与常见加固
2022-03-27 / modified at 2023-02-20 / 2.6k words / 9 mins
️This article has been over 1 years since the last update.

开源版K8S以繁琐复杂而闻名,本文是在其基础上的常见加固方案。

背景

安全是一门非常专业的领域,同时也是奢侈品。本文仅介绍常见加固场景,但是并无法枚举。如果正式上线,建议进行专业的安全/隐私/合规的认证或者渗透测试。

作为业务开发人员甚至架构人员,一般来说是没法100%搞定安全的,因为无论你的设计经验多么丰富,你的知识库也难以跟上天天专职训练的安全团队,尤其是很多安全人员都是野生的,我个人认识的安全从业者即使拿了多个ACK也经常抑郁能力不行。

参考方向

  • 尽可能将问题转移给下游(比如Vault/KMS/PKI等通过多个审计标准的云服务,而不要自己尝试开发与长期更新维护安全组件)
  • 尽可能参考现有的标准实施(比如隔离、策略、分级等要求,可以参考巨硬的标准),这个也是要花钱找第三方刷测试的。比如你的应用刷过了10个知名测试,用户肯定更放心
  • 尽可能从理论维度去枚举安全问题,毕竟不可能专职训练,而且经验/漏洞也会半衰贬值

产品安全生命周期

应用安全不仅仅要求在机房侧实施,躲在防火墙后面就可以了,而是需要从需求分析开始做。

此文写得何等好啊:参考地址

供应链加固

静态安全问题(Vulnerable and Outdated Components)

  • 静态扫描:
    • 编程语言级别的问题,比如memcp/反射/eval/SQL等,这种是很成熟的方案了,比如cppcheck、sonarqube,coverity等工具
    • 开源片断:分析是否使用了GPL的片段(广义上不算安全问题)
    • IaaS扫描:HCL(Terraform)/Dockerfile/yaml也需要扫描。比如conftest就依赖了OPA作为规则引擎去执行校验,但是当前还是比较初级的阶段。
  • 第三方库的BOM跟踪:比如log4j出现问题后,可以实现立刻反查涉及到的软件(这是一个典型的图数据库场景)与CVE缺陷。
    • 跟踪mvn、pip、npm等依赖版本,以及镜像中apt-update的latest版本。
    • 可以用OWASP的dependency-check扫描maven的tree,然后上报到sonarqube/CycloneDX等BOM平台
    • 也可以用OWASP来扫描artifactory仓库的hash值,或者使用JFrog的XRay收费服务
    • 甚至可以直接暴力反查当前容器中的jar包

这条很难,需要大量人力去维护软件的物料编码,相当于打造了软件的”ERP“系统。这里同时也要确保应用功能是用例完善的,否则升级版本成本很高。

CI可信构建(Software and Data Integrity Failures )

这里要求整个从提交代码、构建、发布与签名的流程都需要可信,也有人把它叫做DevSecOps,涉及的知识面太广,最好能做到源码-二进制一致性,即任何时候通过某个tag打包,它的二进制都是可以复现的。这个流程过于烧钱,因此不过多讨论,可以参考这里或者这里的书

构建系统大致有如下几种实现(Provision)

  • 通过VM/PM直接构建,比如HPC/EC2等,缺点是运维成本高,资源池化率低,经常一边超售一边空闲。
  • 通过专业HPC调度器软件构建,比如LSF等,缺点是授权费、运维成本极高(比如LDAP/NFS等),安全上相对较好,因为默认是锁root的,只用了setUid来切换账号
  • 基于Docker+PaaS进行调度,比如K8S/nomad,著名的CircleCI就是通过Nomad实现任务调度的,这里难点主要是docker in docker的构建,需要绑定daemon的socket文件,进而可以反向逃逸host的root。这里有一个小优化,假如宿主机安装了docker,那么docker内只需要单个docker文件即可使用,而不需要大量的依赖。
  • daemon-less构建:在上面Docker的基础上,使用kaniko等定制镜像实现docker-in-docker,注意在kaniko镜像中,仍然需要root权限去执行dockerfile的apt-update等任务,并非完全的rootless。而且可能需要与Jenkins的image混到一起。

(可选)二进制可逆性

在源码(分支、TAG)、编译器版本(比如node/jdk)、二进制管理(jar包、docker image)等管理流程中,尽可能做到可逆性,即向交付用户源码自证清白,并由用户审计源码,甚至按照文档自行编译产生的二进制也能实现hash一致(时间除外)。

涉及到的工具

  • Gitlab等托管工具
  • Artifactory等二进制储存工具(比如编译器的版本)
  • 混合的需要版本的二进制管理,比如使用Perforce Helix Core
  • 构建镜像与构建工具的版本管理:不建议通过将jdk/mvn/node等工具拷贝到构建镜像的单体中,也不建议通过yum等工具安装到根目录,而是建议专门维护一个只读的目录(nosuid/root_squash/ro)直接挂载(类似Github的方案),甚至使用Environment Module的方案直接rsync过去,否则构建镜像可能太胖。编译器的版本等元数据,可以通过Artifactory属性打入二进制中。

这里同样也是需要大量人力的任务,一般只有ToB产品与量产硬件才需要

运行时加固

运行时静态检查

首选基于业界实践,先用自动化工具扫描下问题,让大家干活先搞起来。比如jar包版本,tomcat版本等。

使用加固的容器环境

  • rootless容器:这个虽然有,但是当前生产还没人敢上,尤其是mount操作容易出现uid混乱的问题。
  • SYS_CAP限制:至少限制如下两个
    • 限制setuid
    • 限制mount等操作,避免挂载chmod+s 比如4755,配置只读FS(readOnlyRootFilesystem)

应用程序源码中的凭证加密(Cryptographic Failures )

背景

在源码的配置文件(比如application-prod.yml)中,一般会涉及到“RSA私钥/数据库密码/AKSK”等配置,假如明文存储这些信息,一旦

  • 源码库泄漏(比如没有二次认证,被员工上传到Github,开放的sonarqube仓库)
  • 服务器OS被攻破/代码被逆向(比如简单的stings/strace命令,或者汇编逆向)
  • 开发员工离职时拖库(因为拥有生产数据库的连接串)

这时业务就会遭到重要损失。

对此,有如下方案将安全问题转嫁给更下层(PaaS与云服务)

配置文件加密

常见项目举例如下,这里一般仍然是对称加密,它们将问题转嫁给了某个密钥

  • spring项目:参考jasypt,支持多种算法,支持加盐与自定义算法以提高破解困难,依赖jasypt.encryptor.password
  • sonarqube:基于AES256对称加密,详见这里,依赖sonar.secretKeyPath,注意sonar本身也是需要加固配置
  • nomad:将问题转嫁给了vault
  • Jenkins: 基于AES,依赖$JENKINS_HOME/secrets/master.key,实际上它解密位置过多,一点也不安全

密钥如何保存

上述用来加密与还原的密钥,需要基于更底层的平台(trusted identity provider)来保存,比如需要chroot隔离,比如PID的env隔离与FS挂载隔离。或者权威安全服务。

在k8s中的secret配置就可以进行密钥注入,但是需要注意

  • etcd本身应用、以及其物理存储介质的安全
  • sercet的ABAC配置(默认是base64编码,仍然namespace下的人都可以看)

注意这里是与单点故障并存的,也涉及到一个key保存的递归问题。这种安全方案在开源产品中一般都不是很完善,而云厂商可以将Secret用硬件密码机等密钥管理服务(KMS, Secrets Manager等)的实现。

上述操作只是提高了逆向难度,同时将安全问题仍给了PaaS层,而PaaS/云厂商本身是拥有解密密钥的,从技术角度上是可以读取到你的任何数据。

云上安全加固

Infra层加固

  • 网络:配置独立的VPC、安全组等,比如只进不出策略。
  • OS:使用专用的加固OS,尤其是审计和防火墙

其他安全措施

此外还有如下补充

  • 数据库/配置中心本身也需要部署到隔离的VPC,配置出入策略,仅允许应用服务器访问,而不是internet-exposed。
  • 数据库/配置中心的IP地址,在应用侧推荐用VPC Endpoint/Peering/K8S external Service等类似Sidecar的方案去作为代理隐藏真实IP。
  • 数据库与可视化可以用Pg-pool/redash等工具进行二层封装,并进行AOP拦截。

其他

投入产出

在开源版本上集成社区的安全加固,需要专门的SRE团队来投入大量人力进行加固,一般来说是需要规模才有效益的,否则每天耗在CVE清单中就被耗死了。假如团队较小,建议直接用加固好的云服务。

云服务厂商信任

技术角度上,云服务商/权威数字签名提供商都能突破你的应用的机密性(比如偷看数据库,AI扫描你的S3)和完整性(比如CNNIC的签名)而且难以发现

  • 大部分国家有法律要求对内容进行本地化、审核和绿化(比如特斯拉、iCloud贵州),甚至法律制裁
  • 云厂商的三权分立设计也是由程序开发,也可能有漏洞

即使厂商本身不想看你的数据,也基于合规流程,雇佣了无数安全团队,通过了无数标准。它可以增强商业信心,但是无法形式化证明它的安全性,当前热点的有“全同态加密”方案,但是还没有普及。

其他参考