随着越来越多的组织开始拥抱云原生技术,Kubernetes已经成为容器编排领域的行业标准。这种向Kubernetes的转变极大地简化并自动化了容器化应用程序的部署、扩展和管理,为传统的单体系统提供了优于传统管理协议的众多优势。然而,大规模管理Kubernetes会带来一系列独特的挑战,包括加固集群、保护供应链以及在运行时检测威胁。本文结合云原生计算基金会(CNCF)、美国国家安全局(NSA)、网络安全与基础设施安全局(CISA)的众多最佳实践,整理出6条Kubernetes安全加固建议,以帮助组织降低风险。集群设置和强化保护Kubernetes环境从强化集群开始。对于使用GKE、EKS或AKS等托管Kubernetes服务的用户,相应的云提供商管理主节点安全并为集群强制执行各种默认安全设置。GKEAutopilot执行GKE强化指南和GCP安全最佳实践的额外步骤。但即使对于GKEStandard或EKS/AKS用户,云提供商也有一套指南来保护用户对KubernetesAPI服务器的访问、容器对云资源的访问以及Kubernetes升级。指南如下:GKEHardeningGuideEKSSecurityBestPracticesGuideAKSClusterSecurity对于自我管理的Kubernetes集群(如kube-adm或kops),可以使用kube-bench来测试集群是否满足CISKubernetes基准测试。主要建议包括:加密存储在静态etcd中的秘密,使用TLS证书保护控制平面通信,以及启用审计日志记录。网络和资源策略默认情况下,Kubernetes允许从任何pod到同一集群中的另一个pod的通信。虽然这是发现服务的理想选择,但它不提供网络隔离,犯罪或受感染的系统可以不受限制地访问所有资源。如果团队使用命名空间作为Kubernetes内多租户的主要方式,这将成为一个非常严重的问题。要控制pod、命名空间和外部端点之间的流量,应使用支持NetworkPolicyAPI的CNI插件(例如Calico、Flannel或特定于云的CNI)来进行网络隔离。遵循零信任模型,最佳实践是实施默认的一揽子拒绝策略,阻止所有入站和出站流量,除非另一个策略特别允许。除了网络策略,Kubernetes还提供了两种资源级别的策略:LimitRange和ResourceQuotas。LimitRanges可用于限制单个资源的使用(例如每个pod最多2个CPU),而ResourceQuota控制聚合资源的使用(例如dev命名空间中总共20个CPU)。RBAC和服务帐户一旦制定了强大的网络和资源策略,下一步就是实施RBAC授权以限制访问。Kubernetes管理员可以对用户和组强制执行RBAC以访问集群,以及限制服务访问集群内部和外部的资源(例如云托管的数据库)。此外,企业应该谨慎使用在创建时安装到每个pod的默认服务帐户。Pod可能会被授予过多的权限,具体取决于授予默认服务帐户的权限。如果不需要与Kubernetes服务进行特定通信,请将automountServiceAccountToken设置为false以防止挂载。系统强化既然集群是安全的,下一步就是最小化系统的攻击面。这适用于节点上运行的操作系统以及容器上的内核。选择为运行容器而优化的专用操作系统,例如AWSBottlerocket或GKECOS,而不是通用Linux节点。接下来,利用Linux内核安全功能,例如SELinux、AppArmor(自1.4起测试版)和/或seccomp(自1.19起稳定)。AppArmor为Linux用户或用户组定义权限,将程序限制在一组有限的资源中。一旦定义了AppArmor配置文件,带有AppArmor注释的pod将执行这些规则。apiVersion:v1kind:Podmetadata:name:apparmorannotations:container.apparmor.security.beta.kubernetes.io/hello:localhost/k8s-apparmor-example-deny-writespec:containers:-name:helloimage:busyboxcommand:["sh","-c","echo'HelloAppArmor!'&&sleep1h"]另一方面,Seccomp限制了对容器的系统调用。只要seccomp配置文件在底层Kubernetes节点上可用,就可以在securityContext部分中定义seccomp配置文件。apiVersion:v1kind:Podmetadata:name:audit-podlabels:app:audit-podspec:securityContext:seccompProfile:type:LocalhostlocalhostProfile:profiles/audit.jsoncontainers:-name:test-container图像:hashicorp/http-echo:0.2.3参数:-“-text=刚刚进行了一些系统调用!”即使没有seccomp配置文件,用户仍然可以限制容器免受各种特权升级攻击。在安全上下文中,Kubernetes允许配置容器是否可以以特权或root身份运行,或者将特权提升到root身份。用户还可以限制hostPID、hostIPC、hostNetwork和hostPaths。所有这些设置都可以通过Pod安全策略(在v1.21中弃用)或使用其他开源工具(例如K-Rail、Kyverno和OPA/Gatekeeper)来强制执行。最后,如果需要额外的安全保证,可以配置自定义RuntimeClass以充分利用硬件虚拟化(例如gVisor或Kata)。在节点级别定义RuntimeClass并在pod定义部分中指定它。apiVersion:node.k8s.io/v1#RuntimeClass在node.k8s.ioAPI中定义对应CRI配置的---apiVersion:v1kind:Podmetadata:name:mypodspec:runtimeClassName:myclass供应链安全即使集群和系统是安全的,要保证整个应用的端到端安全,供应链也必须考虑。对于内部开发的应用程序,遵循创建容器的最佳实践,即使用最小的基础镜像来减少攻击面,修复包版本,并使用多阶段构建来创建小镜像。另外,定义容器运行所需的非root用户,或者使用podman构建无root容器来限制root访问。接下来,使用开源工具(例如Trivy、Clair或Anchore)或商业工具扫描所有图像中的漏洞。一些工具还允许对图像进行签名和验证签名,以确保容器在构建和上传过程中未被篡改。最后,定义一个白名单注册表,Kubernetes可以使用ImagePolicyWebhook或上述任何策略实施工具从中提取图像。监控、日志记录和运行时安全此时,我们有一个安全的集群和一个受到严密保护的供应链,可以生成干净、经过验证的图像,访问权限有限。然而,环境是动态的,安全团队需要能够响应操作环境中的事件。首先,将readOnlyRootFilesystem设置为true,将tmp日志文件存储到emptyDir中,保证容器在运行时不发生变化。除了典型的应用监控(如Prometheus/Grafana)或日志(如EFK)存储外,还可以使用Falco或Sysdig来分析系统调用过程和KubernetesAPI日志。这两种工具都可以在运行时解析来自内核的Linux系统调用,并在违反规则时触发警报。示例规则包括:权限升级警报、已知目录上检测到的读/写事件警报或shell调用警报。最后,将KubernetesAPI审计日志与现有的日志聚合和警报工具集成,以监控集群中的所有活动。这包括API请求历史记录、性能指标、部署、资源消耗、操作系统调用和网络流量。结论由于云原生系统的复杂性,需要采用多层方法来保护Kubernetes环境。建议Kubernetes做好云原生安全的4C:云、集群、容器、代码。首先,加固集群并遵循云安全最佳实践;第二,严格保护容器以减少攻击面、限制访问并确保运行时不变性;第三,保护供应链并分析代码和容器以查找漏洞。最后,监控运行时的所有活动,为在Kubernetes中运行的每一层软件构建防御。参考链接:https://dzone.com/articles/kubernetes-security-guide-high-level-k8s-hardening
