JackXuF 2020-09-25
Kubernetes还不到6岁,但它已经是每个人最喜欢的容器编排程序了。云和基础设施监测公司Datadog发现Kubernetes主导着容器市场:“大约45%的运行容器的Datadog客户使用Kubernetes。”其他容器编排程序,如Marathon和Docker swarm已经退出。
Kubernetes在公有云上更受欢迎。例如,根据Datadog的统计,“大约80%在Azure中运行容器的Datadog客户现在都在使用Kubernetes”。在亚马逊网络服务(AWS)上,Datadog发现它的受欢迎程度在过去两年翻了一番,达到了45%。
人气越高危险就越大。Windows用户深知,一个程序越受欢迎,就越容易受到攻击。Kubernetes也是如此。如果你在使用它,你必须保护它。
但是这并不容易。
Kubernetes的管理组织Cloud Native Computing Foundation(CNCF)最近对Trail of Bits和Atredis合作伙伴进行安全审计。Bits的报告说,Kubernetes存在许多安全问题,这是因为Kubernetes的配置和部署并不简单,某些组件的默认设置容易让人混肴,同时缺少操作控制以及隐式设计的安全控制。”
由此可见,这真的不容易。
不过,我们必须尝试。这是我们如何保证Kubernetes安全的前五种方法。
1.确保容器本身安全
如果容器损坏,保护Kubernetes并没有任何好处。开源安全公司Snyk在2019年分析了10个最受欢迎的Docker镜像。他们发现所有映像都包含易受攻击的系统库。
正如VMware副总裁兼首席开源官Dirk Hohndel 在2019年开源领袖峰会上所说的那样:“容器打包格式类似于Windows中的.exe和macOS中的.dmg,基本上你可以发布一个包含所有依赖项的完整文件系统。由于您现在将这些依赖项包含在容器中,因此您必须关注这些二进制文件用途,产生方式以及相应的来源。“
简而言之,您必须先确定容器的内容是可信任的,然后再将其部署给Kubernetes进行管理。否则,您将遇到最常见的计算机问题之一:垃圾回收(GIGO)。因此,您别无选择,只能检查每个生产容器是否存在潜在的安全问题。
是的,很痛苦。从来没有人说过安全是容易的。
2.锁定容器的Linux内核
从本处开始只会越来越困难。除了确保容器是安全的以外,由于所有容器都运行在单个Linux内核上,因此确保该内核尽可能安全是有意义的。而且,推荐使用AppArmor或SELinux进行安全配置,保护内核。
但是,这些复杂的配置限制了用户控制,程序管理,文件访问和系统维护。他们将其作为Linux安全模块来执行,该模块在Linux上强加了强制性访问控制(MAC)体系结构。对于Linux的内置安全模型(除非明确禁止,否则允许一切),这是一种完全不同的安全方法(除非明确允许,否则限制一切)。
很多系统管理员都无法正确设置两者。更糟糕的是,如果您配置错误,那这就不仅仅是一个重新配置的过程。如果您配置不对,您的Linux系统将被冻结,而您将不得不重新进行调整。或者,您可能认为它的配置是正确的,但是实际上您的容器可能仍然会像以前一样受到攻击。
正确以及安全的配置需要操作人员的大量时间和专业知识。在AppArmor或SELinux保护的内核上运行应用程序可能会遇到困难。大多程序对底层操作系统采取了安全措施。这些受保护的内核不允许这样做。
如果这两种方法中的任何一种被证明是太麻烦了,那么您可以通过阻止内核自动加载内核模块来获得一些保护。例如,由于即使是非特权进程也可以强制加载一些与网络协议相关的内核模块,只需创建一个特定的网络套接字,就可以添加规则来阻止有问题的模块。您可以使用禁止的模块配置文件来执行此操作:
/etc/modprobe.d/kubernetes-blacklist.conf
文件中记得加入配置说明,例如:
#SCTP在大多数Kubernetes集群中不使用,并且也有漏洞。
不过,最好的方法还是安装AppArmor或SELinux。
3.使用基于角色的访问控制(RBAC)
从Kubernetes1.8开始,您可以使用RBAC来控制用户可以做什么。这一点很重要,因为试图将运行在数十个实例和集群上的用户混为一谈来提供服务是非常恐怖的。使用RBAC,零信任安全方法,用户和组件(如应用程序和节点)只需要获得完成任务所需的权限。
RBAC在应用程序编程接口(API)级别上工作。这样,即使不使用授权者本身,RBAC规则也会锁定用户。RBAC还阻止用户通过编辑角色或角色绑定为自己提供更多特权。
默认情况下,它也会阻止外来者。RBAC策略向控制平面组件、节点和控制器授予作用域权限。但是,这一点很重要,它不向kube-system namespace之外的服务帐户授予任何权限。
为了便于管理Kubernetes,RBAC提供了预定义的角色。这样,开发人员、操作员和集群管理员只需获得他们所需的权限,而不需要任何用不到的权限。
在这个系统中,cluster admin角色相当于Unix和Linux的超级用户。群集管理员可以创建、编辑或删除任何群集资源。不用说,必须小心保护群集管理员角色的访问权限。
4.保守秘密的辛勤工作
Kubernetes Secrets对象包含敏感元素,例如密码,OAuth令牌或ssh密钥。简而言之,它们是Kubernetes集群的钥匙。您必须保护好他们。
Kubernetes会自动创建用于访问API的机密,并修改您的Pod以使用它们。但是,您的secrets(例如Pod访问数据库所需的用户名和密码)则在您的控制和保护之下。
很简单吧?不幸的是,Kubernetes的secrets带有许多内置的安全漏洞。官方所列出的漏洞简直令人恐惧。
这种情况很糟糕。你可以随时通过加密secrets来缓解它。如果可能的话,你也应该把这个secret与镜像或pod分开。一种方法是将进程拆分为单独的容器。例如,可以将应用程序分为前端容器和后端容器。后端具有私钥secret并响应来自前端的签名请求。
除非您既是安全管理员又是Kubernetes管理员,否则必须使用第三方秘密工具来保护您的secret。其中包括AWS Secrets Manager,Google Cloud Platform KMS和用于公共云的Azure Key Vault。而且,程序如Hashicorp Vault, CyberArk/Conjur, Confidant和Aqua Security Kubernetes Security for the Enterprise。
5.保持网络安全
从上面可以看出,允许访问etcd非常危险。正如Kubernetes安全企业ControlPlane的联合创始人Andrew Martin 在Kubernetes自己的博客中写道:“ 对API服务器的etcd的写访问权限等同于在整个集群上获得root权限,甚至可以很容易的使用读访问权限公平地提升特权。”
因此,Martin建议:“ etcd应该配置有peer和客户端TLS证书,并部署在专用节点上。为避免私钥被从工作节点窃取和使用,集群也可以通过防火墙连接到API服务器。
不仅etcd需要网络保护。由于Kubernetes完全由API驱动,因此默认情况下,所有内部集群通信均使用TLS加密。
但是,这还不够。默认情况下,Kubernetes Pod接受来自任何来源的流量。在此重复一遍:“任何来源。” Pod已开放用于网络连接,这并不安全。由您决定网络策略,该策略可以安全地定义Pod如何在群集内以及与外部资源进行通信。
您可以通过添加支持网络策略控制器的网络插件来实现。如果没有这样的控制器,您设置的任何网络策略都不会生效。不幸的是,Kubernetes默认没有官方默认甚至首选的网络策略控制器。相反,您必须使用第三方插件,如Calico,Cilium,Kube-router,Romana或Weave Net。不管怎样,我最喜欢的是Calico。
我建议您从**“默认拒绝所有**”网络策略开始。这样,仅允许您随后明确允许的与其他网络策略规则的连接。由于网络策略是在namespace中设置的,因此您需要为每个namespace设置网络策略。
设置完成后,您可以开始允许适当的网络访问规则。更多可以参考 【Kubernetes Network Policy Recipes】(https://github.com/ahmetb/kubernetes-network-policy-recipes)。
确保Kubernetes的安全是一项重要工作。
正如我在一开始所说的那样,保护Kubernetes确实不是一件容易的事。到现在为止,我相信您现在是非常同意我这一说法。
Kubernetes从一开始就被设计为易于部署。不幸的是,这也意味着它在设计上是不安全的。这意味着要增加安全性完全取决于您。幸运的是,增加安全性,则使你的Kubernetes集群更具有生产价值。
本文只谈到了Kubernetes安全需要解决的最重要的问题。当然还有很多其他的问题。但是,我真的希望我给了你足够的思路让你明白这工作有多重要。而且,您必须现在就开始保护Kubernetes集群,否则黑客会毫不犹豫地提醒您,您已经将公司的重要系统暴露在危险之中。