一、K8s的风险和挑战

  一)因容器大量部署导致忽视问题

  尽管容器具有快速、可移植性等特点,但是他们也会出现安全盲点,从而增加攻击面。

  随着容器的大量部署,保持云基础组件的可见性会变得越来越难。容器化应用程序的分布式性质会让我们难以快速发现哪些容器存在漏洞或错误配置。

  二)滥用镜像和镜像注册中心会带来安全问题

  组织必须要有镜像和可用镜像注册中心的有效治理策略。我们需要确保使用定期扫描、安全、已批准的基础镜像来构建容器镜像,并使用白名单镜像注册中心的镜像来启动k8s环境中的容器。

  三)容器彼此的之间与其他端点之间的通信

  在部署过程中,容器与pod需要相互通信,并与其他内、外部端点也进行通信才能正常运行。

  若某个容器被破坏,攻击者可影响范围与该容器通信范围直接相关,这意味着与该容器通信的其他容器和pod可能也受到攻击。

  在庞大的容器环境中,手动配置非常复杂,因此实施网络分段会非常困难。

  四)K8s 有丰富的配置选项,但默认值通常并不安全

  根据 DevOps 原则,Kubernetes 旨在加快应用程序部署并简化管理和操作,同时提供了丰富的控件集,用于有效保护集群及其应用程序的安全。

  例如 Kubernetes 网络策略,它类似于防火墙规则,控制了 Pod 之间以及与其他端点的通信方式。当网络策略与 Pod 关联时,该 Pod 只能与该网络策略中定义的目标进行通信。但默认情况下,Kubernetes 不会将网络策略应用于 Pod,这意味着在 Kubernetes 环境中每个 Pod 都可以与其他 Pod 通信。

  另一个配置风险与 secret 管理有关:如何存储和访问敏感数据(例如凭证和密钥)。我们需要确保不会将 secret 信息当做环境变量传递,要将其放入容器的只读卷中。

  五)容器与kubernetes构成合规性挑战

  云原生环境在遵守安全最佳实践、行业标准和基准以及内部组织策略方面也带来了挑战。除了保持合规性之外,组织必须显示该合规性的证明。

  我们要调整策略以确保kubernetes环境符合最初为传统应用程序体系架构编写的规范。同时,容器化应用程序的分布式和动态特性意味着在实现合规性监控和审核自动化时,才能大规模运行。

  六)容器运行带来了常见和新的安全性挑战

  容器和kubernetes的一个安全性优势是可以将它们视为不可变的基础设施。因为应用运行时,不应该被修改或更改,要在更新时从通用模板中删除并重新创建。

  容器的其他属性带来了独特的挑战,例如他们可以快速创建、删除。当我们在正在运行的容器检测到潜在威胁时,不仅要停止该容器并重新启动未被破坏的版本,还必须确保修复信息能够应用到新的容器镜像中,以安全地重新配置应用。

  其他的安全风险还包括运行带有恶意进程的受损容器。对于那些破坏容器环境的攻击者而言,加密挖矿是常用手段,但他们还可以通过受损容器执行其他恶意进程,例如:通过网络端口扫描以查找漏洞,再进行其他破坏。

