收集 Slack 审核日志

支持的平台:

本文档介绍了如何使用 Google Cloud Run functions 将 Slack 审核日志注入到 Google Security Operations。解析器可处理两种格式的 Slack 审核日志。它首先会对布尔值进行归一化处理,然后清除预定义的字段。然后,它将“message”字段解析为 JSON,并通过舍弃非 JSON 消息来处理这些消息。解析器会根据特定字段(date_createuser_id)是否存在应用不同的逻辑来将原始日志字段映射到 UDM,包括元数据、正文、网络、目标和相关信息,并构建安全结果。

准备工作

请确保满足以下前提条件:

  • Google SecOps 实例
  • Slack Enterprise Grid 租户和管理控制台的特权访问权限
  • GCP Cloud Run functions 和 Cloud Scheduler 的特权访问权限

收集 Slack 审核日志的前提条件(应用 ID、OAuth 令牌、组织 ID)

  1. 登录 Enterprise Grid 组织的 Slack 管理控制台
  2. 前往 https://api.slack.com/apps,然后依次点击创建新应用 > 从头开始
  3. 输入应用名称,然后选择您的开发 Slack 工作区
  4. 点击创建应用
  5. 在左侧边栏中,前往 OAuth 和权限
  6. 前往范围部分,然后添加以下用户令牌范围
    • auditlogs:read
  7. 依次点击安装到 Workspace > 允许
  8. 安装完成后,依次前往组织级应用 > 安装到组织
  9. 使用组织所有者/管理员账号授权该应用。
  10. 复制并安全地保存以 xoxp- 开头的用户 OAuth 令牌(这是您的 SLACK_ADMIN_TOKEN)。
  11. 复制您的组织 ID,该 ID 可在 Slack 管理控制台中的设置和权限 > 组织设置下找到。

设置目录

  1. 在本地机器上创建一个新目录,用于部署 Cloud Run 函数。
  2. Chronicle 提取脚本 GitHub 代码库下载以下文件:
    • slack 文件夹中下载:
      • .env.yml
      • main.py
      • requirements.txt
    • 从代码库的目录中,下载整个 common 目录及其所有文件:
      • common/__init__.py
      • common/auth.py
      • common/env_constants.py
      • common/ingest.py
      • common/status.py
      • common/utils.py
  3. 将所有下载的文件放入部署目录。

您的目录结构应如下所示:

  deployment_directory/
  ├─common/
  │ ├─__init__.py
  │ ├─auth.py
  │ ├─env_constants.py
  │ ├─ingest.py
  │ ├─status.py
  │ └─utils.py
  ├─.env.yml
  ├─main.py
  └─requirements.txt

在 Google Secret Manager 中创建 Secret

  1. Google Cloud 控制台中,依次前往安全性 > Secret Manager
  2. 点击创建 Secret
  3. Chronicle 服务账号提供以下配置详细信息:
    • 名称:输入 chronicle-service-account
    • 密钥值:粘贴您的 Google SecOps 提取身份验证 JSON 文件的内容。
  4. 点击创建密钥
  5. 复制密文资源名称,格式如下:

    projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest
    
  6. 再次点击创建 Secret 以创建第二个 Secret。

  7. Slack 令牌提供以下配置详细信息:

    • 名称:输入 slack-admin-token
    • 密钥值:粘贴您的 Slack 用户 OAuth 令牌(以 xoxp- 开头)。
  8. 点击创建密钥

  9. 复制密文资源名称,格式如下:

      projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest
    

