category
我们概述了在集群环境中应优先考虑的安全缓解措施和设置。我们关于Kubernetes集群的安全指南的第二部分涵盖了与工作节点、kubelet、pod和审计日志相关的最佳实践。
在上一篇文章中,我们讨论了开发人员保护控制平面组件的不同方式,包括Kube API服务器配置、RBAC授权以及通过网络策略在pods之间进行通信的限制。
这一次,我们将重点关注开发人员可以实现的最佳实践,以保护工作节点及其组件。我们将讨论kubelet、pod,以及如何设置审计日志以更好地了解集群。最后,我们包括一些基本提示,尽管它们看起来像是常识,但仍需要强调。
对于我们的大多数示例,应该注意的是,我们将在Kubernetes v1.18中使用kubeadm集群设置。
工作节点
如果控制平面是操作的大脑,那么工作节点就是肌肉。它们运行并控制集群中的所有pod和容器。集群上可以有零个或多个工作节点,但不建议在与控制平面相同的节点上运行pod。Worker的主要组件是kubelet、容器运行时接口(默认情况下是Docker,但可能是另一个)和kube代理。通过使用kubectl命令:kubectl get-nodes,您可以查看所有节点,包括主节点。输出应该类似于下图:
kubectl get-nodes命令的输出
图1。kubectl get-nodes命令的输出
让我们从推荐的工作节点配置文件的所有权和权限开始。根据CIS Kubernetes Benchmark v1.5.1,以下是您应该监控Workers的任何更改的主要文件:
File or directory |
Recommended ownership |
Recommended permission (or more restrictive) |
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf |
root:root |
644 |
kube-proxy config file |
root:root |
644 |
/etc/kubernetes/kubelet.conf |
root:root |
644 |
certificate authorities file |
root:root |
644 |
/var/lib/kubelet/config.yaml |
root:root |
644 |
表1。CIS Kubernetes Benchmark v1.5.1建议
kubelet
kubelet是在集群的每个节点上运行的代理,它确保所有容器都在一个pod中运行。它也是对节点进行任何配置更改的代理。尽管它没有显示在Kubernetes的主架构图上,但即使是主节点也有一个kubelet(和一个kube代理)代理在运行,以防您想在那里运行其他pod,尽管不建议这样做。
关于kubelet安全设置,您需要担心两个主要问题:限制kubelet权限和轮换kubelet证书。限制kubelet权限可以防止攻击者在攻破容器后读取您的kubelet凭据,并可以在集群中执行其他操作。
要检查这些设置,您可以在任何主节点上运行ps-ef|grep kube apiserver,并查看默认情况下启用了什么,例如在此处的图像中(请注意,我们使用的是v1.18.5版本的kubeadm集群设置的默认设置,因此此处的结果可能与您的不同)。
显示kubelet安全设置的ps-ef|grep kube apiserver的命令输出
图2:显示kubelet安全设置的ps-ef|grep kube apiserver的命令输出
Kubelet的RBAC
从上图中可以看出,--authorization mode参数已经设置了“Node,RBAC”值,这些值是默认启用的。但是,这在集群中可能有所不同,因此仔细检查它总是很重要的。
我们之前没有提到准入控制器,但它们是在执行某些验证或更改(也称为突变)的请求的身份验证和授权阶段之后向Kube API服务器请求期间可以调用的代码。验证和突变是Kubernetes中两种类型的准入控制器。准入控制器也可以是两者的组合。它们之间唯一的区别是突变控制器可以修改对象,而验证不能。
要检查集群上启用了哪些准入控制器,请检查kube apiserver设置中的-enable准入插件参数。您可以通过在主节点上键入以下命令来完成此操作:ps-ef|grep-kube-apiserver|grep-enable admission-plugins。在我们的测试集群上,默认启用的唯一准入控制器是NodeRestriction。这限制了kubelet可以修改的对象,因此也限制了哪些pod可以读取哪些秘密。在这样做的过程中,它不允许pod读取集群中的任何机密,除了连接到其节点的机密或允许查看的机密。
要了解更多关于准入控制器以及您可以启用哪些准入控制器的信息,请查看Kubernetes官方文档。
kubelet代理使用有效期为一年的证书对API服务器进行身份验证。您还应该配置kubelet证书轮换以生成新密钥,并在当前证书即将过期时从Kubernetes API请求新证书。
你可以在这里找到更多关于证书轮换的信息。
Pod
在保护了控制平面、工作节点和大多数组件之后,我们现在似乎是安全的,但事实并非如此。正如第一篇文章中所讨论的,我们总是试图应用深度防御方法来减少我们的攻击面,使攻击者更难利用我们的集群。
您可以采取三种主要行动来确保您的吊舱的基本安全级别:
- 限制资源。您最不希望在集群上发生的事情是,您的一个pod开始消耗节点上的所有可用资源,使其他pod出现性能问题,并可能导致节点上的拒绝服务(DoS)。Kubernetes有一个解决方案,叫做ResourceQuotas。您也可以在PodSpec上定义硬限制和软限制,但这很难快速管理。同时,ResourceQuota是一个允许您在命名空间中设置硬资源和软资源限制的对象。要启用ResourceQuota,您需要在kube apiserver标志上设置它–enable admission-plugins=ResourceQuota。您可以使用以下命令检查您的kube apiserver设置:ps–ef|grep-kube apiserver。以下是ResourceQuota对象的示例:
图3。示例ResourceQuota对象
来源:Kubernetes资源配额文档
- 创建并应用安全上下文。安全上下文允许您定义pod或容器的权限和访问控制权限。以下是一些您应该尽可能始终使用的安全控制措施:
- AllowPrivilegeEscalation。这控制进程是否可以获得比其父进程更多的特权。这应该设置为false。
- 只读根文件系统。这定义了容器是否具有只读根文件系统。默认设置为false,但建议您将其设置为true。
- RunAsNonRoot。此设置指示容器是否必须以非根用户身份运行,并且应设置为true。将其设置为true的结果是,在容器试图以根用户(UID 0)身份运行的任何情况下,kubelet都会对其进行验证,但无法启动容器。
- 使用Seccomp、AppArmor和SELinux。这些是Linux内核的安全特性,也可以通过SecurityContext进行设置。然而,它们如何工作的细节不在本文的范围之内。有关更多信息,您可以查看Linux基金会的概述。
- Seccomp。此功能过滤进程的系统调用。目前,它仅在API的alpha版本上可用,并且可以在SecurityContext对象定义中设置为:seccomp.security.alpha.kubernetes.io/pod:runtime/default。
- AppArmor。此功能使用程序配置文件来限制单个程序的功能:也就是说,通过将程序限制在一组有限的资源中。它目前在测试版上可用,可以这样设置:
- container.appermor.security.beta.kubernetes.io/container:runtime/default。
SELinux。这启用了SELinux模块,该模块将安全标签应用于对象,并通过安全策略评估所有与安全相关的交互。以下是如何应用它的示例:
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
Pod安全策略
Pod安全策略(PSP)是一个可以控制前面提到的集群级别的大多数安全设置的对象。要做到这一点,您还需要启用一个名为PodSecurityPolicy的准入控制器,默认情况下不会启用该控制器。创建PSP后,您需要授权用户,以便他们可以通过RBAC通过我们在本系列文章的第一部分中提到的ClusterRole和ClusterRoleBinding使用它。您也可以使用Role和RoleBinding,但这会将PSP的使用限制在特定的命名空间中。以下是您可以通过PodSecurityPolicy在集群上控制的内容列表:
可以通过PodSecurityPolicy在集群上控制的内容的列表
图4。可以通过PodSecurityPolicy在集群上控制的内容的列表
来源:Kubernetes关于Pod安全策略的文档
PodSecurityPolicies的更多示例可以在Kubernetes的官方文档中看到。
审核日志
日志是系统的重要组成部分,尤其是像Kubernetes集群这样的复杂系统。审计日志可以记录对Kube API服务器的所有请求,因为它是集群内的中心通信点。不幸的是,Kubernetes审核日志在默认情况下被禁用,因为它们会增加API服务器的内存消耗。
作为群集管理员,您的工作就是设置此项。我们强烈建议您在将集群投入生产之前执行此操作;这不仅可以帮助您检测任何安全问题,还可以帮助您的开发人员进行调试和故障排除。要做到这一点,您需要在kube-apiserver配置上至少设置前两个标志:
- --audit-log-path:告诉您希望Kubernetes保存日志的日志文件的位置
- --审核策略文件:告诉您为集群定义的审核策略文件的位置
- audit-log-maxage:告诉保留审核日志文件的天数
- --audit-log-maxbackup:告诉要保存为备份的审核日志文件的数量
- --audit-log-maxsize:告诉每个审核日志文件在旋转之前的大小
这样做的方法是创建一个审核策略对象,该对象定义应记录哪些事件以及应收集哪些数据。您可以为集群上的不同资源设置不同的日志记录级别。该策略有四个已知的审核级别:
- 没有一个不会记录匹配的事件
- 元数据。只记录请求元数据,不记录请求或响应主体
- 要求记录请求元数据和请求正文,但不记录响应
- 请求响应。记录事件元数据、请求和响应主体
这是记录所有请求元数据的审核策略的基本示例:
用于记录所有请求元数据的示例审核策略
图5。用于记录所有请求元数据的示例审核策略
既然你有了一个策略,你如何告诉Kubernetes开始记录数据?为此,您需要将所做的更改应用于kube-apiserver.yaml文件。最后要记住的一件事是,如果kube-apiserver被部署为Pod,则需要装载带有日志和策略文件位置的hostPath。
已装入卷的示例
装载的hostPath的示例
图6。安装体积的样本(顶部);装载的主机路径示例(底部)
来源:Kubernetes关于审计和日志后端的文档
此外,我们强调以下几点,因为我们认为这样做非常重要:请考虑在您的集群上启用审核日志。不过,别忘了制定一个适当的政策;否则,空间会很快用完。
有关Kubernetes审计的更多信息可以在官方文档中找到。您还可以查看Datadog在KubeCon NA 2019期间对审计日志的精彩演示。
这里有一个快速提示:如果您的节点上安装了Trend MicroTM Deep SecurityTM或Trend Micro Cloud OneTM代理,请确保检查您是否已启用这些入侵防御系统(IPS)规则来检测集群上的任何更改,并保护其免受已知的Kubernetes漏洞和攻击:
- 1009450–Kubernetes API代理请求处理权限提升漏洞(CVE-2018-1002105)
- 1009493–Kubernetes Dashboard身份验证绕过信息泄露漏洞(CVE-2018-18264)
- 1009561–Kubernetes API服务器拒绝服务漏洞(CVE-2019-1002100)
这些完整性监视(IM)规则监视主节点和辅助节点的主文件和进程中的任何可疑更改,并向它们发出警报:
- 1009060–Kubernetes Cluster Master
- 1009434–Kubernetes集群节点
以下日志检查(LI)规则检查Kubernetes主节点组件的日志,并根据不同的事件向它们发出警报。
- 1009105–Kubernetes控制平面
保护Kubernetes集群的基础知识
最后,永远记住基础知识。除了应用上述措施来保护您的Kubernetes环境外,不要忘记一些关于集群日常工作的基本内务规则:
- 尽早并经常通过kubectl更新来更新您的Kubernetes环境版本。在生产中应用之前,将其应用于测试环境。
- 不要将管理员用户用于您的日常工作;管理员只能由连续集成和连续部署(CI/CD)工具使用。
- 除非您有任何业务或合规限制,否则请考虑使用托管服务,如Azure Kubernetes Service(AKS)、Amazon Elastic Kubernets Service(Amazon EKS)或Google Kubernete Engine(GKE),因为它们通常对您的安全态势有更好的默认设置,并且维护控制平面的成本非常低。
- 为Kubernetes应用CIS基准文档中概述的安全最佳实践,这些文档已被不同行业开发和接受。
- 在GitHub上查看、加入并分叉我们的Awesome K8s安全列表
- 登录 发表评论
- 4 次浏览
Tags
最新内容
- 1 day 11 hours ago
- 1 day 14 hours ago
- 1 day 14 hours ago
- 4 days 6 hours ago
- 4 days 13 hours ago
- 4 days 14 hours ago
- 4 days 14 hours ago
- 4 days 14 hours ago
- 1 week 1 day ago
- 1 week 1 day ago