云原生安全-更安全的密文管理 Vault on ACK

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

Vault是什么?

如何在云上应用中管理和保护用户的敏感信息是一个经常令开发者头疼的问题,用户的密码口令,证书秘钥等私密信息时常未经加密被随意的放置在配置文件,代码仓库或是共享存储里,而对于普通的开发者来说,设计和实现一套完整的秘钥管理系统是一个很大的挑战。且不论令人生畏的加解密算法,很多的云应用仍然将一些敏感配置信息仅仅经过base64等一些简单的hash运算就放置在某个公共的配置中心上,而很多时候这些敏感信息会从应用的某行异常日志或是某段监控告警中泄露出去;不仅如此,对于一个集中式的秘钥管理系统,如何面向用户进行更细粒度的访问鉴权也是一个难题。

image.png

Vault的出现给了上述问题一个解决方案,它是HashiCorp公司(旗下还有Vagrant,Terraform,Consul等知名产品)维护的开源软件,它的设计思想基于云原生背景下动态基础设施的特点,在云上的不同网络层以及不同的服务之间已经很难找到传统的信任边界,服务之间更加强调以身份(identity)为核心的认证和访问控制,而不是像传统静态基础设施中以IP、主机地址作为信任凭证。为此Vault提供了以下几个功能点:

  • Secret存储形式的多样性,任意的kv形式敏感信息(如数据库密码,证书,ssh登录秘钥,openapi身份凭证等);
  • 存储格式的多样性,支持插件式的存储引擎扩展,可对接如AWS,Consul,NoSQL,KV,PKI,SSH等多种插件引擎;
  • 支持与各类平台的认证对接,可动态生成认证凭据或配置信息;
  • 支持基于Shamir算法的私钥分割完成Vault后端的加封和解封操作,同时支持高可用的部署形态;
  • 支持各类secret的动态生成,续租,撤销和滚动更新;
  • 完备的审计日志;
  • 完备的CLI和RESTful API

Vault与k8s的集成

Vault松耦合的架构使其支持与多种secret引擎和相应的存储后端对接,同时支持与多种认证服务器的交互
本节我们主要介绍Vault与k8s的集成。

Vault在Kubernetes中的应用场景

Vault作为企业级的secret管理工具,是一些大客户在业务上云过程中的安全强需求,尤其是国外市场。在Kubernetes集群中主要有以下应用场景:

  • 作为部署在Kubernetes集群中的应用对外提供秘钥管理服务,支持与多家主流云厂商秘钥服务以及多种secrets形式的对接,支持多种数据库服务的存储对接,同时支持多种认证形式的对接。
  • 作为一个公共的加密服务(Encryption as a Service)而不做后端存储的对接,帮助用户应用剥离繁琐的加密加解密逻辑。
  • 面向政府、金融等对数据安全规格有很高要求的客户,Vault支持基于Two-man原则利用私钥分割算法对后端服务进行加解封,并结合k8s的高可用部署形态为企业提供更加安全可靠的secret管理能力。
    当然这里只是列举了一些Vault原生提供的能力,作为一个在Kubernetes集群上直接运行的安全应用,任何一个面向k8s的应用工具都可以利用其安全能力。

安装Vault

Vault支持helm化安装,在其官方文档中我们可以找到关于启动参数的详细配置说明,同时在阿里云容器服务的应用目录apphub中我们也可以通过控制台在ACK集群中方便的安装Vault
image.png

另外Vault的默认安装也集成了其控制台的安装,通过负载均衡服务或ingress路由的方式我们可以在公网访问其UI,在vault pod的日志中我们可以找到登录使用的root token,在控制台中可以方便的设定与存储引擎和认证方式的对接,同时还可以进行基于策略的访问控制配置。
image.png

认证方式的集成

当用户希望在k8s pod的业务逻辑中与Vault服务端通讯,获取需要的secrets时,首先Vault会对这个pod中的请求进行认证,那么这个pod中的Vault请求认证凭据应该如何获取呢?如上所述,Vault后端支持多种认证方式的对接,对于Kubernetes,Vault支持基于K8s Service Account Token的认证。

使用上,Vault管理员首先需要在后端enable kubernetes的认证方式,生成一个与Vault交互的指定sa,然后通过CLI或API将sa token和集群ca,公网地址等信息写入到Vault后端中,并配置与vault后端的ACL策略绑定。详细步骤请参见官方文档