设置所需的运行时环境变量

  1. 打开部署目录中的 .env.yml 文件。
  2. 使用您的值配置环境变量:

    CHRONICLE_CUSTOMER_ID: "<your-chronicle-customer-id>"
    CHRONICLE_REGION: us
    CHRONICLE_SERVICE_ACCOUNT: "projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest"
    CHRONICLE_NAMESPACE: ""
    POLL_INTERVAL: "5"
    SLACK_ADMIN_TOKEN: "projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest"
    
    • 替换以下内容:
      • <your-chronicle-customer-id>:您的 Google SecOps 客户 ID。
      • <PROJECT_ID>:您的 Google Cloud 项目 ID。
      • CHRONICLE_REGION:设置为您的 Google SecOps 区域。有效值:usasia-northeast1asia-south1asia-southeast1australia-southeast1europeeurope-west2europe-west3europe-west6europe-west9europe-west12me-central1me-central2me-west1northamerica-northeast2southamerica-east1
      • POLL_INTERVAL:函数执行的频率间隔(以分钟为单位)。此时长必须与 Cloud Scheduler 作业间隔相同。
  3. 保存 .env.yml 文件。

部署 Cloud Run 函数

  1. 在 Google Cloud 控制台中打开终端或 Cloud Shell
  2. 导航到您的部署目录:

    cd /path/to/deployment_directory
    
  3. 执行以下命令以部署 Cloud Run 函数:

    gcloud functions deploy slack-audit-to-chronicle \
      --entry-point main \
      --trigger-http \
      --runtime python39 \
      --env-vars-file .env.yml \
      --timeout 300s \
      --memory 512MB \
      --service-account <SERVICE_ACCOUNT_EMAIL>
    
    • <SERVICE_ACCOUNT_EMAIL> 替换为您希望 Cloud Run 函数使用的服务账号的电子邮件地址。
  4. 等待部署完成。

  5. 部署完成后,请记下输出中的函数网址

设置 Cloud Scheduler

  1. Google Cloud 控制台中,依次前往 Cloud Scheduler > 创建作业
  2. 提供以下配置详细信息:
    • 名称:输入 slack-audit-scheduler
    • 区域:选择与您部署 Cloud Run 函数时所选的区域相同的区域。
    • 频率:输入 */5 * * * *(每 5 分钟运行一次,与 POLL_INTERVAL 值一致)。
    • 时区:选择 UTC
    • 目标类型:选择 HTTP
    • 网址:输入部署输出中的 Cloud Run 函数网址。
    • HTTP 方法:选择 POST
    • 身份验证标头:选择添加 OIDC 令牌
    • 服务账号:选择用于 Cloud Run 函数的同一服务账号。
  3. 点击创建

UDM 映射表

