Janiru-Sudasinghe/Airgapped-otel-SecOps-Pipeline

GitHub: Janiru-Sudasinghe/Airgapped-otel-SecOps-Pipeline

该项目演示了一套在完全物理隔离环境下,通过自托管 Bindplane 和 OpenTelemetry Collector 网关将 Windows 事件日志安全转发至 Google SecOps 进行 SIEM 分析的企业级遥测架构。

Stars: 0 | Forks: 0

# 通过自托管 Bindplane 实现离线环境的 Windows 事件日志转发至 Google SecOps

Platform Bindplane Collector SIEM Environment License

## 📌 目录 1. [概述](#-overview) 2. [架构](#-architecture) 3. [核心功能](#-key-features) 4. [技术栈](#-technology-stack) 5. [前置条件](#-prerequisites) 6. . [网络与端口规划](#-network--port-plan) 7. . [实施指南](#-implementation-guide) - [阶段 1 — 准备二进制文件(联网主机)](#phase-1--stage-binaries-internet-connected-hosts) - [阶段 2 — CentOS Bindplane 服务器(离线)](#phase-2--centos-bindplane-server-offline) - [阶段 3 — Google SecOps 接入配置](#phase-3--google-secops-onboarding) - [阶段 4 — 网关 Collector(离线 CentOS)](#phase-4--gateway-collector-offline-centos) - [阶段 5 — Windows 10 Agent(离线)](#phase-5--windows-10-agent-offline) - [阶段 6 — Pipeline(Bindplane GUI)](#phase-6--pipelines-bindplane-gui) - [阶段 7 — 验证与测试](#phase-7--verification--testing) 8. [配置参考](#-configuration-reference) 9. [故障排除](#-troubleshooting) 10. [安全与密钥处理](#-security--secret-handling) 11. [截图](#-screenshots) 12. [仓库结构](#-repository-structure) 13. [经验总结](#-lessons-learned) 14. [参考](#-references) 15. [作者与许可协议](#-author--license) ## 🔎 概述 本项目展示了一个**生产级、物理隔离(离线环境)的日志采集流水线**。一台**没有互联网连接**的 Windows 10 主机生成 Windows 事件日志(安全、应用程序、系统)。由于 Google SecOps 是一项云服务,离线主机无法直接访问它——因此该设计使用了 Bindplane 的**网关 Collector 模式**: - **离线 Windows Agent** 通过 **LAN**(OTLP)将原始 Windows 事件发送到网关。 - **网关 Collector**(位于 CentOS 服务器上,这是唯一一台具有受控出站 HTTPS 访问权限的主机)持有 Google 凭据,并将所有内容转发到 **Google SecOps**。 这使得所有凭据都集中在一个经过加固的出口节点上,并使日志源保持完全隔离——这是在实际的隔离环境/OT/DMZ 环境中使用的模型。 | | | |---|---| | **目标** | 将来自物理隔离主机的 Windows 事件日志转发到 Google SecOps | | **日志源** | Windows 10 Pro(离线)— 安全、应用程序、系统通道 | | **流水线** | 自托管 Bindplane(Google Edition)+ OpenTelemetry Collector | | **目标端** | Google SecOps (Chronicle),区域 `asia-southeast1`,日志类型 `WINEVTLOG` | | **出口模型** | 网关 Collector 模式(仅由 CentOS 服务器访问 Google) | | **结果** | ✅ Windows 事件已成功采集并可在 Google SecOps 中搜索 | ## 🏗 架构 这里映射了遥测数据的完整生命周期,从物理隔离的 Windows 机器上生成安全事件开始,直到其最终到达 Google SecOps 云端。


Network Topology Diagram