当然在pod应用中可以并不局限于一定使用基于sa的kubernetes认证方式。比如[kubernetes-vault]( https://github.com/Boostport/kubernetes-vault
)。该项目使用Vault中的[AppRole](https://www.vaultproject.io/docs/auth/approle.html
)认证方式,在该认证模式中,管理员可以为不同的pod创建不同的Vault原生role模型并绑定到对应的policy上,同时可以基于role创建secret_id,secret_id对应的token可作为与Vault进行认证的临时凭证。kubernetes-vault利用了AppRole的认证交互模式,首先已经完成安装的kubernetes-vault controller会去Watch集群中所有pod的创建,当发现新建pod的部署模板中有指定annotation的init-container存在时,controller会根据模板中指定的vault role id去Vault请求获取其对应的secret_id并发送给init-container中kubernetes-vault的客户端,在应用容器启动前kubernetes-vault客户端用controller返回的secret_id和role_id去Vault请求真正的login token并最终写入到与应用pod共享的挂载目录中;同时客户端会根据token过期时间进行定时的轮转,保证其可用性。下图为kubernetes-vault工作流程图:

image.png

在社区也存在不少基于k8s与Vault进行认证对接的其他方案,其设计思路大同小异,基本都采用了通过init-container或sidecar方式引入一个额外的客户端去Vault请求指定认证模式下的短时凭证并共享给业务容器使用。
在容器服务控制台的应用目录apphub中,我们同样可以找到kubernetes-vault,方便开发者使用helm直接在集群指定命名空间一键部署。Vault也计划在后续自己的官方版本helm chart中增加配置项以支持上述登录认证secret的动态注入。

Vault与阿里云RAM的集成

当我们在应用中需要访问阿里云资源时,需要使用RAM账号对应的AK或是STS临时credentials作为访问相应资源接口的凭证。如果使用账号AK,如何使其能够被应用逻辑获取的同时保证AK的安全性一直是一个头疼的问题;如果使用临时sts token,由于其时效性,我们也需要在考虑安全性的同时思考如何进行临时访问凭证的轮转。相比较两种方式,使用sts临时凭证的方式肯定在安全上是更为推荐的方式,同时对这种动态secret的安全管理也正是Vault的优势所在。本节我们来介绍下Vault与阿里云RAM在认证方式和secret管理引擎上的集成。

认证方式的集成

首先在认证方式上,Vault服务端的role模型可以与RAM role进行一对一的映射匹配,用户可以使用Vault提供的OpenAPI或是CLI,通过传入扮演RAM role返回的临时凭证调用GetCallerIdentity接口,然后Vault服务端会根据请求返回的角色arn id在其后端存储中查找是否有对应的权限策略配置,如果存在则认证成功并返回一个可用于调用Vault其他后端接口的访问token。

Vault Secret引擎与RAM的集成

当我们需要在业务应用逻辑中使用阿里云资源时,通常需要通过角色扮演的方式获取一个RAM返回的临时凭证,然后通过这个临时凭证完成与RAM的鉴权过程。由于凭证的时效性,我们在保证其安全性的同时还要维护一个对应的秘钥轮转机制。Vault的secret引擎实现了与阿里云RAM的对接插件,帮助我们安全、动态的管理RAM凭证,其主要步骤 如下:

1.开启后端引擎

2.在RAM控制台为Vault服务器创建专属子账号并绑定定制化权限策略

3.获取Vault子账号对应的AK并通过Vault CLI/API写入到后端指定路径下

4.在Vault后端写入业务中希望获取的RAM凭证所对应的策略定义或角色,其中策略定义支持inline和remote策略两种形式,所谓inline模式是指直接在api请求中写入策略模板,remote模式指写入RAM中存在的策略类型和名称,比如:

$ vault write alicloud/role/policy-based \
    remote_policies='name:AliyunOSSReadOnlyAccess,type:System' \
    remote_policies='name:AliyunRDSReadOnlyAccess,type:System'

角色模式需要用户指定希望被扮演的角色arn,另外需要Vault子账号在该角色的受信实体里,一个示例如下:

