bearkiter-alt/opnsense-hass
GitHub: bearkiter-alt/opnsense-hass
一款将 OPNsense 防火墙功能接入 Home Assistant 的自定义集成,提供按设备断网、网关监控、流量统计及丰富的自动化服务。
Stars: 0 | Forks: 0
# OPNsense (HASS)
一个针对 [OPNsense](https://opnsense.org/) 的 Home Assistant 自定义集成,它将网关、系统和防火墙别名(firewall-alias)状态公开为实体,并提供用于按设备断网的服务——专为驱动 ADHDTasker 时间奖励自动化而构建,但也适用于从 HA 进行任何 OPNsense 控制。
## 功能
- 读取 **网关** 状态(连通性、延迟、丢包)、**系统** 信息(版本、可用更新)以及 **防火墙别名** 状态。
- **按设备断网**:通过管理主机别名的内容来实现,同时提供 **运行时** 路径(立即生效,重启后丢失)和 **持久化** 路径(通过别名配置 + 重新配置在重启后保留)。
- **开关**:用于切换被跟踪主机别名的 *启用* 状态,以及启用/禁用由 API 创建的防火墙规则。
- **传感器**:用于网关延迟/丢包、OPNsense 版本、可用更新计数以及被跟踪别名项目计数。
- **流量统计** —— 每个接口的实时进出 **比特率** 以及累积 **字节计数器**(用于 HA 统计/能源图表)。
- **活跃主机(Top talkers)** —— 最繁忙的本地设备,每个都解析为 **友好名称 + MAC** 地址(来自 DHCP 租约,带有 ARP 回退机制)。
- **别名设备列表** —— 每个被跟踪的别名都将其成员公开为一个 `devices` 属性,其中为每个设备包含 `{ip, mac, name, manufacturer, online}` 信息。
- 一套 **完整的服务集合**(`alias_add_host`、`alias_remove_host`、`alias_flush`、`alias_set_hosts`、`alias_block_device`、`alias_unblock_device`、`toggle_rule`、`apply`),外加一个返回解析后响应的原始 **`exec_api`** 直通服务。
- **诊断** 下载,其中敏感信息(API key/secret/URL)会被脱敏隐藏。
- 旨在支持 **ADHDTasker → HA → OPNsense** 时间奖励自动化:孩子的设备默认被封锁,在完成任务时可获得 N 分钟的上网时间。
## 要求
- **Home Assistant 2026.6+**。
- 一对 **OPNsense API key/secret**。在 *System > Access > Users > (编辑用户) > API keys* 下创建。**API 用户需要拥有** 所使用端点的权限 —— 至少需要 *System: Firmware*(用于设置验证)以及 *Firewall: Aliases*(用于封锁/解封服务)。流量/活跃主机/设备名称功能还会额外读取 *Diagnostics*(流量 + ARP)和 *Services: DHCPv4: Leases*;如果用户缺少这些权限,只有这些额外的传感器会保持空白 —— 核心轮询依然有效。
- 一个没有任何权限的全新用户可以通过身份验证,但会收到 HTTP 403 错误,提示“权限不足”——使用管理员用户是最简单的。
- **URL** 应为主机根地址,例如 `http://192.168.1.1` —— 包含 `http://` 并且 **不要** 加 `/api` 后缀。除非你的 OPNsense 通过 HTTPS 提供 API *并且* 该端口可从 Home Assistant 访问,否则请使用 `http`。(该集成现在可以容忍缺失协议头或末尾带有 `/api` 的情况,但显式说明可以避免意外。)
- 一条 **预先存在的 GUI 防火墙规则**,该规则需引用你打算管理的主机别名(例如,源设置为 `KidsBlocked` 别名的拦截规则)。该集成管理的是别名 *内容*;作用于这些内容的规则必须已经存在于 GUI 中。
## 安装(HACS 自定义仓库)
1. 在 Home Assistant 中,打开 **HACS → Integrations**。
2. 点击 **⋮** 菜单(右上角) → **Custom repositories**。
3. 添加 `https://github.com/bearkiter-alt/opnsense-hass`,选择类别 **Integration**,然后点击 **Add**。
4. 在列表中找到 **OPNsense (HASS)** 并点击 **Install**。
5. **重启 Home Assistant**。
6. 前往 **Settings → Devices & Services → Add Integration** 并搜索 **"OPNsense (HASS)"**。
## 配置
通过 UI 配置流程进行设置。
| 字段 | 必填 | 默认值 | 备注 |
| --------------- | -------- | ---------- | ------------------------------------------------------------ |
| `name` | 是 | `OPNsense` | 友好名称 / 条目标题。 |
| `url` | 是 | — | **不带** `/api` 后缀的基础 URL,例如 `http://192.168.1.254`。|
| `api_key` | 是 | — | 来自 System > Access > Users 的 API key。 |
| `api_secret` | 是 | — | 与 key 配对的 API secret。 |
| `verify_ssl` | 否 | `false` | 对于自签名 HTTPS,请保持关闭。 |
| `scan_interval` | 否 | `30` | 轮询间隔,单位为秒 (5–3600)。 |
### 选项
设置完成后,打开该集成的 **Configure** 对话框:
- **`scan_interval`** —— 更改轮询间隔(秒,5–3600)。
- **`tracked_aliases`** —— 多选主机别名,将其公开为项目计数传感器和启用开关,并轮询其实时内容(带有友好名称 + MAC 的设备)。例如,选择 `KidsBlocked` 和 `KidsSchool` 以显示其成员。
- **`top_interface`** —— 其顶级带宽用户将反馈到 **Top talkers** 传感器的接口。默认为 `lan`(本地设备);选择 WAN 接口则会改为按远程端点进行排序。
## 实体
- **二元传感器** —— 每个网关一个,设备类为 `connectivity`。`on` = 网关在线(根据转换后的网关状态推导)。属性:`address`、`monitor`、`loss`、`delay`。
- **传感器**
- 每个网关:**延迟**(毫秒,持续时间)和 **丢包率**(%,默认禁用 —— 数据波动太大)。
- **版本** —— OPNsense 版本字符串(诊断)。
- **可用更新** —— 待处理更新的计数(诊断)。
- 每个被跟踪的别名:**项目计数** —— 别名中的条目数量,包含 `addresses` 属性(实时 IP)和 `devices` 属性,将每个 IP 解析为 `{ip, mac, name, manufacturer, online}`。
- 每个接口(例如 `lan`、`opt1`/WAN):**接收/发送速率**(`data_rate`,bit/s —— 显示默认为 Mbit/s)和累积的 **接收/发送** 字节数(`data_size`,`total_increasing`)。速率是根据轮询间的差值推导出来的,因此从第二次轮询开始才会显示。
- **Top talkers** —— 所选接口上的活跃主机计数;排名且已解析名称的列表(`{ip, name, mac, rate_in_bits, rate_out_bits}`)位于 `talkers` 属性中。
- **开关**
- 每条 **API 创建的防火墙规则** —— 启用/禁用该规则(随后会应用规则集)。*注意:* GUI 创建的规则不会在此处显示;仅列出通过 API 创建的规则。
- 每个 **被跟踪的主机别名** —— 切换该别名的 *启用* 标志(随后会进行重新配置)。
## 服务
```
# Block a device immediately (runtime, lost on reboot)
action: opnsense_hass.alias_add_host
data:
alias: KidsBlocked
address: 192.168.1.50
```
```
# Persistent block (default for rewards/blocking)
action: opnsense_hass.alias_block_device
data:
alias: KidsBlocked
address: 192.168.1.50
```
```
# Persistent unblock
action: opnsense_hass.alias_unblock_device
data:
alias: KidsBlocked
address: 192.168.1.50
```
```
# Replace the whole alias content
action: opnsense_hass.alias_set_hosts
data:
alias: KidsBlocked
addresses:
- 192.168.1.50
- 192.168.1.51
```
```
action: opnsense_hass.alias_remove_host
data: { alias: KidsBlocked, address: 192.168.1.50 }
```
```
action: opnsense_hass.alias_flush
data: { alias: KidsBlocked }
```
```
action: opnsense_hass.toggle_rule
data: { uuid: a1b2c3d4-...., enabled: false }
```
```
action: opnsense_hass.apply
data: { target: both }
```
```
# Raw passthrough, returns a response
action: opnsense_hass.exec_api
data:
method: GET
path: /routes/gateway/status
response_variable: gw
```
### 运行时与持久化
- **运行时** (`alias_add_host`、`alias_remove_host`、`alias_flush`) 直接编辑实时的 pf 表 —— 即时生效,但 **重启后丢失**。
- **持久化** (`alias_block_device`、`alias_unblock_device`、`alias_set_hosts`) 编辑别名 *配置* 并重新配置 —— **重启后依然保留**。对于奖励/封锁自动化,请优先使用这些方式。
## 时间奖励自动化工作示例 (ADHDTasker → HA → OPNsense)
```
# Default state: kid's device is blocked. ADHDTasker completing a task fires an
# event that grants N minutes of internet, then re-blocks via a timer.
automation:
- alias: "Reward - grant internet on ADHDTasker task complete"
trigger:
- platform: event
event_type: adhdtasker_task_completed
event_data:
reward: internet
action:
- action: opnsense_hass.alias_unblock_device
data:
alias: KidsBlocked
address: "{{ trigger.event.data.device_ip }}"
- action: timer.start
target:
entity_id: timer.internet_reward
data:
duration: "{{ trigger.event.data.minutes | default(30) }}:00"
- alias: "Reward - re-block internet when timer ends"
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.internet_reward
action:
- action: opnsense_hass.alias_block_device
data:
alias: KidsBlocked
address: "192.168.1.50"
```
## 许可证
[MIT](LICENSE) © 2026 bearkiter-alt
标签:Home Assistant, OPNsense, 智能家居, 系统集成, 网络调试, 自动化, 设备管控, 逆向工具