## ✨ 核心功能 - **真正的日志源物理隔离** — Windows 主机没有任何互联网路由;通过失败的出站连接测试进行了验证。 - **网关出口模式** — 凭据和出站 HTTPS 完全位于一台主机上(CentOS 网关)。 - **100% 离线的软件供应链** — 每一个二进制文件都在联网主机上暂存、校验、通过介质传输,并在本地安装。Bindplane 以 `offline: true` 模式运行,因此 Collector 永远不会向外请求 GitHub/`bdot.bindplane.com`。 - **GUI 管理的流水线** — source、processor 和 destination 都在 Bindplane 控制台中构建,并通过 OpAMP 推送到 Collector(无需手动编辑 Collector YAML)。 - **原始 WINEVTLOG 采集** — Windows 事件以原始格式发送,以便 Google SecOps 的 `WINEVTLOG` parser 能够正确对其进行标准化。 - **可复现** — 所有版本均锁定在 **v1.100.0**。 ## 🧰 技术栈 | 层级 | 组件 | 版本 | |---|---|---| | Hypervisor | VMware Workstation | | | 服务器 OS | CentOS Stream 9 | | | Agent OS | Windows 10 Pro | | | Pipeline 管理 | Bindplane (Google Edition) | v1.100.0 | | Collector | observIQ Distro for OpenTelemetry Collector (BDOT) | v1.100.0 | | 数据库 | PostgreSQL (PGDG) | 15 | | SIEM | Google SecOps (Chronicle) | `asia-southeast1` | | 传输协议 | 通过 LAN 的 OTLP (gRPC);到 SecOps 的 gRPC/HTTPS | | ## ✅ 前置条件 - **2 台离线 VM:** CentOS Stream 9(Bindplane 服务器 + 网关)和 Windows 10 Pro(Agent),位于同一个隔离的 LAN 网段。 - **2 台联网的暂存主机:** 一台 CentOS,一台 Windows — 仅用于下载二进制文件并通过离线介质传输。 - 一个 **Bindplane (Google Edition) 许可证密钥**。 - 一个 **Google SecOps** 租户(本项目使用区域 `asia-southeast1`)。 - 用于物理隔离传输的可移动介质(USB/ISO)。 ## 🌐 网络与端口规划 | 主机 | 示例 IP | 端口(入站) | 用途 | |---|---|---|---| | Bindplane 服务器 / 网关 (CentOS) | `192.168.98.130` | `3001/tcp` | Bindplane UI/API + OpAMP (WebSocket) | | | | `4317/tcp` | OTLP gRPC(网关接收) | | | | `4318/tcp` | OTLP HTTP(网关接收) | | | | `5432/tcp` | PostgreSQL(本地/局域网) | | Windows Agent | `192.168.98.140` | — | 仅出站到服务器 `:3001` 和 `:4317` | | Google SecOps | 云端 | `443`(从网关出站) | 采集 API | ## 🚀 实施指南 ### 阶段 1 - 准备二进制文件(联网主机) 🟢 **暂存 CentOS** - 下载所有 Linux 产物并解决 PostgreSQL 依赖: ``` # 创建嵌套文件夹并进入根目录 airgap 目录 mkdir -p ~/airgap/{bindplane,postgres,collector,artifacts} && cd ~/airgap ``` ``` # 直接将 BindPlane Enterprise RPM 下载到 bindplane 文件夹中 wget "https://downloads.bindplane.com/bindplane/1.100.0/bindplane-ee_linux_amd64.rpm" \ -O ~/airgap/bindplane/bindplane-ee_v1.100.0_linux_amd64.rpm ``` ``` # Download the BindPlane CLI zip into the bindplane folder wget "https://storage.googleapis.com/bindplane-op-releases/bindplane/1.100.0/bindplane-ee-linux-amd64.zip" \ -O ~/airgap/bindplane/bindplane-cli-v1.100.0.zip ``` ``` # 将 BindPlane CLI zip 下载到 bindplane 文件夹中 wget "https://github.com/observIQ/bindplane-otel-collector/releases/download/v1.100.0/observiq-otel-collector_v1.100.0_linux_amd64.rpm" \ -P ~/airgap/collector/ # Download the OpenTelemetry collector RPM into the collector folder ``` ``` # 将 OpenTelemetry offline artifacts 下载到 collector 文件夹中 wget "https://github.com/observIQ/bindplane-otel-collector/releases/download/v1.100.0/observiq-otel-collector-v1.100.0-artifacts.tar.gz" \ -P ~/airgap/collector/ ``` ``` # 进入 postgres 目录以隔离数据库文件 cd postgres/ ``` ``` # 在本地安装 Postgres repo 以便 dnf 能够定位 packages sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm ``` ``` # 禁用默认的 OS Postgres module 以防止版本冲突 sudo dnf module disable -y postgresql ``` ``` # 安装必要的工具(dnf-plugins-core 提供 'dnf download' 命令) sudo dnf install -y dnf-plugins-core wget ``` ``` # 保存 repo setup 文件本身,用于目标离线机器 wget -P ~/airgap/postgres/ https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm ``` ``` # 获取 Postgres 15 并解析所有依赖项以供离线使用 dnf download --resolve --alldeps --destdir=postgres postgresql15-server postgresql15 postgresql15-libs postgresql15-contrib ``` ``` # 返回根目录,对所有下载的文件进行 hash,并输出到文本文件中以供完整性验证 cd ~/airgap && find . -type f \( -name '*.rpm' -o -name '*.tar.gz' -o -name '*.zip' \) -exec sha256sum {} \; > SHA256SUMS.txt ``` 🪟 **暂存 Windows** - 下载 Agent MSI:(PowerShell) ``` # 强制 PowerShell 使用 TLS 1.2 进行安全 Web 连接,防止与现代 Web 服务器发生连接错误 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ``` ``` # 下载 observIQ OpenTelemetry Collector 安装程序 (v1.100.0) 并将其在本地保存为 MSI 文件 Invoke-WebRequest -Uri "https://bdot.bindplane.com/v1.100.0/observiq-otel-collector.msi" -OutFile "observiq-otel-collector-v1.100.0.msi" ``` ``` # 计算已下载 MSI 的 SHA256 加密 hash,并将该值保存到文本文件中以供完整性验证 (Get-FileHash .\observiq-otel-collector-v1.100.0.msi -Algorithm SHA256).Hash | Out-File -FilePath .\observiq-v1.100.0-SHA256.txt ``` **传输** `~/airgap/` 到 CentOS 服务器,并通过离线介质将 MSI 传输到 Windows Agent 的 `C:\offline\` 目录,然后在两个目标上重新验证校验和。 ### 阶段 2 - CentOS Bindplane 服务器(离线) 🔵 **离线 CentOS 服务器** - 基础系统、防火墙、时间: ``` # 将系统时区设置为斯里兰卡时间 (Asia/Colombo) sudo timedatectl set-timezone Asia/Colombo ``` ``` # 显示当前系统日期和时间以验证时区更改是否成功 date ``` ``` # 将机器的 hostname 设置为 'bindplane.local' sudo hostnamectl set-hostname bindplane.local ``` ``` # 在防火墙中永久开放 TCP 端口 3001(BindPlane OP 用户界面和 API 的默认端口) sudo firewall-cmd --permanent --add-port=3001/tcp ``` ``` # 永久开放 TCP 端口 4317(OpenTelemetry collector 通过 gRPC 接收 OTLP 的默认端口) sudo firewall-cmd --permanent --add-port=4317/tcp ``` ``` # 永久开放 TCP 端口 4318(OpenTelemetry collector 通过 HTTP 接收 OTLP 的默认端口) sudo firewall-cmd --permanent --add-port=4318/tcp ``` ``` # 永久开放 TCP 端口 5432(PostgreSQL 数据库连接的默认端口) sudo firewall-cmd --permanent --add-port=5432/tcp ``` ``` # 重新加载防火墙以应用新添加的端口规则,然后立即列出所有开放端口以进行验证 sudo firewall-cmd --reload && sudo firewall-cmd --list-ports ``` ``` # 启用 Chrony NTP (Network Time Protocol) 服务以在开机时自动启动,并立即启动它 sudo systemctl enable --now chronyd ``` ``` # 启用 Chrony NTP 服务以在开机时启动,立即启动它,并检查其同步状态 sudo systemctl enable --now chronyd && chronyc tracking ``` **安装 PostgreSQL 15(离线):** ``` # 导航至包含已下载 PostgreSQL RPM 文件的目录 cd postgres/ ``` ``` # 从已下载的 RPM 文件本地安装所有 PostgreSQL packages,无需互联网连接 sudo dnf localinstall -y *.rpm ``` ``` # 初始化 PostgreSQL 数据库集群,这将创建运行数据库所需的基础文件和系统表 sudo /usr/pgsql-15/bin/postgresql-15-setup initdb ``` ``` # 启用 PostgreSQL 15 服务以在系统开机时自动启动,并立即启动它 sudo systemctl enable --now postgresql-15 ``` ``` # 检查 PostgreSQL 服务的当前状态,以确认其正在正常运行且没有错误 systemctl status postgresql-15 ``` **创建数据库和用户**(使用强密码 — **不要**重复使用用户名): ``` # 以默认的 'postgres' 超级用户身份运行一段 SQL 命令,以创建 BindPlane 数据库和用户 sudo -u postgres psql <<'SQL' CREATE USER bindplane_user WITH PASSWORD 'bindplane_user'; CREATE DATABASE bindplane OWNER bindplane_user; GRANT ALL PRIVILEGES ON DATABASE bindplane TO bindplane_user; SQL ``` ``` # 直接连接到新创建的 'bindplane' 数据库,以授予用户对 public schema 的权限 sudo -u postgres psql -d bindplane <<'SQL' GRANT ALL ON SCHEMA public TO bindplane_user; ALTER DATABASE bindplane OWNER TO bindplane_user; SQL ``` **在** `/var/lib/pgsql/15/data/pg_hba.conf` 中**启用密码身份验证** — 将 `127.0.0.1/32` 和 `::1/128` 行设置为 `scram-sha-256`(如果远程访问 PostgreSQL,请添加 LAN 行): ``` host all all 127.0.0.1/32 scram-sha-256 host all all ::1/128 scram-sha-256 host bindplane bindplane_user 192.168.98.0/24 scram-sha-256 ``` 如果 PostgreSQL 必须监听 localhost 以外的地址,请在 `/var/lib/pgsql/15/data/postgresql.conf` 中设置 `listen_addresses = '*'`。然后: ``` # 重启 PostgreSQL 15 服务以应用任何最近的配置更改,并确保数据库平稳运行 sudo systemctl restart postgresql-15 ``` ``` # 以 'bindplane_user' 身份通过本地 TCP/IP (127.0.0.1) 连接到 'bindplane' 数据库来验证数据库连接,并执行一个简单的查询以检查版本 psql -h 127.0.0.1 -U bindplane_user -d bindplane -c "SELECT version();" ``` **安装并初始化 Bindplane:** ``` # 将下载的 BindPlane Enterprise RPM 文件从您的离线 bundle 复制到临时目录中进行安装 cp ~/airgap/bindplane/bindplane-ee_* /tmp/ ``` ``` # 使用复制的 RPM 文件在本地安装 BindPlane 应用程序 package,无需互联网连接 sudo dnf localinstall -y /tmp/bindplane-ee_*.rpm ``` ``` # 初始化 BindPlane 服务器配置,设置 data directory 的环境变量并指定新生成的配置文件的路径 sudo BINDPLANE_CONFIG_HOME=/var/lib/bindplane /usr/local/bin/bindplane init server --config /etc/bindplane/config.yaml ``` 回答 `init` 提示: | 提示 | 值 | |---|---| | License Key | `` | | Server Host | `0.0.0.0` | | Server Port | `3001` | | Remote URL | `http://192.168.98.130:3001` | | Authentication Method | `single-user` | | Username / Password | `admin` / `` | | Database Host / Port | `192.168.98.130`(或 `localhost`)/ `5432` | | Database Name / User / Password | `bindplane` / `bindplane_user` / `` | | SSL Mode | `disable` | **在** `/etc/bindplane/config.yaml` 中**启用离线模式**(添加 `offline: true`;确认 OpAMP `secretKey`): ``` apiVersion: bindplane.observiq.com/v1beta1 offline: true env: production auth: type: system username: admin password: secretKey: # UUID used to enroll collectors ``` ``` # 启用 BindPlane 服务以在系统开机时自动启动,并立即启动它 sudo systemctl enable --now bindplane ``` ``` # 检查 BindPlane 服务的当前运行状态,以验证其已成功启动且没有错误 sudo systemctl status bindplane ``` ``` # 检索并显示安装期间生成的默认 BindPlane 账户凭据(用户名和密码),以便您可以登录 Web 界面 bindplane get account ``` **托管离线 Collector 产物**,以便物理隔离的 Collector 可以在没有互联网的情况下安装: ``` # 在您的主文件夹中创建一个隐藏的 '.bindplane' 目录,用于存储 CLI 配置和缓存 mkdir -p ~/.bindplane ``` ``` # 将离线 zip 文件中的 BindPlane CLI 可执行文件直接解压到系统级目录中,以便您可以从任何地方运行 'bindplane' 命令 sudo unzip ~/airgap/bindplane/bindplane-cli*.zip -d /usr/local/bin/ ``` ``` # 创建一个名为 'airgap' 的新 CLI profile,告知 CLI 如何连接到您的 BindPlane 服务器(请务必将 替换为上一步中的密码) bindplane profile set airgap --remote-url http://192.168.98.130:3001 --username admin --password ``` ``` # 将新创建的 'airgap' profile 设置为您未来所有 CLI 命令的活跃 profile bindplane profile use airgap ``` ``` # 通过检查版本来验证 CLI 是否已正确安装并能与 BindPlane 服务器成功通信 bindplane version ``` ``` # 将离线 OpenTelemetry collector artifacts 上传到 BindPlane 服务器,允许您在没有互联网访问的情况下在网络上部署和升级 agents bindplane upload agent-upgrade ~/airgap/collector/observiq-otel-collector-v1.100.0-artifacts.tar.gz --version v1.100.0 ``` 🌐 在浏览器中访问 `http://192.168.98.130:3001` 并登录。 ### 阶段 3 - Google SecOps 接入配置 ☁️ **Google SecOps 控制台:** 1. **SIEM Settings → Collection Agents** → 下载 **Ingestion Authentication File**(service-account JSON)。 2. **SIEM Settings → Profile → Organization Details** → 复制 **Customer ID** 并记录 **GCP Project Number**。 3. 记录网关使用的采集详情: | 字段 | 值 | |---|---| | Name | `google-secops-dest` | | Region | `asia-southeast1` | | Endpoint (gRPC) | `asia-southeast1-malachiteingestion-pa.googleapis.com` | | Customer ID | `` | | GCP Project Number | `` | | Log type / parser | `WINEVTLOG` | | Auth method | `json`(将凭据粘贴到 destination 中) | ### 阶段 4 - 网关 Collector(离线 CentOS) 🔵 **离线 CentOS 服务器:** ``` # 使用离线 bundle 中的 RPM package 安装或升级 observIQ OpenTelemetry Collector sudo rpm -U ~/airgap/collector/observiq-otel-collector_v1.100.0_linux_amd64.rpm ``` ``` # 在 vim 文本编辑器中打开 collector 的 manager 配置文件,以便您可以将其指向您的 BindPlane OP 服务器 sudo vim /opt/observiq-otel-collector/manager.yaml ``` ``` endpoint: ws://192.168.98.130:3001/v1/opamp secret_key: ``` ``` # 启用 OpenTelemetry collector 服务以在系统开机时自动启动,并立即启动它 sudo systemctl enable --now observiq-otel-collector ``` ``` # 检查 collector 服务的当前运行状态,以确保其平稳运行且通信正常 sudo systemctl status observiq-otel-collector ``` 🌐 **Bindplane 控制台** - 确认网关显示为 **Connected**,然后构建网关 pipeline: - **Create Configuration:** 为其命名为 `Gateway-Pipeline`,Select Platform = **Linux**,点击 Next。 - **Add Source → Select Bindplane Gateway**(默认值 - 监听 `4317`/`4318`)点击 Save。 - **Add Processors → 搜索并添加 Batch**,保存;然后再次搜索并添加 **Google SecOps Standardization**,设置 `logType = WINEVTLOG`,保存。 - **在右侧 Add Destination → 搜索并添加 Google SecOps:** Protocol `gRPC`;Endpoint `asia-southeast1-malachiteingestion-pa.googleapis.com`;Auth `json`(粘贴凭据 JSON);Customer ID ``;Fallback Log Type `WINEVTLOG`;启用 **Retry on Failure** 点击 Save。 - **点击 Apply → 选择网关 Collector → Start Rollout。** ### 阶段 5 - Windows 10 Agent(离线) ⬛ **离线 Windows Agent**(使用管理员权限的 PowerShell / CMD): ``` # 将 Windows 机器重命名为 'WIN-AGENT01' 并立即重启系统以应用新名称 Rename-Computer -NewName WIN-AGENT01 -Restart ``` ``` # 测试到 BindPlane 服务器的 UI/API 端口的本地网络连通性,以确保此 agent 能够与管理控制台通信(这应该报告成功) Test-NetConnection 192.168.98.130 -Port 3001 ``` ``` # 测试到 BindPlane 服务器的 OpenTelemetry gRPC 端口的本地网络连通性,agent 将把其 metric 和 log 数据发送到该端口(这应该报告成功) Test-NetConnection 192.168.98.130 -Port 4317 ``` ``` # 通过确认机器无法访问外部公共 IP 地址来验证 air-gap 隔离是否正在有效工作(这必须失败) Test-NetConnection 8.8.8.8 -Port 443 ``` 假设您已经将 observiq-otel-collector-v1.100.0.msi 文件传输到了 C:\offline\,请通过本地暂存的 MSI 静默安装 Agent,并将其指向服务器的 OpAMP endpoint: ``` :: Install the observIQ OpenTelemetry Collector silently from the offline MSI file, configuring it to connect and authenticate with your BindPlane OP management server msiexec /i "C:\offline\observiq-otel-collector-v1.100.0.msi" /quiet ^ ENABLEMANAGEMENT=1 ^ OPAMPENDPOINT=ws://192.168.98.130:3001/v1/opamp ^ OPAMPSECRETKEY= ``` ``` :: Query the Windows Service Control Manager to check the status of the newly installed collector service (you want to see STATE: 4 RUNNING) sc query observiq-otel-collector :: expect STATE: 4 RUNNING ``` 🌐 在 Bindplane 控制台 → **Agents** 中,确认 `WIN-AGENT01` 状态为 **Connected**。 ### 阶段 6 - Pipelines (Bindplane GUI) 🌐 **Bindplane 控制台** - 构建 Windows Agent pipeline: - **Create Configuration:** 为其命名为 `Windows-Server-Logs`,Select Platform = **Windows**。 - **Add →Select Windows Events:** 在 Channels 部分启用 **System**、**Application**、**Security**。在 **Advanced** 下,**开启 Raw Logs** - *必须项;否则 SecOps 会拒绝 WINEVTLOG。*(可选:设置 **Start At → beginning** 以进行回填。)点击 Save。 - **Add Destination → Select Bindplane Gateway (OTLP):** Endpoint/Hostname `192.168.98.130`,Port `4317`,Protocol `gRPC`,TLS **insecure/disabled**(内部 LAN)。 - **Add Processor →Select Batch。** 点击 Save。 - **Apply → 选择 `WIN-AGENT01` → Start Rollout。** ### 阶段 7 - 验证与测试 ⬛ **离线 Windows Agent** - 生成测试事件: ``` :: Generate a synthetic "Error" event in the Windows SYSTEM log to verify the OpenTelemetry collector is successfully reading and forwarding System events to BindPlane eventcreate /T ERROR /ID 999 /L SYSTEM /SO BindplaneTest /D "Air-gap WINEVTLOG test event" ``` ``` :: Generate a second synthetic "Error" event, this time in the APPLICATION log, to ensure application-level events are also being captured and routed correctly eventcreate /T ERROR /ID 999 /L APPLICATION /SO BindplaneTest /D "Air-gap WINEVTLOG test event" ``` 🌐 **Bindplane 控制台** - 确认实时吞吐量:`Windows Events → Bindplane Gateway`(Agent pipeline)以及 `Bindplane Gateway → Google SecOps`(网关 pipeline)。 🔵 **离线 CentOS 服务器** - 检查网关导出情况: ``` # 实时持续监控 OpenTelemetry collector 的实时 log 文件,以验证遥测数据是否已成功通过身份验证并导出,且没有出现 401 (Unauthorized) 或 403 (Forbidden) 错误 sudo tail -f /opt/observiq-otel-collector/log/collector.log # 成功 = chronicle 导出且无 401/403 ``` ☁️ **Google SecOps 控制台:** - 针对关键词 `BindplaneTest` 进行 **Raw Log Search**。 - **UDM Search:** 在最近的时间窗口内搜索 `metadata.log_type = "WINEVTLOG"`。 - **SIEM Settings → Health Hub:** 确认 WINEVTLOG 的 **Last Ingested / Last Normalized** 时间是最近的。✅ ## ⚙️ 配置参考 Collector 配置是**由 Bindplane GUI 生成并通过 OpAMP 推送的** — 此处仅作为参考包含;请勿在主机上手动编辑它们。
configs/gateway/gateway-config.yaml.example (CentOS 网关) ``` # 由 Bindplane 管理(GUI 生成的参考 —— 请勿手动编辑) receivers: otlp/source0: protocols: grpc: { endpoint: 0.0.0.0:4317 } http: { endpoint: 0.0.0.0:4318 } processors: batch/winevtlog: {} google_secops_standardization/secops: logType: WINEVTLOG exporters: chronicle/SecOps: compression: gzip creds: customer_id: endpoint: asia-southeast1-malachiteingestion-pa.googleapis.com log_type: WINEVTLOG raw_log_field: body retry_on_failure: { enabled: true } service: pipelines: logs/gateway-to-secops: receivers: [otlp/source0] processors: [batch/winevtlog, google_secops_standardization/secops] exporters: [chronicle/SecOps] ```
configs/windows-agent/windows-agent-config.yaml.example (Windows Agent) ``` # 由 Bindplane 管理(GUI 生成的参考 —— 请勿手动编辑) receivers: windowseventlog/source0__security: { channel: security, raw: true, start_at: end } windowseventlog/source0__application: { channel: application, raw: true, start_at: end } windowseventlog/source0__system: { channel: system, raw: true, start_at: end } processors: batch/winevtlog: {} exporters: otlp/bindplane_gateway: endpoint: 192.168.98.130:4317 compression: gzip tls: { insecure: true } retry_on_failure: { enabled: true } sending_queue: { enabled: true } service: pipelines: logs/winevtlog: receivers: [windowseventlog/source0__security, windowseventlog/source0__application, windowseventlog/source0__system] processors: [batch/winevtlog] exporters: [otlp/bindplane_gateway] ```
## 🛠 故障排除 | 症状 | 可能原因 | 修复方法 | |---|---|---| | 网关 `403 / PermissionDenied` | 区域 endpoint、Customer ID 或凭据错误 | 验证 `asia-southeast1` endpoint 和 Customer ID;尝试使用多区域 endpoint | | 网关 `401` | 凭据无效/已过期 | 重新下载 Ingestion Authentication File 并重新粘贴 | | Agent 显示 **Disconnected** | 到 `:3001` 的 LAN 可达性问题,协议错误 | 重新测试 `Test-NetConnection …:3001`;确保使用 `ws://`(而不是 `wss://`);检查 firewalld 3001 | | 日志在 Bindplane 中流动,但 **SecOps 中什么都没有** | **Raw Logs 未启用**(最常见)、时钟偏差、时间范围太窄 | 确认推出的配置中包含 `raw: true`;同步时钟;扩大搜索窗口 | | `:4317` 上出现 `connection refused` | 网关未监听 / 防火墙问题 | 确认网关状态为 Connected,4317/tcp 已开放,OTLP source 已推出 | ## 🔐 安全与密钥处理 每个提交的文件都使用了占位符(``、``、``、``、``、``)。 在任何推送之前,请运行密钥扫描程序(例如 `gitleaks detect`)并确认没有遗留真实密钥。 ## 📸 截图 将证据放置在 [`screenshots/`](screenshots/) 中并在此处引用。建议的截图集合: **在 Windows Agent 上 (⬛):** 1. [`Test-NetConnection`](screenshots/Test-NetConnection.png) 在 `:3001`/`:4317` 上成功,并在互联网上**失败**(证明物理隔离)。 2. [`sc query observiq-otel-collector`](screenshots/sc_query_observiq-otel-collector.png) 显示为 **RUNNING**。 3. [`collector_log`](screenshots/collector_log.png) 尾部显示 OTLP 导出到 `192.168.98.130:4317`。 4. [`Event_Viewer`](screenshots/Event_Viewer.png) 显示测试事件。 **在 Bindplane 控制台中 (🌐):** 1. [`Agents_page`](screenshots/Agents_page.png) - 两个 Collector 均显示 **Connected**。 2. [`Windows_pipeline`](screenshots/Windows_pipeline.png) - `Windows Events → Bindplane Gateway`,带有实时吞吐量。 3. [`Gateway_pipeline`](screenshots/Gateway_pipeline.png) - `Bindplane Gateway → Google SecOps`,带有吞吐量。 **在 Google SecOps 中 (☁️):** 1. [`UDM_Search`](screenshots/UDM_Search.png) 查询 `metadata.log_type = "WINEVTLOG"` 返回了测试事件 ## 📂 仓库结构 ``` Airgapped-otel-SecOps-Pipeline/ ├── README.md # This file ├── docs/ │ └── diagram.png └── screenshots/ └── ... # Evidence (see Screenshots section) ``` ## 📚 经验总结 - **网关正是为此而生的。** 物理隔离的源无法直接访问云 SIEM — 通过单一出口网关进行路由是最简洁、最小化凭据暴露的解决方案。 - **Raw Logs 对** `WINEVTLOG` **来说是不可妥协的**。这是导致“SecOps 中没有日志”的最常见原因。 - **离线模式 + 托管产物**(`offline: true` + `bindplane upload agent-upgrade`)使得完全断网的 Collector 集群能够进行安装和升级。 - **固定版本并校验所有内容。** 物理隔离环境中的可复现性依赖于受控且经过验证的二进制文件。 - **时钟同步至关重要** — 偏差的时钟会使采集到的日志落在您的搜索窗口之外,从而看起来“丢失了”。 ## 🔗 参考 - Google SecOps — *Use Bindplane with Google SecOps* · *Collect Microsoft Windows Event logs* · *Ingestion API* - Bindplane 文档 — *Offline Collector Package Installation* · *Bindplane Gateway* · *Google SecOps (Chronicle) destination* · *Linux/Windows collector installation* - observIQ — `bindplane-otel-collector` GitHub 发布版 (v1.100.0) - PostgreSQL — PGDG RHEL 9 仓库 ## 👤 作者与许可协议 **Janiru Sudasinghe** - GitHub: [@Janiru-Sudasinghe](https://github.com/Janiru-Sudasinghe) - LinkedIn: [Janiru Sudasinghe](https://www.linkedin.com/in/janiru-sudasinghe/?skipRedirect=true) 基于 **MIT License** 发布
标签:Bindplane, GET参数, Google SecOps, OpenTelemetry, 事件转发, 日志收集, 运维监控, 隔离环境