日志字段 UDM 映射 逻辑
action metadata.product_event_type 直接从原始日志中的 action 字段映射。
actor.type principal.labels.value 直接从 actor.type 字段映射,并添加了键 actor.type
actor.user.email principal.user.email_addresses 直接从 actor.user.email 字段映射。
actor.user.id principal.user.product_object_id 直接从 actor.user.id 字段映射。
actor.user.id principal.user.userid 直接从 actor.user.id 字段映射。
actor.user.name principal.user.user_display_name 直接从 actor.user.name 字段映射。
actor.user.team principal.user.group_identifiers 直接从 actor.user.team 字段映射。
context.ip_address principal.ip 直接从 context.ip_address 字段映射。
context.location.domain about.resource.attribute.labels.value 直接从 context.location.domain 字段映射,并添加了键 context.location.domain
context.location.id about.resource.id 直接从 context.location.id 字段映射。
context.location.name about.resource.name 直接从 context.location.name 字段映射。
context.location.name about.resource.attribute.labels.value 直接从 context.location.name 字段映射,并添加了键 context.location.name
context.location.type about.resource.resource_subtype 直接从 context.location.type 字段映射。
context.session_id network.session_id 直接从 context.session_id 字段映射。
context.ua network.http.user_agent 直接从 context.ua 字段映射。
context.ua network.http.parsed_user_agent 使用 parseduseragent 过滤条件从 context.ua 字段派生的已解析的用户代理信息。
country principal.location.country_or_region 直接从 country 字段映射。
date_create metadata.event_timestamp.seconds date_create 字段中的纪元时间戳会转换为时间戳对象。
details.inviter.email target.user.email_addresses 直接从 details.inviter.email 字段映射。
details.inviter.id target.user.product_object_id 直接从 details.inviter.id 字段映射。
details.inviter.name target.user.user_display_name 直接从 details.inviter.name 字段映射。
details.inviter.team target.user.group_identifiers 直接从 details.inviter.team 字段映射。
details.reason security_result.description 直接从 details.reason 字段映射,如果是数组,则用英文逗号连接。
details.type about.resource.attribute.labels.value 直接从 details.type 字段映射,并添加了键 details.type
details.type security_result.summary 直接从 details.type 字段映射。
entity.app.id target.resource.id 直接从 entity.app.id 字段映射。
entity.app.name target.resource.name 直接从 entity.app.name 字段映射。
entity.channel.id target.resource.id 直接从 entity.channel.id 字段映射。
entity.channel.name target.resource.name 直接从 entity.channel.name 字段映射。
entity.channel.privacy target.resource.attribute.labels.value 直接从 entity.channel.privacy 字段映射,并添加了键 entity.channel.privacy
entity.file.filetype target.resource.attribute.labels.value 直接从 entity.file.filetype 字段映射,并添加了键 entity.file.filetype
entity.file.id target.resource.id 直接从 entity.file.id 字段映射。
entity.file.name target.resource.name 直接从 entity.file.name 字段映射。
entity.file.title target.resource.attribute.labels.value 直接从 entity.file.title 字段映射,并添加了键 entity.file.title
entity.huddle.date_end about.resource.attribute.labels.value 直接从 entity.huddle.date_end 字段映射,并添加了键 entity.huddle.date_end
entity.huddle.date_start about.resource.attribute.labels.value 直接从 entity.huddle.date_start 字段映射,并添加了键 entity.huddle.date_start
entity.huddle.id about.resource.attribute.labels.value 直接从 entity.huddle.id 字段映射,并添加了键 entity.huddle.id
entity.huddle.participants.0 about.resource.attribute.labels.value 直接从 entity.huddle.participants.0 字段映射,并添加了键 entity.huddle.participants.0
entity.huddle.participants.1 about.resource.attribute.labels.value 直接从 entity.huddle.participants.1 字段映射,并添加了键 entity.huddle.participants.1
entity.type target.resource.resource_subtype 直接从 entity.type 字段映射。
entity.user.email target.user.email_addresses 直接从 entity.user.email 字段映射。
entity.user.id target.user.product_object_id 直接从 entity.user.id 字段映射。
entity.user.name target.user.user_display_name 直接从 entity.user.name 字段映射。
entity.user.team target.user.group_identifiers 直接从 entity.user.team 字段映射。
entity.workflow.id target.resource.id 直接从 entity.workflow.id 字段映射。
entity.workflow.name target.resource.name 直接从 entity.workflow.name 字段映射。
id metadata.product_log_id 直接从 id 字段映射。
ip principal.ip 直接从 ip 字段映射。由基于 action 字段的逻辑确定。默认值为 USER_COMMUNICATION,但会根据 action 的值更改为其他值,例如 USER_CREATIONUSER_LOGINUSER_LOGOUTUSER_RESOURCE_ACCESSUSER_RESOURCE_UPDATE_PERMISSIONSUSER_CHANGE_PERMISSIONS。硬编码为“SLACK_AUDIT”。如果存在 date_create,则设置为“Enterprise Grid”;否则,如果存在 user_id,则设置为“Audit Logs”。硬编码为“Slack”。硬编码为“REMOTE”。如果 action 包含“user_login”或“user_logout”,则设置为“SSO”。否则,设置为“MACHINE”。在提供的示例中未映射。默认为“ALLOW”,但如果 action 为“user_login_failed”,则设置为“BLOCK”。如果 date_create 存在,则设置为“Slack”;否则,如果 user_id 存在,则设置为“SLACK”。
user_agent network.http.user_agent 直接从 user_agent 字段映射。
user_id principal.user.product_object_id 直接从 user_id 字段映射。
username principal.user.product_object_id 直接从 username 字段映射。

需要更多帮助?从社区成员和 Google SecOps 专业人士那里获得解答。