$ vault write alibaba/role/role-based \
role_arn='acs:ram::5138828231865461:role/hastrustedactors'

5.在具体的业务应用中,只需要通过调用Vault的creds/policy-based或role-based接口即可动态获取相应的RAM访问凭证,下面是一个角色扮演返回临时token的CLI调用示例:

$ vault read alicloud/creds/role-based
Key                Value
---                -----
lease_id           alicloud/creds/role-based/f3e92392-7d9c-09c8-c921-575d62fe80d9
lease_duration     59m59s
lease_renewable    false
access_key         STS.L4aBSCSJVMuKg5U1vFDw
secret_key         wyLTSmsyPGP1ohvvw8xYgB29dlGI8KMiH2pKCNZ9
security_token     CAESrAIIARKAAShQquMnLIlbvEcIxO6wCoqJufs8sWwieUxu45hS9AvKNEte8KRUWiJWJ6Y+YHAPgNwi7yfRecMFydL2uPOgBI7LDio0RkbYLmJfIxHM2nGBPdml7kYEOXmJp2aDhbvvwVYIyt/8iES/R6N208wQh0Pk2bu+/9dvalp6wOHF4gkFGhhTVFMuTDRhQlNDU0pWTXVLZzVVMXZGRHciBTQzMjc0KgVhbGljZTCpnJjwySk6BlJzYU1ENUJuCgExGmkKBUFsbG93Eh8KDEFjdGlvbkVxdWFscxIGQWN0aW9uGgcKBW9zczoqEj8KDlJlc291cmNlRXF1YWxzEghSZXNvdXJjZRojCiFhY3M6b3NzOio6NDMyNzQ6c2FtcGxlYm94L2FsaWNlLyo=
expiration         2018-08-15T21:58:00Z

如何在k8s应用中使用Vault Secret

在了解了Vault的基本概念以及与Kubernetes的认证交互流程后,我们进入客户最为关心的话题。如何在k8s pod应用中方便地获取Vault服务端管理的secret。社区针对此问题也有激烈的讨论和不少相关解决方案,方案主要集中在两个方向:

**[定时同步进程](https://github.com/hashicorp/vault/issues/7364
)**:使用一个同步进程定时地从Vault服务端获取指定范围的秘钥更新并同步到k8s集群中的secret模型,代表的项目有vaultingkube 和[secrets-manager]( https://github.com/tuenti/secrets-manager
) 。其主要设计思想也不尽相同,以secrets-manager为例,首先用户可以通过CRD定义在Vault中关注的secret数据源,然后secrets-manager对应的controller会在Reconcile函数中定时对比指定管理范围内的k8s secret和vault secret的状态,如果不一致则进行一次调协。而用户在pod应用中可以直接引用原生secret模型中的内容获取远端Vault服务器中的秘钥。
当然社区中也存在一些对这种秘钥同步方案的质疑,比如认为该方案在秘钥同步的传输过程和用户pod使用原生secret的rest交互中会增加攻击面,但是该方案在部署实施上比较友好,也得到了很多用户的支持。

CSI插件形式集成:该方案基于CSI plugin将Vault中的秘钥通过volume的形式挂载到pod应用中。
secrets-store-csi-driver 通过实现一套基于CSI规范的driver机制可以对接不同厂商的后端存储,而Vault secret的driver(secrets-store.csi.k8s.com)允许kubelet将各类企业级秘钥存储中的secret通过volume挂载,一旦attach动作完成,秘钥数据即挂载到了容器对应的文件系统中。在CSI driver的基础上,不同的秘钥管理后端可以实现定制化的provider去对接CSI driver框架中的规定接口。provider的功能概括如下:

  • 对接后端秘钥管理系统,提供秘钥获取等必须的接口实现
  • 适配当前CSI driver的接口定义
  • 通过框架中的回调函数无需调用Kubernetes API即可将从后端获取的秘钥数据挂载到指定路径下

HashiCorp官方也基于此框架实现了一套对接Vault的Provider。这里我们以此为例具体来看下在一个k8s pod应用中如何通过CSI plugin的方式使用Vault中管理的secret秘钥。

1 首先我们创建一个开启了CSI存储插件的ACK集群,然后参考文档在集群中部署Vault服务端,为了便于验证这里我们使用dev模式省去unseal解封等流程,同时配置provider与Vault交互的认证模式和相应的访问控制策略

