GrzegorzOle/behavioral-auth

GitHub: GrzegorzOle/behavioral-auth

一款纯本地运行的行为生物特征认证守护进程,通过分析键盘和鼠标的动态行为模式结合面部识别,持续验证当前计算机操作者的身份并在行为偏离时发出警告。

Stars: 0 | Forks: 0

# behavioral-auth 一个纯本地运行的守护进程(daemon),它会学习**你**个人的打字和鼠标移动方式,冻结该模式,然后在当前键盘操作者不再匹配该模式时向你发出警告。 它**从不锁定会话,也从不将任何人登出。** 它能做的最严厉的操作就是向日志、控制台以及(可选的)桌面通知写入一条警告信息。这是一个刻意为之的设计约束,而不是未完成的功能。 一切都运行在你的机器上:使用本地磁盘上的 DuckDB,CPU 上的 ONNX,除非你自己开启 SIEM 转发,否则不会有任何网络请求——请参阅[什么数据会离开本机](#what-leaves-the-machine)。 **支持 Linux 和 Windows。** 每次发布都会提供 Windows 安装程序和 Linux AppImage,两者都是完全独立的——请参阅[安装](#install)。Linux 是这两者中历史更久、测试更充分的平台;Windows 构建版本较新,[平台支持](#platform-support)准确列出了其中哪些部分已得到确认,哪些尚未确认。 ## 它实际做了什么 ``` first start, empty machine │ ▼ ┌─────────┐ collects keystroke + mouse behaviour, │ NAUKA │ silently photographs your face in the background, │LEARNING │ retrains every so often and checks whether the └────┬────┘ pattern has stopped moving │ │ ... enough data + N stable cycles in a row + sanity gate ▼ ┌────────────┐ pattern is FROZEN. Scores live behaviour against it. │ NADZÓR │ Nothing retrains here — a stranger cannot teach the │ MONITORING │ system to accept them just by using the computer. └────┬───────┘ │ ... behaviour deviates, and keeps deviating ▼ ┌─────────┐ logs, prints, notifies. Locks nothing. │ ALARM │ Clears itself when normal behaviour returns. └─────────┘ ┌─────────────┐ you docked, or swapped keyboards. The pattern was learned │ ZAWIESZONY │ on other hardware, so there is nothing meaningful to │ SUSPENDED │ compare against — it stops scoring and says so. Never an └─────────────┘ alarm. Collection continues. ``` 这个模式只会在**你**下达指令时改变——执行 `behavioral-auth reset`(其他人要使用这台机器)或 `behavioral-auth learn-more`(完善你现有的模式)。代码中没有任何自动适应的逻辑。数据也不会过期:即使你休假两周回来,模式依然有效,不需要在回来之前刷新它。但是行为习惯在几周时间内确实会产生变化,因此 `behavioral-report` 会显示模式的存在时间以及每周的偏差中位数。如果偏差呈现上升趋势,那可能是**你**自己的习惯在漂移,**或者**是其他人坐在了键盘前——这个系统无法区分这两者,也不会假装能区分。报告只提供数据,将判断权交给你。 ### 模式绑定于特定的硬件组合 你在笔记本电脑键盘上的打字方式,与通过扩展坞连接的外接键盘上不同;你在触控板上的移动方式也不同于鼠标。因此,模式会绑定在学习它时所使用的硬件上,而来自其他硬件的行为数据**完全不参与评分**,而不是获得低分。 这不仅仅是为了避免误报。基于两种设置*混合*训练出的模式会具有更大的分布范围,因此其阈值会设置得更高,从而接受更多的行为——在注册时混合使用硬件会使系统发现陌生人的能力**降低**,而不仅仅是更可能打扰你。如果你在插上扩展坞时进行注册,然后拔下扩展坞,守护进程会暂停评分并通知你;`learn-more` 会将第二种设置的数据合并进来,并在此刻向你明确警告这种代价。 ## 明确它能告诉你什么,不能告诉你什么 这一点比任何功能都重要,因此放在安装说明之前。 **没有冒充者的数据。** 系统自始至终只看到过一个人:你。这带来了硬性的后果: - **无法测量错误接受率(False-accept rate)。** 无论本系统还是任何程度的调参都无法做到。`behavioral-report` 刻意拒绝打印 FAR/FRR 数据——早期版本曾根据你自己的分数计算出这些数字,这让一个毫无意义的数字看起来像是一项安全指标。 - 推广门控(Promotion gate)*确实*验证了以下内容:(1) 模式已经**收敛**——模型对全新的、从未训练过的行为的重建效果与对训练数据一样好,且阈值已停止变动;(2) 模型**未退化**——它能可靠地标记出通过扭曲你自己的数据生成的合成冒充者。第二项检查不是走过场。如果让自编码器将其自身目标作为输入,它会学会直接复制它,从而对*地球上的任何一个人*都得出漂亮、稳定且极低的误差,并且永远不会对任何人触发警报。这个门控的存在正是为了捕捉这种情况,而且在开发过程中它确实捕捉到了。 - 推广提示信息会明确说明这一切,包括训练好的模型最终对哪些类型的差异是**盲目**的。 **人脸识别是一个佐证信号,而不是门控。** LBPH 仅使用单一标签进行训练,因此它只能回答“我有多大把握认为这是已注册的人员”——校准后的置信度截断值就是整个决策过程。未知的面孔被视为*无证据*,绝不会被当作入侵者的证据。将其视为一种能在某些情况发生改变时发出警报的绊线。不要将其视为访问控制机制。 ## 什么数据会离开本机 **默认情况下:什么都不会。** 在 `siem.enabled: false`(这是默认发布设置)的情况下,此代码树中的任何代码路径都不会打开网络套接字。你记录下的行为数据、基于其训练的模型以及你的人脸照片都保存在 `/var/lib/behavioral-auth` 中,并且只有此守护进程才能读取。 你可以开启向 SIEM(本地 syslog,或直接发送到 Wazuh 管理器)的转发。如果你开启转发,以下是发送内容的完整列表: | 发送的内容 | 绝对不会发送的内容 | |---|---| | 报警:触发和解除状态,包含 `reason`、`ratio`(类似于 `4.54` 的数字)以及持续时间 | 键盘按键代码、键名、任何你输入过的内容 | | 状态转换:`LEARNING → MONITORING → ALARM`,以及转换原因 | 鼠标坐标或移动轨迹 | | 操作:守护进程启动/停止、`pause`、`learn-more` 以及 `reset` | 你的人脸照片,或来自摄像头的任何视频帧 | | 摄像头是否匹配,显示为 `match`、`stranger` 或 `unknown` | 特征向量、序列、模型权重、缩放器(scaler)、阈值 | | 附加或丢失的输入设备,以及硬件堆栈的更改,作为**哈希处理后的**指纹显示 | 设备名称、供应商/产品 ID——任何等同于硬件清单的信息 | | 主机名,以及注册/会话的 UUID | 单个序列的评分——按照 5 秒的步长,每小时会有成百上千个 | 事件携带的是**一个判定结果和一个数字,绝不包含计算出它们所基于的行为数据。** `StateStore.transition` 接收一个用于本地数据库的自由格式 `details` 字典;它被刻意设置为*不*进行转发,这样以后在那里添加的字段就不会在没有人决定应该转发的情况下擅自离开本机。 ### 本地副本并不像看起来那样会完全消失 `siem.store_alarms_locally: false` 会阻止报警被写入 DuckDB。但它**并不会**让它们在本地彻底消失: - 如果使用 `sink: syslog`,事件会被移交给 `/dev/log`,因此它也会进入**本机的 journald 或 rsyslog**,并根据你系统的日志保留策略停留在那里。你只是移除了一个本地副本,而不是全部。 - 未送达的事件会在**磁盘假脱机队列**(`siem.spool_path`)中等待,直到 SIEM 确认接收。如果 SIEM 一天无法连接,那就会有一天量的报警文件留在那里。它们一旦送达就会被删除。 如果你完全不希望报警留下任何本地痕迹,可以使用 `sink: wazuh` 通过网络发送它们,而不必经过本地 syslog——即便如此,只要存在无法发送的数据,假脱机队列依然会保存它们。不存在任何一种配置,能够使得一个事件既能在网络中断时存活,又不留下任何本地痕迹;这两个愿望是相互矛盾的,而这个守护进程选择了*不丢失事件*。 ## 安装说明 有三种获取方式。每个打标签的版本都提供了适用于两种操作系统的现成可运行构建版本——无需编译任何内容。 ### Windows — 安装程序 从 [releases](../../releases) 下载 **`behavioral-auth-setup-.exe`** 并以管理员身份运行。它会将程序安装到 `C:\Program Files\behavioral-auth\`,在 `C:\ProgramData\behavioral-auth\` 中生成一个可编辑的配置文件,并注册一个自启动服务。 可通过“*应用和功能 (Apps & features)*”进行卸载。完整的操作步骤请见 [docs/USAGE.md](docs/USAGE.md)。 目前已可用的功能:套件可成功安装,CLI 和报告可运行,服务可成功注册。**在依赖它之前,有两件事需要了解。** 目前还没有人确认能在 *Session 0* 中通过服务捕获输入——如果在你打字时 `status` 停留在 `LEARNING` 状态且没有序列数据,请在你自己的会话中运行 `behavioral-authd.exe`,这是文档中记载的备选方案。此外,上述硬件绑定在 Windows 上不适用:`pynput` 是一个全局钩子,无法区分不同的键盘。请参阅 [平台支持](#platform-support)。 ### Linux — AppImage 下载 **`behavioral-auth-x86_64.AppImage`**,执行 `chmod +x` 赋予执行权限,然后将其作为多调用二进制文件运行: ``` ./behavioral-auth-x86_64.AppImage authd # also: auth, report, face ``` 你仍然需要 `input` 和 `video` 用户组、一个可写的数据目录,以及 FUSE 2——AppImage 打包了应用程序本身,但不包含系统环境。前置依赖条件只需三条命令,详见 [docs/USAGE.md](docs/USAGE.md)。 ### Linux — 从源码构建 这是经过测试的路径,如果你想自动配置 systemd unit 和 udev 规则,请使用此方法。要求 Python 3.11+。 ``` git clone behavioral-auth && cd behavioral-auth make venv sudo usermod -aG input,video "$USER" # then log out and back in ``` 适用于 Fedora/RHEL 和 Ubuntu/Debian 的系统安装脚本位于 `src/scripts/` 中。 ## 运行 ``` behavioral-authd # that's it — creates the database, starts learning ``` 无需模式(schema)同步步骤,无需手动注册,无需手动运行任何流水线(pipeline)。在一台完全清空的机器上,守护进程会创建数据库、应用迁移、开启注册并开始收集数据。控制台会显示当前进度: ``` ╭─ behavioral-auth ───────────────────────────── NAUKA ─╮ │ wzorzec 3f9a1c2b czas 01:42:07 │ │ sekwencje 842/1200 [████████████░░░░░░] │ │ aktywność 64m/90m [█████████████░░░░░] godzin 2/3│ │ twarz 48/60 [███████████████░░░] │ │ cykl 3 seria stabilnych 1/3 │ │ ✓ pass_rate 0.94 err_ratio 1.31 separacja 4.2x │ ╰───────────────────────────────────────────────────────╯ ``` 在 systemd 环境下没有控制台,所有信息都会输出到 journal 中: ``` systemctl --user enable --now behavioral-authd journalctl --user -fu behavioral-authd ``` ### 两分钟内测试整个流程 学习通常需要数小时的真实使用,而测试报警则需要第二个人(来模拟)。因此我们提供了一个在加速时钟下运行的合成输入源(在 `prod` 模式下会被拒绝使用——因此这里加上 `--mode dev`,这也会合并 `config.dev.yaml` 并降低所有的推广门控要求): ``` make demo # behavioral-authd --mode dev --synthetic-input user --synthetic-speed 40 ``` 观察它进行学习、收敛、推广,并切换到 MONITORING 状态——大约需要一分钟。然后,在另一个终端中,让一个不同的人坐在键盘前: ``` make demo-impostor # behavioral-auth set-profile impostor ``` 偏差会越过阈值,一旦偏差*持续*处于高位,就会触发 ALARM。 在 `--mode dev` 下推广的模式只是一个冒烟测试,不是可以依赖的正式模式;可以通过 `behavioral-auth reset` 清除它。该演示会写入与真实运行相同的 `data_dir`,因此如果你不想碰真实的目录,请将 `BEHAVIORAL_AUTH_CONFIG` 指向一个临时配置文件。 ## 命令 | 命令 | 功能说明 | |---|---| | `behavioral-authd` | 守护进程。负责学习,然后进行监控。 | | `behavioral-auth status` | 显示当前状态和进度。可在守护进程运行时使用。 | | `behavioral-auth reset` | **其他人将要使用这台机器。** 销毁当前模式及所有人脸截图,从零开始学习。 | | `behavioral-auth learn-more` | 使用更多数据完善现有模式。完全由用户手动触发,绝不自动执行。 | | `behavioral-auth pause` / `resume` | 停止/开始评分(数据收集仍会继续)。 | | `behavioral-auth set-profile user\|impostor` | 在运行中途切换合成的模拟人员。仅在使用 `--synthetic-input` 启动守护进程时有效。 | | `behavioral-report` | 学习周期、评分、报警、模式存在时间以及每周的偏差情况。不包含 FAR/FRR 数据——原因见上文。 | | `behavioral-face info` / `verify` | 检查并测试守护进程构建的人脸模式。 | 守护进程在其整个生命周期内持有 DuckDB 的唯一写锁,因此 CLI 是通过控制池(control spool)而不是数据库与它通信的。当没有守护进程运行时,相同的命令将直接操作数据库。 ## 配置 主配置文件为 `config/config.yaml`,并会叠加合并 `config..yaml` 覆盖层。将 `BEHAVIORAL_AUTH_CONFIG` 指向某个文件即可覆盖默认的搜索路径。 `general.mode` 默认为 **`prod`** —— 即下文提到的门控条件,需要数小时的真实使用才能满足。如果将其设置为 `dev`,则会合并 `config.dev.yaml` 并放宽所有条件,使得整个流程在几分钟内即可完成;在这些宽松门控下推广的模式仅仅是冒烟测试,绝不能作为正式依赖的依据,守护进程在启动时也会明确声明这一点。 决定行为的核心配置项: ``` learning: min_sequences: 1200 # roughly 2-4 h of real, active use min_active_minutes: 90 # summed window coverage, not wall-clock min_distinct_hours: 3 # you must be seen across the day, not one burst stable_consecutive_cycles: 3 stability: false_alarm_max: 0.02 # never promote a pattern that would flag YOU sanity_detection_min: 0.90 # ...or one that detects nobody at all alarm: enter_consecutive: 16 # a burst of scores is not a sustained anomaly: enter_min_span_sec: 120 # adjacent sequences overlap, so span matters too clear_consecutive: 16 clear_min_span_sec: 120 face: enabled: true confidence_threshold: auto # calibrated from your own held-out crops keep_samples: true # crops stay in face_samples/, 0700, wiped on reset ``` 这里没有 `lock_cmd`,也没有 `enforce` 模式。它们是直接从代码中移除了,而不是仅仅在配置文件中禁用。 ### 发送事件到 Wazuh 管理器 `packaging/wazuh/` 目录下包含了一个解码器(decoder)和一个规则集(ruleset)。它们需要安装在**器**上,而不是本机上——解码工作是在管理器端完成的。如果没有这些规则,Wazuh 管理器虽然能接收到事件,但不会匹配到任何规则,这意味着它会默默丢弃它们:既不会报警,除非开启了 `logall_json`,否则也不会进行归档。 如果此主机上的 Wazuh 代理已经配置为收集 journald 日志——这是 Fedora 的默认设置——那么事件无需更改任何代理端的配置即可到达管理器。请使用 `journalctl -f SYSLOG_FACILITY=10` 进行验证;**不要**使用 `journalctl -t behavioral-auth`,因为 journald 会解析 RFC 3164 格式的日志,而这些事件是按照 RFC 5424 格式封装的,所以即使转发功能正常工作,后者也什么都找不到。 解码器和规则已经通过了格式正确性检查,并针对捕获到的事件帧进行了测试,但还**没有**在真实的 Wazuh 管理器上实际运行过。你可以使用 `wazuh-logtest` 花一分钟时间在你的管理器上进行验证;具体操作流程请见 `packaging/wazuh/README.md`。 ## 隐私 所有数据都保留在本机上。有两点值得注意: - **按键的*代码*会被记录**,同时记录的还有按键时间——这足以知道你按下了按键代码 30,但并不能推断出你的键盘布局将其映射为了哪个具体字符。尽管如此,还是请将 `behavior.duckdb` 视为敏感数据妥善保管。 - **人脸截图会被存储**在 `face_samples//` 目录下(权限 0700,大小为 150×150 的灰度图像),这样无需重新注册即可重新校准置信度阈值。你可以设置 `face.keep_samples: false` 以仅保留训练好的模型,或者设置 `face.enabled: false` 以彻底不打开摄像头。`behavioral-auth reset` 会删除这些照片。 ## 平台支持 **Linux —— 构建、运行和验证均在此平台完成。** 数据采集使用 `evdev`;发布版提供了一个完全独立的 AppImage。 **Windows —— 自 0.4.0 起开始发布,目前处于 Beta 阶段。** 软件套件是完整的:包含一个能够产生与 evdev 采集器相同的事件行的 `pynput` 输入后端、一个 Event Log SIEM 接收器(sink)、一个 Windows 服务以及一个安装程序,所有这些都由 CI 在每次打标签的发布版本中自动构建,现可供下载。 与其给出一个含糊的状态,不如直接看实际的分类细节: | 已确认支持 | 尚未确认支持 | |---|---| | 打包后的程序可以在 Windows runner 上成功构建和冻结 | **在服务控制管理器 (SCM) 下进行数据采集** —— 即下文的 Session 0 问题 | | `behavioral-auth.exe` 和报告功能可正常运行 | 报警信息能够成功写入 Event Log | | 安装程序能够编译并生成可运行的 `.exe` | 推广至 MONITORING 状态(已观察到一次稳定循环,但还需连续多次确认) | | 与操作系统无关的逻辑(键盘代码映射、事件整形)已经过单元测试 | Wazuh 代理能够解码 Event Log 报警 | | **安装程序可在真实机器上安装** —— 包含 Program Files 目录结构、ProgramData 中的可编辑配置文件、系统级的 `BEHAVIORAL_AUTH_CONFIG` 变量以及注册为自启动的服务 | 人脸通道读取视频帧 —— 见已知局限性 | | **卸载过程是干净的** —— 服务会注销,且 `C:\ProgramData\behavioral-auth\` 会按预期保留 | | | **`pynput` 钩子可以在真实硬件上捕获真实的键盘和鼠标输入** | | | **一个完整的学习周期可以在 Windows 上完成** —— 包括训练、评分和推广健全性门控 | | | **冻结的服务宿主进程能够启动** 并达到 `LEARNING` 状态 | | 以上所有已确认的内容均于 2026-07-29 在一台真实的 Windows 机器上观察验证;所有未标记的内容都在每次发布时由 CI 运行测试。 **请准确理解关于服务的那一行。** 目前已确认服务*宿主进程*能够在 `debug` 模式下启动,该模式运行在**交互式用户会话**中。这与在 Session 0 中通过 SCM 运行不是一回事,而且它刻意没有回答这个问题——这就是为什么“在 SCM 下进行数据采集”仍然被归类在右侧的“尚未确认支持”一列中。 **在 0.5.3 版本中已修复 —— 服务完全无法启动的问题(影响 0.5.2 及更早版本)。** 服务在能够向 SCM 报告状态之前,就在解析其配置文件的阶段崩溃了,而 SCM 只能将其描述为事件 7000/7009,“未及时响应启动信号”。这主要有两个原因:搜索路径中没有类似于 Linux `/etc` 的 Windows 对等路径,因此安装程序生成的配置文件只能通过系统级环境变量访问,而 SCM 在机器重启前是读取不到该变量的;此外,打包在内的默认配置文件所使用的名称根本没有任何程序会去查找。如果你正在使用 0.5.2 或更早的版本,请升级——没有任何值得尝试的变通方案。 它目前仍处于 Beta 阶段:我们从未看到报警信息成功到达 Event Log,而且也尚未在真实的 SCM 环境下监控过该服务捕获数据的行为。`docs/USAGE.md` 列出了在真实硬件上需要检查的内容。 在依赖它之前,有两个 Windows 特有的局限性值得了解: - **没有独立的设备身份标识。** `pynput` 是一个单一的全局钩子,无法判断某次按键来自哪个键盘,因此上文提到的硬件堆栈绑定在 Windows 上是不适用的——它在这里是无效的,并没有被强制执行。 - **Session 0 中的服务**可能根本无法捕获交互式桌面输入;备用方案是在用户会话中运行 `behavioral-auth.exe`。 通过 WSL2 并将输入直通到 `/dev/input` 是第三种选择,而对于守护进程来说,这种方式会被视同常规的 Linux 环境。 ## 目录结构 ``` src/behavioral_auth/ ├── daemon/ state machine, learning controller, alarm logic, control channel ├── collector/ evdev + pynput capture, hardware-stack identity, synthetic source ├── features/ incremental window and sequence extraction ├── models/ Conv1D autoencoder with a bottleneck ├── training/ dataset scoping, fitting, promotion gates, threshold calibration ├── inference/ ONNX scoring, behavioural/face channel rules ├── face/ silent LBPH enrolment, quality gates, calibration ├── reporting/ what was observed ├── siem/ optional forwarding: syslog, Windows Event Log, Wazuh └── db/ DuckDB access + schema migrations packaging/ ├── wazuh/ decoder + ruleset for a Wazuh manager (install there, not here) ├── windows/ PyInstaller spec, service, Inno Setup installer └── AppImage and one-folder Linux bundle ``` ## 许可证 详见 [LICENSE](LICENSE)。
标签:Apex, CNCF毕业项目, 持续身份验证, 机器学习, 系统守护进程, 行为生物识别, 逆向工具