title: "如何设计一个符合工业标准的审计系统" date: 2024-04-15T16:44:40+08:00 categories: [Cloud Native Computing] tags: [audit] aliases: [/posts/audit-system-design/]
审计追踪(Audit Trail)是指一个系统中用于记录用户行为日志、控制组件的活动日志等关键安全信息的服务。日志通常以时间顺序排列,记录了“谁在什么时间做了什么”。
下面是 kubernetes 官方文档对其审计服务的描述:
Kubernetes 审计(Auditing) 功能提供了与安全相关的、按时间顺序排列的记录集,记录每个用户、使用 Kubernetes API 的应用以及控制面自身引发的活动。
审计功能使得集群管理员能够回答以下问题:
- 发生了什么?
- 什么时候发生的?
- 谁触发的?
- 活动发生在哪个(些)对象上?
- 在哪观察到的?
- 它从哪触发的?
- 活动的后续处理行为是什么?
与审计相关的,常见的工业标准有 IEC62443、NIST SP 800-92。下面是 IEC 中涉及到审计相关的章节。
工业标准 | 章节 | 安全级别 |
---|---|---|
IEC 62443-4-2:2019 | CR2.8 | SL-C 1 |
IEC 62443-4-2:2019 | CR6.1 | SL-C 1 |
IEC 62443-4-2:2019 | CR6.2 | SL_C 2 |
IEC 62443-4-2:2019 | CR1.13 | SL_C 1 |
IEC 62443-4-2:2019 | CR2.9 | SL_C 1 |
IEC 62443-4-2:2019 | CR2.10 | SL_C 1 |
IEC 62443-4-2:2019 | CR3.7 | SL_C 1 |
IEC 62443-4-2:2019 | CR3.9 | SL_C 2 |
对于本地运行的软件,通常 Syslog 具有更好的系统兼容性。对于使用 ELK 采集日志的项目更适合用 CEF,其他情况建议使用自定义的 JSON。
下面是三种格式(协议)的对比。
Elastic-Search 使用的、一种基于 Event-souring 思想设计的日志格式。优点是冗余信息少,适合配合 ELK 体系构建监控系统。 它的传输基于 Syslog 协议,同时扩展了可读性的 key-value,基于文本的设计也可以让 CEF 格式的日志写入到文件。总体来说,它是这几种格式中在可读性、效率和标准三方面最平衡的一个。
Syslog 是 Linux 操作系统默认的审计日志格式,通常采用其 RFC5424 版本。大部分 SIEM1 系统都支持这种格式的导入。 Syslog 协议适配性很好,基于 mTLS 的 Syslog 传输可以在兼容传统软件的同时,最大程度保证系统的安全性。但是对于微服务来说,实现和维护标准协议成本较高。所以如 AWS CloudTrail, OpenTelemetry 等都选择更简单的 HTTPS + JSON 格式。
大部分 SaaS 产品都是用 JSON,简单高效。JSON 的特点是冗余信息多,结构容易解析。例如,下面是OpenTelemetry 官方文档提到的日志模型中的字段:
Field Name | Description |
---|---|
Timestamp | Time when the event occurred. |
ObservedTimestamp | Time when the event was observed. |
TraceId | Request trace id. |
SpanId | Request span id. |
TraceFlags | W3C trace flag. |
SeverityText | The severity text (also known as log level). |
SeverityNumber | Numerical value of the severity. |
Body | The body of the log record. |
Resource | Describes the source of the log. |
InstrumentationScope | Describes the scope that emitted the log. |
Attributes | Additional information about the event. |
下面是 kubernetes apiserver 关于 Audit 消息格式定义的例子:
{
"apiVersion": "audit.k8s.io/v1",
"kind": "Event",
"level": "Metadata",
"auditID": "12345678-1234-1234-1234-1234567890ab",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/pods",
"verb": "get",
"user": {
"username": "admin",
"uid": "1234",
"groups": ["system:masters"],
"extra": {
"someKey": ["someValue"]
}
},
"sourceIPs": ["192.168.1.1"],
"userAgent": "kubectl/v1.20.0 (linux/amd64) kubernetes/abcdef",
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "my-pod",
"uid": "abcdef12-3456-7890-abcd-ef1234567890",
"apiVersion": "v1",
"resourceVersion": "12345",
"subresource": "status"
},
"responseStatus": {
"metadata": {},
"status": "Success",
"code": 200
},
"requestObject": {
"metadata": {
"name": "my-pod",
"namespace": "default"
},
"spec": {
"containers": [
{
"name": "my-container",
"image": "my-image"
}
]
}
},
"responseObject": {
"metadata": {
"name": "my-pod",
"namespace": "default",
"resourceVersion": "12345"
},
"spec": {
"containers": [
{
"name": "my-container",
"image": "my-image"
}
]
},
"status": {
"phase": "Running"
}
},
"requestReceivedTimestamp": "2023-05-21T12:34:56Z",
"stageTimestamp": "2023-05-21T12:34:57Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by RoleBinding \"admin-binding\""
}
}
对于审计日志来说,安全性要求会被一般日志系统更高。
安全性,通常可以从机密性(Confidentiality),完整性(Integrity),可用性(Availability)三个维度来考量。
攻击者可以通过系统的安全漏洞,获取特殊权限,进而查看某些审计日志。
可以采取以下措施:
攻击者可以通过系统的安全漏洞,修改、删除某些审计日志。
除了上面提到的加密和权限控制,还可以采取以下措施:
日志文件的限制:通常要除了限制日志文件的大小,还要限制备份数量、最长备份天数等。下面是 kubernetes 中关于日志文件存储的参数:
攻击者可以攻击审计追踪服务,导致审计追踪服务内存、磁盘空间不足等。
审计上下文:记录审计日志会显著增加系统内存和流量的使用。所以审计服务应该缓存审计相关的上下文,如服务名称和 ID 的映射关系、事件 ID 和描述等。不同服务向审计服务发送消息时应以最小长度为原则设计消息结构。审计服务的策略中应该允许用户配置日志级别,过滤规则等以减少系统负担。
审计服务除了导出文件格式的日志,通常也要支持第三方系统的导出。我们通常把分析、存储日志的第三方服务称为 SIEM (Security information and event management)。在 kubernetes 中,导出日志到第三方 web 服务的模块称为 webhook。
导出到第三方系统通常可以采用标准的 Syslog 格式或是 JSON Lines,支持范围最广。此外,需要考虑日志截断、第三方系统批处理和流处理的配置等,可以参考 kubernetes 的这篇文档。
由于设计侧重点不同,下面提供的每种开源项目都需要慎重考虑其优点和不足,其特性是否满足自身需要、系统的环境是分布式还是单体应用。
大部分 Linux 默认的审计服务,配合 rsyslog 等工具,可以解决本地设备的日志采集、查看、过滤。 rsyslog 基于字符串 template 的日志格式配置可以满足使用不同 SIEM 系统的用户集成的需要。
AWS 的 Cloud Trail 采用应用服务主动推送审计事件的模式,用户可以为设计追踪服务设置策略,收集到的日志会分别按需流入后续的批处理和流处理工具链中。
kubernetes 的日志收集与 AWS 实现类似,也是基于中心化的服务,但是这套架构设计并非只为审计日志一种情况设计。它遵循了很多 kubernetes 声明式设计的理念,非常值得学习。
例如 kubernetes 专门为审计设计的 stage:
每个请求都可被记录其相关的阶段(stage)。已定义的阶段有:
- RequestReceived - 此阶段对应审计处理器接收到请求后, 并且在委托给其余处理器之前生成的事件。
- ResponseStarted - 在响应消息的头部发送后,响应消息体发送前生成的事件。 只有长时间运行的请求(例如 watch)才会生成这个阶段。
- ResponseComplete - 当响应消息体完成并且没有更多数据需要传输的时候。
- Panic - 当 panic 发生时生成。
kubernetes 审计事件 使用和 Event API 不同的消息结构3。
综上,云平台的审计服务设计可以总结为:
OpenTelemetry 是现在云原生最主流的日志框架。可以支持侵入式(SDK)、非侵入式(Agent)两种日志采集模式。Collector 的设计可以让一部分日志处理的工作放在日志发送端完成。
审计追踪(Audit Trail)是指系统记录下所有影响操作或事件的时间顺序记录,用于追踪系统活动,核查是否存在违规行为。
审计日志应具备以下特性:
常见的审计日志格式有 Syslog、CEF、JSON 等,主要区别在于冗余信息、可读性和与日志收集系统的兼容性。
审计日志具有较高的安全性要求:
一些典型的审计日志系统架构:
SIEM 是安全信息和事件管理(Security Information and Event Management)的缩写。https://www.microsoft.com/en-us/security/business/security-101/what-is-siem↩
对于日志的加密,一般在服务端会对日志额外添加 checksum 链来校验。可以参考亚马逊的实现 server-side encryption (SSE-S3).↩