image.png
然后通过cli向Vault后端写入测试数据
image.png

2 通过官方提供的helm方式安装Secret Store CSI Driver,命令如下:

helm install . -n csi-secrets-store --namespace dev --set providers.vault.enabled=true

安装成功后如下图所示:
image.png

3 在集群中创建secretproviderclasses实例用于Secret Store CSI Driver与Vault的参数对接,一个示例如下,注意这里的vault服务端地址可通过kubectl get service vault获取。
image.png

4 最后我们来看下如何在应用pod中对接上述provider实例获取对应的Vault秘钥。这里pod对于上述vault provider的使用分为两种方式:

1)如果pod运行的目标集群版本在v1.15.0以上,且集群apiserver和节点kubelet manifest配置均开启了 CSIInlineVolume=true的feature-gates,则我们可以在pod中的volume字段内置声明需要使用的csi provider实例。

kind: Pod
apiVersion: v1
metadata:
  name: nginx-secrets-store-inline
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - name: secrets-store-inline
      mountPath: "/mnt/secrets-store"
      readOnly: true
  volumes:
    - name: secrets-store-inline
      csi:
        driver: secrets-store.csi.k8s.com
        readOnly: true
        volumeAttributes:
          secretProviderClass: "vault-foo"

2)如果目标集群不支持CSI的Inline Volume特性,我们需要首先创建使用csi的pv和对应的pvc实例,一个pv模板示例如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vault
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: secrets-store.csi.k8s.com
    readOnly: true
    volumeHandle: kv
    volumeAttributes:
      providerName: "vault"
      roleName: "example-role"
      vaultAddress: http://172.21.12.21:8200
      vaultSkipTLSVerify: "true"
      objects:  |
        array:
          - |
            objectPath: "/foo"
            objectName: "bar"
            objectVersion: ""

在pod实例模板中引用指定pvc即可在pod中获取到vault,这里我们在ACK集群以pv/pvc模式为例创建一个nginx应用容器实例并在其中挂载上文中我们创建的secretproviderclasses实例:
image.png

