众所周知,Kubernetes作为编排引擎为应用开发者提供了Secrets模型用于在应用Pod中加载和使用敏感信息(如数据库密码、应用证书、认证token等)。Secrets的使用对于K8s开发者来说应该已经比较熟悉了,下面是一些Secrets相关的基本概念:
-
Secrets是一个namespace维度的模型,结合K8s RBAC访问控制可以实现集群内namespace维度的读写隔离
-
Secrets可以通过文件或环境变量的形式挂载到Pod容器中使用
-
Secrets中的敏感数据是以tmpfs格式存储在节点文件系统中
-
集群apiserver是以base64明文编码的形式在etcd中存储Secrets
-
Secrets单个实例的大小限制在1MB内
我们知道虽然K8s Secrets可以作为K8s应用处理敏感信息的载体和桥梁,但是并不能保证敏感信息的安全性,特别是一些关键的密钥信息,需要开发者和安全管理人员在应用系统实施前确定密钥管理的安全方案,明确应用密钥应该存储在哪里?如何在不破坏密钥可加载和使用的前提下保护其读写和传输阶段的安全性?云服务商有哪些安全方案可以帮助保护应用密钥?用户又应该在K8s环境中采取哪些安全措施帮助管理和使用密钥?
针对如上问题,本文尝试从云服务商提供的密钥管理安全方案和面向应用开发者的密钥管理最佳安全实践两个维度回答上面的疑问。
安全方案:
基于云上安全责任共担模型,云服务商有责任保护管控侧配置和敏感信息的安全性,同时提供密钥管理的安全方案,帮助用户提升应用密钥安全水位,下面是一些推荐的安全方案:
1 使用云上密钥管理服务
云服务商通常都提供密钥管理服务,比如阿里云KMS密钥管理服务,可以提供专业的密钥生命周期管理和数据加解密,帮助简化应用系统接入流程。
在应用系统开发部署的供应链流程中,任何一个环节对敏感密钥的硬编码都有可能导致泄露风险。通过使用云上KMS服务,可以在应用开发、测试、构建等生命周期流程中使用统一方式进行密钥的读写,避免硬编码出现;同时云上的KMS服务支持自动化的密钥轮转能力,进一步降低了敏感信息泄露传播的安全风险,同时也可帮助企业应用满足合规需求。
2 使用secret store CSI driver
从指定文件系统路径或是从环境变量读取是应用消费密钥的通常方式,如何将云上KMS服务中的密钥信息导入到应用Pod容器内的指定路径下呢?
K8s社区基于CSI存储标准扩展实现了secrets-store-csi-driver用于将存储在外部密钥管理服务中的密钥以volume存储卷的形式挂载到应用pods中。当volume完成attach挂载后,密钥信息可以以文件系统的形式在容器中使用,从而避免K8s secret实例的创建,带来的好处一是避免etcd中出现明文secret信息,二来可以在大规模场景下避免secret堆积;同时应用仍旧可以保持原先的文件路径方式读取密钥,避免了通过KMS服务接口形式获取密钥带来的额外改造代价。
基于该插件机制,各云服务商可以实现自己的provider对接不同的后端密钥管理服务,比如阿里云的secrets-store-csi-driver-provider-alibabacloud,提供在集群中部署该插件,可以方便的将阿里云KMS凭据管家中保存的密钥凭据以文件或K8s Secrets实例两种方式同步到应用容器中,同时支持后端凭据修改后的同步更新能力,保证业务容器中密钥信息的实时性。当然这里也会有“最后一把密钥”的问题,由于插件需要调用KMS凭据管家服务的权限,如何在集群中保护插件对KMS服务请求的凭据呢?这里推荐使用RRSA方案,可以将KMS凭据的请求权限绑定在插件使用的独立serviceaccount上,避免将权限泄露给应用pod中。
3 开启etcd落盘加密
etcd是K8s集群默认的后端存储系统,虽然很多时候我们已知Secrets在etcd中是base64明文存储这样的安全风险,但是又不可避免其存在性。尤其在云服务商提供的托管集群形态下,etcd维护在云服务商侧,基于云上安全零信任原则和很多应用场景下的合规要求,推荐使用K8s提供的etcd落盘加密机制,用户可以选择使用阿里云KMS服务中管理的密钥在Secret数据落盘流程中以信封加密的形式加密数据,同时在读取Secret信息的时候自动解密。配合使用自动轮转密钥可进一步提升数据安全性。
4 使用机密计算容器
对于数据安全性有严格要求的场景,比如金融支付、隐私认证或涉及知识产权的核心数据计算,除了保证这些核心敏感信息在读写和传输过程中的安全性,还需保证机密信息在云上节点内存运算和存储过程中的安全可信。在此场景下推荐使用阿里云ACK-TEE机密计算集群,ACK-TEE可以基于底层硬件加密技术在容器应用实现一个可信执行加密环境,保证机密信息在云端代码使用过程中的完整性,实现数据全生命周期的安全可信。同时应用系统核心密钥也可以存储在可信的隔离环境Enclave中,实现类似KMS HSM的能力,减少密钥传输链路。
最佳实践:
基于云服务商提供的密钥管理安全方案,应用开发运维人员需要负责自身业务密钥的安全性。这里我们概括了一些业务侧推荐实施的密钥管理最佳安全实践:
RBAC访问控制
Secrets作为K8s系统中的基础模型,通过RBAC实现对Secrets实例的访问权限控制是基本且必要的安全要求,在集群日常运维开发中应该遵循权限最小化原则授权,避免在下发的凭证中绑定全局secret读写权限,及时吊销可能泄露的集群访问凭证。
Pod安全加固
容器逃逸是针对K8s集群常见的攻击方式,对于一个已经逃逸到容器主机的攻击来说,他可以轻松获取节点上相关secrets的明文信息,同时也可以发起进一步的攻击获取整个集群的访问权限,从而造成集群内敏感信息的泄露。
K8s提供了多种安全配置帮助应用开发者加固容器安全,应用开发者应当根据实际业务需要最小化Pod的capabilities,避免使用privileged或其他共享主机网络、文件系统等特权配置。通过使用安全策略可以在应用部署时刻有效拦截不符合安全策略约束的违规特权部署。另外部署和使用Network Policy可以限制应用Pod内的东西向网络访问,进一步收敛攻击者入侵后实施下一步横向攻击的安全风险。
节点安全加固
集群基础设施安全是保证上层应用安全的基础。首先应该尽量选择私有网络,同时使用安全组ACL规则控制出入网流量。 对于集群节点自身,推荐使用经过基于等保/CIS等安全合规规范加固过的基础镜像作为集群节点OS,可以帮助在基础设施层身份鉴别、访问控制、安全审计、入侵防范等多个维度提升基础安全性,降低攻击者从主机侧攻击窃取敏感信息的风险。
K8s集群自身组件的配置也对上层应用系统的安全性起到至关重要的作用,可以参考使用基线巡检功能及时发现集群中的不当安全配置,封堵漏洞。
供应链安全加固
关于密钥的读取使用会贯穿应用制品生命周期的各阶段,需要在组织流程上加强对密钥安全的风险意识,规范密钥使用,严禁在应用模板、代码仓库、配置文件中硬编码敏感信息,在制品供应链生命周期中统一使用密钥管理服务进行管理,同时企业内部安全管理运维团队可针对供应链各环节增加自动化安全扫描卡点,从源头上防止敏感信息的传播和泄露。
审计和监控
在企业应用系统中,涉及密钥生命周期管理和读写使用的所有操作均应接入审计日志,保证针对敏感信息的操作可溯源;同时接入运行时刻监控机制,比如针对应用中存储敏感信息的路径设置可疑读写监控告警,对云账号AK设置泄露告警等安全设置。当发生密钥泄露时,日志和告警可以帮助企业运维快速定位问题,判断影响面,同时及时进行相关止血措施。
使用临时凭证,定期或自动轮转密钥
不要在应用系统中使用如账号AK这样的固定密钥,推荐使用临时凭据,当密钥发生泄露时,获得临时凭据的攻击者只有一个短暂的窗口期进行下一步的探查和攻击,这无疑增加了攻击难度,也给系统运维人员提供了封堵和修复系统漏洞的机会,试想如果凭据是永久的,可能应用系统的彻底修复需要成倍的难度。
同样的道理,当我们使用云上KMS密钥管理服务中的密钥时,推荐定期轮转或开启密钥自动轮转特性,提升应用安全防御能力。
使用信封加密并保护好最后一把密钥
区别于直接使用云上管理服务提供的密钥去直接加解密明文数据,信封加密使用一个独立的数据加密密钥,并将其加密后封入信封中传递使用,用户业务侧的敏感信息可以在本地实现离线的加解密,避免上传云端传输过程中的泄露,同时解决了云服务商不信任问题。同时,对于数据量较大的加解密场景,离线的计算过程也避免了云上传输和计算的开销,有效提升计算性能并降低成本。
“最后一把密钥”的安全是KMS加解密场景中的普遍问题,在信封加密过程中,我们同样需要在云上放置一把KEK密钥用于加解密数据密钥,此时通用的方案是使用诸如RAM这样的访问控制服务,在最小化授权的前提下保证密钥安全性。在应用侧,需要限制读取云上密钥的RAM凭证的可见范围,同时使用可自动轮转的临时凭证,推荐在容器应用中使用类似RRSA这样的应用维度的隔离机制保护RAM凭证的安全性。
参考
若有收获,就点个赞吧