工作原理与平台边界
banhack233 组合 fail2ban / sshguard 风格防爆破、系统巡检、SSH/可选 TCP 保活、通知、自启动与版本更新。它不是 fail2ban 配置解析器、完整商业杀毒或 EDR。
从日志到动作
加载并严格校验配置 → 获取状态写入锁
→ 读取状态、释放到期或新白名单的已记录自动封禁
→ 按规则和来源游标读取新增日志
→ 先找本批成功登录:清计数、设置来源 IP 宽限
→ 密码失败:规范化 IP → 白名单/宽限 → 用户分组 → 阈值
→ 仅 SSH 目标端口的防火墙动作 / dry-run / notify 冷却
→ 记录应用日志并持久化通知 → 独立投递与重试
→ 只读巡检 → 保存状态 → 下一轮
默认只统计 Failed password,不把 Invalid user、失败公钥、认证上限提示、连接关闭当成额外密码失败。同一读取批次内的成功优先于封禁;随后默认给予同规则该 IP 10 分钟宽限。自定义规则省略 success_grace 时为零,但当前批次的成功保护仍有效。
count_by_user=true 时用 规则|IP|用户名 计数;同一个出口的不同账号各自累计,共享账号仍共用计数。实际防火墙只有来源 IP。公网路由不会把客户端网卡 MAC 地址传给 SSH 服务端,无法据此区分公司内的电脑。需要设备身份时应使用独立账号/密钥、SSH 证书或具备设备身份的接入网络;本程序没有实现按设备封禁。
公司出口白名单最直接,但意味着该出口后所有来源获得豁免;成功宽限同样信任该 IP 的近期成功登录。安全要求更高时可缩短 success_grace,或使用 action=notify 加人工处置。没有“每分钟建立六次连接就丢弃”的规则。
日志、状态与到期
- 文本来源按规则和路径独立保存偏移,检查文件身份,替换/截断后重新读取;半行留到下轮,超长记录丢弃,单轮读取约 4 MiB。轮转文件被删除前尚未读取的旧尾部无法恢复。
- Windows 按 EventRecordID 顺序处理,每轮最多 1024 个事件,保存游标并去重;首次
start_at_end=true记录最新位置。发现日志清空导致 ID 回退时重新读取。 - 跨文件重复转发没有全局事件 ID,仍可能重复计数。失败时间使用扫描时刻,尚不解析历史日志时间;生产保持
start_at_end=true。 - 同一状态文件有跨进程锁,第二个 daemon/test 会报错;通知队列应随该实例使用独立路径。
- 到期由运行中的守护进程释放;服务停止时不会继续自动解封。多个有效规则/用户名封禁共享 IP 时,全部解除后才删除后端条目。
- 解封失败保留状态并重试;自定义动作不自动推测撤销命令。
unban只操作后端,删除状态文件不等于清理防火墙。 - 内核规则和状态文件不同步持久化。主机重启或外部清空规则后,尚未到期的封禁目前不会全量自动重建。
- 重命名/删除规则不立即解除已有封禁。变更
ssh_ports后应审阅旧规则;保存的端口记录用于到期清理。
平台能力
| 能力 | Linux | macOS | Windows |
|---|---|---|---|
| 发布架构 | amd64 / arm64 | amd64 / arm64 | amd64 / arm64 |
| 自启动 / 每日更新 | systemd / timer | launchd / 86400 秒 | SYSTEM 计划任务 |
| 日志 | auth.log / secure / 自定义文本 | 自行配置认证文本来源 | OpenSSH/Operational 事件或文本 |
| 封禁 | nft 优先,否则 iptables/ip6tables | PF 表,需管理员配置引用规则 | netsh 入站 localport |
| SSH 端口 | ssh_ports,默认 [22] |
PF 规则自行指定 | ssh_ports,默认 [22] |
| secure-ssh / keepalive | 支持 | 不支持 | 不支持 |
| 恶意程序扫描 | 轻量辅助 | 报告不支持 | 报告不支持 |
| GeoIP | 可选本地 IPv4 数据库 | 同左 | 同左 |
nft 存在但执行失败时不会偷偷切换到另一套防火墙;应修复选中后端的权限/内核问题。PF 没有检测到引用 <banhack233> 的过滤规则时会拒绝执行,避免把“表里有 IP”误认为已经阻断;管理员仍需验证规则范围和效果。Windows 本地端口语义参考 Microsoft netsh。
六平台构建、Linux/Windows/macOS 单元测试与 Linux 隔离集成检查,不等于每个真实操作系统都完成流量验收。Windows 的 autostart-status 仍不准确反映任务活跃状态,使用任务计划程序核对;updater 重启检查单独读取任务运行状态。
只读与清理边界
status、doctor、定时巡检始终只读。malware-scan 必须输出报告;唯一配置开关 direct_kill 默认 false。显式开启后仅限定的入侵程序名可终止;临时目录、masscan、xmrig 或命令行中的关键词不会单独触发清理。它们仍可作为待复核线索,不能据此证明入侵。
报告命名 {名字}.yyyy-MM-dd_HH-mm-ss.txt;同名同秒时给名字加序号,避免覆盖。默认保留最近修改的 50 份,属于按数量和修改时间淘汰的 LRU 类策略,不会因读取报告而更新保留优先级。
dry_run 只约束防火墙动作,并非所有命令的只读开关。手动清理、SSH 配置写入及显式更新必须分别理解。keepalive -write 默认只写 SSH,系统 TCP/conntrack 仅显式 -tcp 才改。业务 TCP 长连接还依赖自研 TCP 服务/客户端的心跳、socket keepalive 和中间网络超时。
当前仍需完善
- 原生 journald 输入、历史事件时间、快速轮转旧尾部补读、重启后的防火墙完整协调。
- 更强的主机健康与防护指标、可重复容量基准;当前没有 Prometheus 端点或性能 SLO。
- macOS PF 安全托管及真实跨平台网络验收、设备身份接入方案。
- 独立发布签名/证明;当前更新校验依赖受信 GitHub Release 的 SHA256SUMS。