相比于secrets-manager等采用secret定时同步的方式,使用CSI对接指定Vault secret provider实例的方式虽然在实施步骤上比较复杂,同时在应用中也无法动态获取Vault后端secret的变更,但是该方案避免了secret在同步链路上频繁传输的安全风险,同时也客服了之前describe po可能造成的秘钥泄露,在整体安全性上要高出不少。大家可以根据实际应用场景选择适合自己的方式。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
9天前
|
Kubernetes 开发工具 Docker
微服务实践k8s与dapr开发部署实验(2)状态管理
微服务实践k8s与dapr开发部署实验(2)状态管理
31 3
微服务实践k8s与dapr开发部署实验(2)状态管理
|
9天前
|
Kubernetes Cloud Native 开发者
构建高效的云原生应用:Docker与Kubernetes的完美搭档
【5月更文挑战第29天】 在现代软件开发领域,"云原生"这一术语已经成为高效、可扩展和弹性的代名词。本文将深入探讨如何通过Docker容器化技术和Kubernetes集群管理工具实现云原生应用的构建和管理。我们将剖析Docker的核心原理,揭示其轻量级和易于部署的特点,并进一步探索Kubernetes如何为这些容器提供编排,保证应用的高可用性与自动扩缩容。文章不仅讨论了二者的技术细节,还提供了实践案例,帮助开发者理解并运用这些技术构建和维护自己的云原生应用。
|
6天前
|
存储 Kubernetes 监控
【云原生】Kubernetes----PersistentVolume(PV)与PersistentVolumeClaim(PVC)详解
【云原生】Kubernetes----PersistentVolume(PV)与PersistentVolumeClaim(PVC)详解
|
7天前
|
Kubernetes Cloud Native 开发者
构建高效云原生应用:Kubernetes与微服务架构的融合
【5月更文挑战第31天】 在数字化转型和技术迭代的大潮中,企业对于敏捷、可扩展的IT基础设施需求日益增长。云原生技术以其独特的优势成为推动这一进程的关键力量。本文深入探讨了如何通过结合Kubernetes容器编排和微服务架构来构建和维护高效、可靠的云原生应用。我们将剖析这种技术整合的必要性,揭示其背后的原理,并讨论在实际部署过程中可能遇到的挑战及解决方案。通过案例分析和最佳实践的分享,旨在为开发者和架构师提供一套行之有效的云原生应用构建指南。
|
9天前
|
域名解析 Kubernetes 网络协议
【域名解析DNS专栏】云原生环境下的DNS服务:Kubernetes中的DNS解析
【5月更文挑战第29天】本文探讨了Kubernetes中的DNS解析机制,解释了DNS如何将服务名转换为网络地址,促进集群内服务通信。Kubernetes使用kube-dns或CoreDNS作为内置DNS服务器,每个Service自动分配Cluster IP和DNS条目。通过示例展示了创建Service和使用DNS访问的流程,并提出了优化DNS解析的策略,包括使用高性能DNS解析器、启用DNS缓存及监控日志,以实现更高效、可靠的DNS服务。
|
9天前
|
Kubernetes Cloud Native PHP
构建高效云原生应用:基于Kubernetes的微服务治理实践深入理解PHP中的命名空间
【5月更文挑战第28天】 在当今数字化转型的浪潮中,云原生技术以其独特的弹性、可扩展性和敏捷性成为了企业IT架构的重要选择。本文深入探讨了如何在云平台之上,利用Kubernetes这一容器编排工具,实现微服务架构的有效治理。通过分析微服务设计原则与Kubernetes特性的融合,提出了一套系统的微服务部署、监控和管理策略。文章不仅阐述了关键技术点,还提供了具体实施步骤和最佳实践,以期帮助企业构建出既高效又稳定的云原生应用。 【5月更文挑战第28天】在PHP的编程世界中,命名空间是管理代码和避免名称冲突的强大工具。本文将探讨PHP命名空间的核心概念、实现方式及其在现代PHP开发中的应用。通过深
|
9天前
|
弹性计算 Kubernetes 监控
【阿里云弹性计算】阿里云 ECS 与 Kubernetes 集成:轻松管理容器化应用
【5月更文挑战第28天】阿里云ECS与Kubernetes集成,打造强大容器管理平台,简化应用部署,实现弹性扩展和高效资源管理。通过Kubernetes声明式配置在ECS上快速部署,适用于微服务和大规模Web应用。结合监控服务确保安全与性能,未来将深化集成,满足更多业务需求,引领容器化应用管理新趋势。
105 2
|
9天前
|
运维 监控 安全
【阿里云云原生专栏】云原生时代的 DevSecOps:阿里云的安全开发流程实践
【5月更文挑战第28天】在云原生时代,面对安全新挑战,阿里云践行DevSecOps理念,将安全贯穿于开发运维全过程。通过安全需求分析、设计、代码审查、测试及持续监控,确保云原生应用安全。例如,Kubernetes配置中加入安全设置。阿里云还提供多种安全服务和工具,如身份认证、云防火墙等,助力用户构建安全可靠的云应用,为数字化转型保驾护航。
68 4
|
11天前
|
SQL 监控 安全
【阿里云云原生专栏】云原生安全体系构建:阿里云云防火墙与WAF的应用
【5月更文挑战第27天】阿里云云防火墙和WAF是构建云原生安全体系的关键产品,提供网络、主机和Web应用多维度防护。云防火墙采用分布式架构抵御网络攻击,确保应用安全稳定;WAF专注Web应用安全,防止SQL注入、XSS和DDoS等威胁。简单部署配置,结合使用可实现全面安全防护,提升企业云上应用安全性,保障业务安全运行。未来,阿里云将持续强化云原生安全建设。
141 1
|
12天前
|
敏捷开发 Kubernetes Cloud Native
【阿里云云原生专栏】跨云部署与管理:阿里云云原生技术的多云策略
【5月更文挑战第25天】阿里云云原生技术提供多云策略,助力企业高效跨云部署与管理。通过容器化(如Kubernetes)、服务网格等,实现应用一致性与可移植性;统一资源管理,简化跨云操作。挑战包括数据同步、网络问题和平台差异,但阿里云的解决方案为企业在多云环境中实现资源优化、业务敏捷和系统可靠性提供了强有力支持。随着云计算发展,阿里云将持续演进其多云策略,为企业数字化转型提供保障。
96 1

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多