PitziLabs/firewalla-axiom-pipeline
GitHub: PitziLabs/firewalla-axiom-pipeline
将 Firewalla 的 Zeek 网络日志实时推送至 Axiom 云端,实现零成本的 30 天可搜索留存与按设备下钻分析。
Stars: 0 | Forks: 0
# firewalla-axiom-pipeline
将 DNS 和连接流日志从 Firewalla Gold SE 传输到 [Axiom](https://axiom.co),用于长期留存、搜索和仪表板展示 —— 无需任何经常性费用。
## 这个项目能做什么
你的 Firewalla 应用程序会显示每个设备访问的域名,但数据会在设备上快速轮替。此流水线捕获相同的数据(Zeek DNS 和连接日志)并将其传输到 Axiom 的云端,为你提供:
- 网络上每个 DNS 查询的 **30 天可搜索历史记录**
- **按设备下钻**仪表板(选择一个设备,查看其域名)
- 通过自动化 Redis 清单导出实现**设备名称解析**
- 使用 Firewalla 的 `post_main.d` 实现**固件更新弹性**
- Firewalla 上 **约 50 MB 的 RAM 开销**
总成本:**$0/月**(Axiom 免费层:500 GB/月,30 天留存)
## 架构

## 前置条件
- **Firewalla Gold SE**(Gold Pro 或 Purple SE 应该也可以 —— 未测试)
- 已启用 **SSH 访问**(Firewalla 应用程序 → 设置 → 高级 → SSH)
- 在 Firewalla 上启动 **Docker**(`sudo systemctl start docker && sudo systemctl enable docker`)
- **Axiom 账户**(在 [app.axiom.co](https://app.axiom.co) 免费)
## 快速入门
### 1. 创建 Axiom 数据集和 API token
1. 在 [app.axiom.co](https://app.axiom.co) 注册
2. 创建两个数据集:
- `firewalla`(或你喜欢的名称 —— 用于日志事件)
- `firewalla-devices`(用于设备查找表)
3. 进入 **Settings → API Tokens → New API Token**
4. 将其命名为 `firewalla-ingest`,授予 **Ingest** 权限,复制 token
### 2. 克隆此仓库并配置
```
git clone https://github.com/cpitzi/firewalla-axiom-pipeline.git
cd firewalla-axiom-pipeline
# 创建本地 env 文件(不提交到 git)
cp env.example .env
nano .env
# 填写 Axiom dataset 名称和 API token
```
### 3. 部署到 Firewalla
```
# 替换为你的 Firewalla IP 地址
export FW_IP=192.168.1.1
# 将配置文件复制到 Firewalla 持久化目录
scp fluent-bit/fluent-bit.conf pi@${FW_IP}:/home/pi/.firewalla/config/
scp fluent-bit/parsers.conf pi@${FW_IP}:/home/pi/.firewalla/config/
scp scripts/device_lookup_export.sh pi@${FW_IP}:/home/pi/.firewalla/config/
scp scripts/start_log_shipping.sh pi@${FW_IP}:/home/pi/.firewalla/config/post_main.d/
scp cron/user_crontab pi@${FW_IP}:/home/pi/.firewalla/config/
scp .env pi@${FW_IP}:/home/pi/.firewalla/config/log_shipping.env
```
### 4. 启动
```
ssh pi@${FW_IP}
# 使脚本可执行
chmod +x /home/pi/.firewalla/config/post_main.d/start_log_shipping.sh
chmod +x /home/pi/.firewalla/config/device_lookup_export.sh
# 启动 log pipeline
sudo /home/pi/.firewalla/config/post_main.d/start_log_shipping.sh
# 导出设备清单
sudo /home/pi/.firewalla/config/device_lookup_export.sh
# 安装 cron 以进行每小时设备导出
crontab /home/pi/.firewalla/config/user_crontab
```
### 5. 验证
```
# 检查 Fluent Bit 是否健康
sudo docker logs --tail 20 fluent-bit-axiom
# 应无错误 —— 检查 Axiom Stream 视图查看传入事件
```
## 文件布局
```
firewalla-axiom-pipeline/
├── README.md
├── LICENSE
├── env.example # Template for credentials
├── fluent-bit/
│ ├── fluent-bit.conf # Main Fluent Bit configuration
│ └── parsers.conf # Zeek log parser definitions
├── scripts/
│ ├── start_log_shipping.sh # Docker bootstrap (post_main.d)
│ └── device_lookup_export.sh # Redis → Axiom device inventory
├── cron/
│ └── user_crontab # Persistent cron jobs
├── dashboards/
│ └── axiom-queries.md # Saved APL queries for Axiom
└── deploy.sh # One-command deploy script
```
## Axiom 仪表板设置
有关完整的 APL 查询集,请参阅 [dashboards/axiom-queries.md](dashboards/axiom-queries.md),包括:
- 所有设备的热门域名
- 按设备划分的域名细分(含设备名称解析)
- 随时间变化的 DNS 活动
- 用于设备下钻的仪表板过滤栏配置
## Firewalla 内部机制
此流水线依赖于以下 Firewalla 数据源:
| Source | Path | Contents |
|--------|------|----------|
| Zeek DNS log | `/bspool/manager/dns.log` | 每个 DNS 查询:源 IP、域名、查询类型、响应 |
| Zeek conn log | `/bspool/manager/conn.log` | 每个连接:源、目标、端口、字节、持续时间 |
| ACL alarm log | `/alog/acl-alarm.log` | 被 Firewalla 规则阻止的连接 |
| Redis device inventory | `redis-cli hgetall host:mac:*` | IP、MAC、设备名称、DHCP 名称、接口 |
### 跨固件更新的持久性
Firewalla 使用 overlay 文件系统 —— 大多数更改在重启或固件更新后会被清除。唯一可靠的持久路径位于 `/home/pi/.firewalla/config/` 下。`post_main.d/` 中的脚本在每次启动和固件更新后自动运行。带有 `--restart always` 的 Docker 容器可以在正常重启中存活;`post_main.d` 脚本处理完全 overlay 重置的边缘情况。
### Zeek 日志格式
在最近的固件上,Zeek 日志写入为 **JSON**(而非 TSV)。`dns.log` 中的关键字段:
- `id.orig_h` — 源设备 IP
- `id.resp_h` — DNS 服务器 IP
- `query` — 查询的域名
- `qtype_name` — 查询类型(A、AAAA、CNAME 等)
- `answers` — DNS 响应
注意:字段名称包含点(例如 `id.orig_h`),这在 APL 中需要括号表示法:`parsed["id.orig_h"]`。
## 故障排除
### 数据停止流动
```
# 检查容器状态
sudo docker ps -a
# 检查错误
sudo docker logs --tail 50 fluent-bit-axiom
# 重启容器
sudo docker restart fluent-bit-axiom
```
常见原因:
- **HTTP 503 错误**:Axiom 宕机 —— 等 Axiom 恢复后重启容器
- **容器丢失**:固件更新清除了 Docker —— 运行 `start_log_shipping.sh`
- **无日志文件**:检查 `ls -la /bspool/manager/dns.log` 是否存在
- **/bspool 已满**:见下文 —— 这是繁忙网络上最常见的问题
### /bspool tmpfs 已满(第一大陷阱)
Zeek 写入 `/bspool`,这是一个 **30 MB tmpfs**(RAM 磁盘)。每 3 分钟,Zeek 将活动日志轮替为带时间戳的副本,如 `dns.2026-03-11-21-24-00.log`。在繁忙的网络(90+ 设备)上,这些轮替的文件可能在数小时内填满 tmpfs。当达到 100% 时,Zeek 完全停止写入,你的流水线就会陷入沉寂。
症状:
- `df -k /bspool/manager/` 显示 100% 使用率
- `dns.log` 有陈旧的时间戳(数天前)
- Fluent Bit 正在运行但不传输新数据
修复:
```
# 删除轮转日志
sudo rm /bspool/manager/*.2026-*.log
# 重启以彻底重启 Zeek(不要直接使用 zeekctl)
sudo reboot
```
预防:此仓库中的 `user_crontab` 包含每 5 分钟运行一次的清理作业,删除超过 5 分钟的轮替日志文件。Fluent Bit 实时从活动日志读取,从不需要轮替的副本。如果你在此修复添加之前进行了部署,请更新你的 crontab:
```
scp cron/user_crontab pi@:/home/pi/.firewalla/config/
ssh pi@ "crontab /home/pi/.firewalla/config/user_crontab"
```
**重要提示**:切勿在 Firewalla 上通过 `zeekctl restart` 重启 Zeek —— 由于 overlay 文件系统,它无法可靠工作。请始终改用 `sudo reboot`。
### 固件更新后容器无法启动
```
sudo /home/pi/.firewalla/config/post_main.d/start_log_shipping.sh
```
### Fluent Bit 正在运行但无数据流动(位置跟踪器陈旧)
Zeek 日志位于每次重启时都会重新创建的 tmpfs 上。Fluent Bit 在 `.db` 文件中跟踪其读取位置,以免重新读取旧数据。重启后,这些位置文件指向不再存在的文件中的字节偏移量,因此 Fluent Bit 静默地不读取任何内容。
`start_log_shipping.sh` 脚本现在会在每次启动时自动清除位置跟踪器,因此这应该可以自我修复。如果你还是遇到了这个问题:
```
sudo docker rm -f fluent-bit-axiom
sudo rm -rf /home/pi/.firewalla/config/fluent-bit-data/*
sudo /home/pi/.firewalla/config/post_main.d/start_log_shipping.sh
```
### 检查 RAM 使用情况
```
sudo docker stats fluent-bit-axiom --no-stream
```
### 验证 Zeek 日志正在写入
```
tail -5 /bspool/manager/dns.log
```
## 相关
- **[PitziLabs/setup-crostini-lab](https://github.com/PitziLabs/setup-crostini-lab)** — 用于相同家庭实验室环境的 Chromebook 引导脚本
- **[cpitzi/setup-xubuntu-lab](https://github.com/cpitzi/setup-xubuntu-lab)** — Xubuntu VM 工作站引导(构建仪表板的地方)
- **[PitziLabs/aws-lab-infra](https://github.com/PitziLabs/aws-lab-infra)** — Terraform AWS 实验室 —— 相同的基础设施即产品组合理念
## 许可证
MIT 许可证 —— 详见 [LICENSE](LICENSE)。
## 致谢
与 [Claude](https://claude.ai)(Anthropic)通过多会话结对编程迭代构建,包括通过 SSH 在 Firewalla 上进行实时调试、Fluent Bit 容器故障排除、Axiom APL 查询开发,以及发现 Zeek 将 MAC 小写化而 Redis 将其存储为大写。
## 特别感谢
- [mbierman's syslog forwarding gist](https://gist.github.com/mbierman/f3d184b65e0f4de6fa75a4a5d5145426) —— 最初的 Firewalla 日志导出参考
- [Firewalla open source repo](https://github.com/firewalla/firewalla) —— 用于理解内部数据模型
- 自 2019 年以来一直要求此功能的 Firewalla 社区论坛常客
标签:Axiom, Cutter, DNS 监控, DNS解析, Docker, Firewalla, Fluent Bit, OISF, Rootkit, Zeek, 仪表盘, 安全防御评估, 家庭实验室, 开源项目, 搜索引擎查询, 数据管道, 日志管理, 日志采集, 网络安全, 请求拦截, 软件工程, 防火墙, 隐私保护, 零成本