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, 智能家居, 系统集成, 网络调试, 自动化, 设备管控, 逆向工具