简介
Kubernetes 审计日志对于确保 Kubernetes 集群的安全、合规性和透明度至关重要。但是,对于托管 Kubernetes 基础设施,通常不支持传统的基于审计文件的日志传输,并且审计日志只能通过控制平面 API 或云提供商日志记录工具获取。在本博客中,我们将向您展示如何从这些其他来源提取审计日志,并仍然利用 Elastic Kubernetes 审计日志集成。
在本博客中,我们将重点关注 AWS 作为我们的云提供商,并且在从 AWS 提取日志时,您有多种选择
- AWS 自定义日志集成(我们将在本博客中使用)
- AWS Firehose 将日志从 Cloudwatch 发送到 Elastic
- AWS 通用集成,支持多种 AWS 来源
在这个由两部分组成的系列的第一部分中,我们将重点关注正确提取 Kubernetes 审计,第二部分将重点关注调查、分析和告警。
Kubernetes 审计文档描述了需要审计才能获得以下问题的答案
- 发生了什么?
- 何时发生的?
- 谁发起的?
- 它发生在什么资源上?
- 在哪里观察到的?
- 从哪里发起的(源 IP)?
- 它要去哪里(目标 IP)?
当事件发生并进行调查时,以上问题的答案变得非常重要。或者,对于试图满足合规要求的受监管公司来说,这可能只是一个日志保留用例。
我们特别重视 Kubernetes 中的审计日志,因为默认情况下未启用审计日志。审计日志会占用大量内存和存储空间。因此,通常需要在保留/调查审计日志与放弃原本为托管在 Kubernetes 集群上的工作负载分配的资源之间取得平衡。我们讨论 Kubernetes 中的审计日志的另一个原因是,与通常的容器日志不同,在启用后,这些日志被编排写入云提供商的日志服务。对于大多数云提供商来说都是如此,因为 Kubernetes 控制平面由云提供商管理。对于云提供商来说,使用其内置的编排工作流(涉及控制平面)来支持由其日志记录框架实现支持的托管服务是有意义的。
默认情况下,Kubernetes 审计日志可能非常详细。因此,选择性地选择需要完成多少日志记录变得非常重要,以便满足组织的所有审计要求。这是在审计策略文件中完成的。审计策略文件针对
在本博客中,我们将使用 AWS 上的 Elastic Kubernetes Service (Amazon EKS) 以及自动传输到 AWS CloudWatch 的 Kubernetes 审计日志。
管理员用户在 EKS 上创建的名为“empty-secret”的机密的示例审计日志以以下格式记录在 AWS CloudWatch 上:
一旦审计日志显示在 CloudWatch 上,就该考虑如何将其传输到 Elasticsearch 了。Elasticsearch 是一个很棒的平台,可以创建可视化 Kubernetes 集群中记录的不同审计事件的仪表板。它也是分析各种审计事件的强大工具。例如,一小时内进行了多少次秘密对象创建尝试?
现在我们确定 Kubernetes 审计日志已记录在 CloudWatch 中,让我们讨论如何将日志提取到 Elasticsearch 中。Elasticsearch 集成可以消费在 CloudWatch 上编写的日志。默认情况下,仅使用此集成将从 CloudWatch 获取 JSON,即真正的审计日志 JSON 嵌套在包装器 CloudWatch JSON 内。将日志引入 Elasticsearch 时,务必使用Elastic Common Schema (ECS) 以获得最佳的搜索和分析性能。这意味着需要一个提取管道来解析标准 Kubernetes 审计 JSON 消息并在 Elasticsearch 中创建符合 ECS 的文档。让我们深入了解如何实现这一点。
Elasticsearch 具有一个使用 Elastic Agent 的 Kubernetes 集成,可从控制台使用 Kubernetes 容器日志,并从文件路径使用审计日志。对于如上所述的云提供商用例,可能无法将审计日志写入 Kubernetes 集群上的路径。那么,我们如何利用 ECS 设计用于解析 Kubernetes 审计日志,该设计已在 Kubernetes 集成中实现,以处理 CloudWatch 审计日志?那是最令人兴奋的管道部分!让我们看看如何做到这一点。
我们要做的
-
从云提供商的日志记录模块中读取 Kubernetes 审计日志,在我们的示例中,由于日志位于此处,因此读取 AWS CloudWatch 中的日志。我们将使用 Elastic Agent 和Elasticsearch AWS 自定义日志集成从 CloudWatch 读取日志。注意:请注意,有多个 Elastic AWS 集成,我们专门使用 AWS 自定义日志集成。
-
创建两个简单的提取管道(这样做是为了隔离和可组合性的最佳实践)
-
第一个管道查找 Kubernetes 审计 JSON 消息,然后将其重定向到第二个管道
-
第二个自定义管道将关联 JSON
消息字段,该字段与 Elasticsearch Kubernetes 审计托管管道(又名集成)所期望的正确字段相关联,然后将消息重定向到正确的数据流,kubernetes.audit_logs-default,这反过来又会将所有正确的映射和提取管道应用于传入消息 -
总体流程将是
1. 创建 AWS CloudWatch 集成
a. 填充 AWS 访问密钥和密钥对值
b. 在日志部分,填充日志 ARN、标签并保留原始事件(如果需要),然后保存此集成并退出页面
2. 接下来,我们将配置自定义提取管道
我们这样做是因为我们想覆盖通用托管管道的功能。我们将通过搜索安装 AWS CloudWatch 集成时作为资产创建的托管管道来检索自定义组件名称。在本例中,我们将添加自定义提取管道
从开发工具控制台运行以下命令。在这里,我们从 CloudWatch JSON 中提取消息字段,并将值放入名为 kubernetes.audit 的字段中。然后,我们将此消息重定向到 Kubernetes 集成附带的默认 Kubernetes 审计数据集或 ECS
PUT _ingest/pipeline/logs-aws_logs.generic@custom
{
"processors": [
{
"pipeline": {
"if": "ctx.message.contains('audit.k8s.io')",
"name": "logs-aws-process-k8s-audit"
}
}
]
}
PUT _ingest/pipeline/logs-aws-process-k8s-audit
{
"processors": [
{
"json": {
"field": "message",
"target_field": "kubernetes.audit"
}
},
{
"remove": {
"field": "message"
}
},
{
"reroute": {
"dataset": "kubernetes.audit_logs",
"namespace": "default"
}
}
]
}
让我们进一步理解这一点
-
当我们创建 Kubernetes 集成时,我们会得到一个名为
logs-kubernetes.audit_logs的托管索引模板,该模板写入名为logs-kubernetes.audit_logs-1.62.2的管道,默认情况下。 -
如果我们查看管道
logs-kubernetes.audit_logs-1.62.2,我们会看到所有的处理器逻辑都针对字段kubernetes.audit进行操作。 这就是为什么我们上面代码片段中的 json 处理器会创建一个名为kubernetes.audit,然后再删除原始的 *message* 字段并重新路由。重新路由会定向到kubernetes.audit_logs数据集,该数据集支持logs-kubernetes.audit_logs-1.62.2管道(数据集名称来源于管道名称约定,格式为logs-<datasetname>-version)
3. 现在让我们验证日志是否真的在流动,并且审计消息正在被解析
a. 我们将使用 Elastic Agent 并使用 Fleet 以及我们在步骤 1 中创建的集成策略进行注册。有多种部署 Elastic Agent 的方法,在本练习中,我们将使用 Docker 进行部署,这既快速又简单。
% docker run --env FLEET_ENROLL=1 --env FLEET_URL=<<fleet_URL>> --env FLEET_ENROLLMENT_TOKEN=<<fleet_enrollment_token>> --rm docker.elastic.co/beats/elastic-agent:8.16.1
b. 在 Discover 中检查消息。在 8.15 版本中,还有一个名为 Logs Explorer 的新功能,只需点击几下即可查看 Kubernetes 审计日志(和容器日志)(见下图)。瞧!我们可以看到 Kubernetes 审计消息已被解析!
4. 让我们快速回顾一下我们所做的事情
我们在 ElasticSearch 中配置了 CloudWatch 集成,以从 CloudWatch 读取 Kubernetes 审计日志。然后,我们创建了自定义的摄取管道,将审计消息重新路由到正确的数据流,以及 Kubernetes 审计日志集成附带的所有开箱即用的映射和解析。
在下一部分中,我们将研究如何分析摄取的 Kubernetes 审计日志数据。