二、kubernetes最佳实践

  要解决上面列出的这些kubernetes安全挑战,开发者需要将安全集成到容器生命周期的每个阶段:构建、部署和运行。我们必须构建安全的镜像,按照最佳安全实践部署配置,并在运行时保护工作负载免受威胁。

  最后,我们还需要保护kubernetes基础架构及组件,包括kubernetes API Server、etcd等,这些组件自身都可能收到攻击,总体攻击面也会由此增加。  

  一)构建阶段

  保护容器和kubernetes的安全要从构建阶段开始,此时花费的实践将在将来获得回报,若开始就没做好安全实践,后面将付出极大的修复成本。

  构建阶段主要做的两件事:

  1. 构建安全镜像
  2. 扫描这些镜像以查找任何已知漏洞

   1、使用最小的基础镜像

  避免将镜像与OS软件包管理器与shell一起使用,因为它们可能包含已知漏洞。若必须包含操作系统包,请在以后的步骤中删除包管理器。考虑使用最小的镜像

  2、不要添加不必要的组件

   确保从生产中的容器中删除debug工具。镜像中不应该包含易于被攻击者利用的通用工具。

  3、仅使用最新镜像

   确保镜像(以及包括的任何第三方工具)是最新的,并使用最新版本组件。

  4、使用镜像scanner识别已知漏洞

  镜像scanner应该能够识别镜像中的漏洞(包括分层),并告诉是否可以修复。它必须能够扫描OS软件包和第三方运行库中的漏洞,以查找容器化应用程序中使用的程序语言漏洞。

  5、将安全性集成到您的CI/CD pipeline

  使镜像扫描和其他安全检查成为CI/CD pipeline的一部分,以在扫描程序检测到高级别可修复漏洞时自己执行安全保护并使CI构建失败同时生成告警。

  6、标记无需修复的漏洞

  有时若应用程序没有已知漏洞,或者该漏洞不是关键漏洞,因此不需要立即修复。在这种情况下,请它们添加到白名单或从scanner中过滤,这样就不会因不可操作的告警而导致工作中断。

  7、纵深防御

  在容器镜像或使用该镜像的正在运行的deployment发现安全问题时,请确保已进行策略检查并准备好修复工作流来监测和更新这些镜像。

  二)部署阶段

  在部署工作负载之前,应该安全地配置kubernetes基础设施。从安全的角度来看,首先需要了解正在部署的内容以及如何部署;然后可以识别并响应违法安全策略的行为。

  • 正在部署的内容:包括有关正在使用的镜像信息,例如组件或漏洞以及将要部署的Pod
  • 部署在哪里:包含cluster、namespace和node
  • 部署方式:是否运行特权,可以与那些deployment进行通信,同时使用的pod安全上下文
  • 可以访问的内容:包括secrets,卷和其他基础组件,例如主机
  • 是否符合要求:是否符合您的策略和安全要求

  8、使用namespace隔离的工作负载

  使用namespace是kubernetes资源的主要的隔离方式。namespace为网络策略、访问控制和其他重要的安全控制提供了参考。将工作负载分到不同的namespace有助于遏制攻击,并限制用户的错误或破坏性操作的影响。

  9、使用kubernetes网络策略来控制pod和集群之间的流量

  默认情况下,kubernetes允许每个pod与其他pod通信。网络分段策略是一项安全控制策略,可以防止在攻击者入侵的情况下跨容器横向移动。

  如何设置Kubernetes网络策略。

  10、防止过度访问secret信息

  第一步,请确保deployment仅使用其实际需要的secret,以防止不必要的信息泄露。

  11、 评估容器使用的特权

  赋予容器的功能,角色绑定和权限集会极大地影响环境的安全风险。此处的目标是遵守最小权限原则,并提供容器执行其预期功能的最小权限和功能。

  pod安全策略是一种控制pod与安全相关的属性的方法,包括容器特权级别。这些可以使操作人员指定以下内容:

  1. 不要以超级用户身份运行应用程序进程
  2. 不允许权限升级
  3. 使用只读的根文件系统
  4. 使用默认的(masked/proc文件系统挂载)
  5. 不要使用主机网络或进程空间
  6. 删除未使用和不必要的Linux功能
  7. 使用SELinux选项获取更细颗粒度的过程控制
  8. 为每个应用程序分配自己的kubernetes服务账号
  9. 若不需要访问kubernetes API,请不要在容器中保存服务账号凭据

  12、评估镜像来源,包括注册

  根据经验,请勿从未知来源镜像来部署代码。对于kubernetes,这意味着仅使用来自已知或列入白名单的注册镜像。

  13、将镜像扫描扩展到部署阶段

  作为镜像扫描的扩展,请在部署阶段根据扫描结果设置策略。一种设置方式是使用Validation Admission Controller,当Kubernetes指定没有扫描结果或严重漏洞的镜像时,或者如果镜像已建立超过90天,Kubernetes将拒绝使用该镜像进行应用部署。

  最近未扫描的镜像可能包含自上次扫描以来新发现的漏洞。

  14、适当使用标签和注释

  例如,考虑使用名称,电子邮件别名或负责应用程序团队的Slack Channel为deployments标记或者添加注释。这样可以更容易地提醒相应团队注意安全问题

  15、启用Kubernetes基于角色的访问控制(RBAC)

  RBAC提供了一种方法,用于控制对集群中的用户和服务帐户访问集群的Kubernetes API服务的授权。Kubernetes RBAC是高度可配置的,因此请确保您没有犯这5个Kubernetes RBAC错误中的任何一个错误(​​https://cloud.redhat.com/blog/5-kubernetes-rbac-mistakes-you-must-avoid​​)。

  还有更多构建和部署时安全性最佳实践,它们超出本文的范围。从这里开始,通过探索本文结尾处列出的其他点来提高安全性。

  接下来,我们将提供有关在运行阶段保护您的Kubernetes workload的建议

  三)运行阶段

  运行阶段使容器化的应用程序面临许多新的安全挑战。目标既是获得对运行环境的可见性,也是在威胁出现时对其进行安全监测和快速响应。

  在构建和部署阶段主动保护容器和kubernetes deployment可以大大降低运行时发生安全事件的可能性以及为影响这些事件而进行的后续工作量。

  监控与安全性最相关的容器活动,包括:

  • 进程活动情况
  • 容器服务之间的网络通信
  • 容器化服务与外部客户端和服务器之间的网络通信

  由于容器和Kubernetes具有声明性,因此在容器中观察容器行为来检测异常通常比在虚拟机中更容易。这些属性使您可以更容易地对所部署的内容及其预期活动进行自省

  16、利用kubernetes中的上下文信息

  使用kubernetes中的构建和部署时间信息来评估运行时观察到的活动与预期活动,以检测可疑活动

  17、将漏洞扫描扩展到正在运行的deployment

  除了扫描容器镜像中存在的漏洞之外,同时还要观察正在运行的deployment中是否有新发现的漏洞

  18、使用kubernetes内置控件以加强安全性

  配置pod的安全上下文以限制其功能。这些控件可以消除依赖特权访问的整个攻击类别。例如,只读根文件系统可以防止任何依赖于依赖于安装软件或写入文件系统的攻击。

  19、监控网络流量以限制不必要或不安全的通信

  观察您的应用网络流量并将该流量与基于Kubernetes网络策略所允许的流量进行比较。容器化的应用程序通常会大量使用集群网络,观察应用网络流量是了解应用程序如何相互交互并识别意外通信的好方法。

  同时,将应用流量与允许的流量进行比较,可以为您提供关于未发生但被允许的有价值的信息。有了这些信息,您就可以进一步收紧允许的网络策略,以消除多余的连接并减少攻击面。

  像​​https://github.com/kinvolk/inspektor-gadget​​之类的开源项目可能对此有所帮助,而商业安全解决方案则提供了不同程度的容器网络流量分析。

  20、利用进程白名单

  进程白名单是一种用于识别意外运行进程的经过尝试的真实做法。首先,观察应用程序一段时间,以识别在应用程序行为的正常过程中执行的所有进程,然后将经常加入到列表。该列表将用作针对应用程序行为的白名单。

  在进程级别对运行程序分析具有挑战性;可以寻求在容器和Kubernetes方面有经验的商业安全供应商的支持

  21、比较和分析相同deployment的pod中的不同运行时的状态

  由于高可用性、容错性或规模等原因,容器化的应用经常被复制。复制的应用的行为应该几乎相同;与其他复制的应用有重大偏差的应用需要进一步检测。

  将Kubernetes安全工具与其他外部系统(电子邮件、PagerDuty、Slack、Google Cloud Security Command Center、SIEMs[安全信息和事件管理]等)集成,并利用deployment标签或注释在检测到潜在威胁时提醒给负责应用的团队。商业Kubernetes安全供应商应该支持与外部工具的广泛集成。

  22、如果被攻破,将可疑的pod数量缩为零

  使用Kubernetes控制器自动将可疑的pod缩放为零或杀死,然后重新启动被破坏的应用程序实例。 

  四)基础设施安全

   安全性必须扩展到镜像和工作负载之外,并保护整个环节,包括集群基础结构。必须保护集群、节点和容器引擎。

  23、尽可能将kubernetes更新到最新版本

  仅支持Kubernetes的最后三个版本,其中包括针对新发现的漏洞的安全补丁。因此,如果在Kubernetes中发现了一个高严重性安全漏洞,并且您落后四个版本,则您的版本将不会收到补丁

  24、安全地配置kubernetes API服务

  确保您禁用未经身份验证的匿名访问,并使用TLS加密kubelet和API服务之间的连接。(​​https://cloud.redhat.com/blog/12-kubernetes-configuration-best-practices#6-securely-configure-the-kubernetes-api-server​​)

  25、etcd的安全

  etcd是kubernetes用于数据访问的键值存储。etcd被认为是kubernetes的信任来源。可以根据需要从中读取数据或将数据写入其中。确保仅通过TLS提供客户端连接。

  26、kubelet的安全

  作为在每个节点上运行的主节点代理,对kubelet的错误配置会通过kubelet进行后门访问。通过使用--anonymous-auth=false标志启动kubelet 并利用NodeRestriction准入控制器限制kubelet可以访问的内容,确保已禁用对kubelet的匿名访问。

  Kubernetes包含更多组件,包括kube-scheduler,kube-controller-manager,主节点和工作节点上的配置文件等。您可以通过以下方法了解有关如何安全配置这些Kubernetes组件并满足合规性要求的更多信息。(​​https://cloud.redhat.com/blog/12-kubernetes-configuration-best-practices​​)

  五)实施K8s的安全

  容器和kubernetes的出现并没有改变安全需求。目的仍然是使非法人员很难侵入应用程序及其基础设施,若被入侵成功,则要尽快捕获并组织他们。但是,这些工具和方法必须适应DevOps实践和云原生的需求。

  27、将安全更早地嵌入到容器的生命周期中

  必须尽早将安全集成到容器生命周期中,并确保安全需要和DevOps团队之间保持一致并实现共同的目标。安全可以(并且应该)是一个使能者,使您的开发人员和DevOps团队可以放心地构建和部署具有规模,稳定和安全的生产级别应用。

  28、使用Kubernetes-native安全控制来降低运营风险

  尽可能利用Kubernetes中内置的控件来强制执行安全策略,这样您的安全控件就不会与编排工具发生冲突。例如,不要使用第三方代理或shim来强制网络分段,而是使用Kubernetes网络策略来确保安全的网络通信。

  29、利用Kubernetes提供的上下文来优先进行补救工作

  在庞大的Kubernetes环境中,手动筛选安全事件和策略冲突是非常耗时的。例如,针对严重级别为7或有更高风险漏洞的deployment,如果该deployment包含特权容器并且已开放了Internet,则应上移修复优先级,但如果它位于测试环境中并且支持非关键应用程序,则修复优先级下移。

三、对kubernetes最佳实践的扩充