Authelia 登录频率限制(Regulation)配置全指南:防暴力破解的账户封禁机制
Authelia 登录频率限制Regulation配置全指南防暴力破解的账户封禁机制【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/autheliaAuthelia内置的Regulation频率限制系统能够在用户名/密码认证端点检测到过多失败尝试时对账户进行临时封禁从而有效抵御暴力破解攻击。本文以 docs/content/configuration/security/regulation.md 为核心骨架结合internal/regulation、internal/configuration、internal/handlers等模块的源码实现系统讲解regulation配置块的每一个参数、底层判定算法、与认证流程的集成方式以及通过authelia storage bans命令手动管理封禁条目的实战方法。读完本文你将能够理解modes、max_retries、find_time、ban_time四个配置项的精确语义与默认值掌握封禁判定计数窗口、成功重置、封禁时长的真实算法学会排查与运维封禁条目让账户在ban_time到期后自动恢复登录。一、Regulation 是什么为什么要限流Regulation 是 Authelia 安全体系中的一层认证防爆破brute-force prevention机制。当攻击者针对用户名/密码登录端点即第一因素认证1FA反复尝试弱口令或撞库时Regulation 会统计find_time时间窗口内的失败次数一旦达到max_retries阈值即按配置的modes封禁用户账号或来源 IP封禁持续ban_time时长。与前端限流、验证码等方案不同Regulation 是服务端、持久化的每次认证尝试成功或失败都会写入存储层MySQL/PostgreSQL/SQLite的认证日志表封禁记录BannedUser/BannedIP同样持久化到数据库Authelia 重启后依然有效封禁到期后记录不会自动删除但查询时通过时间条件判定其已失效账户即可恢复登录。二、Configuration完整配置示例Regulation 配置位于configuration.yml的regulation顶层键下一个完整可用的最小示例regulation: modes: - user - ip max_retries: 3 find_time: 2m ban_time: 5m字段说明速览配置项类型默认值作用modeslist(string)[user]封禁的生效对象user封账号或ip封来源 IPmax_retriesinteger3达到该失败次数即触发封禁设为0可完全禁用 Regulationfind_timestring,integerduration2 minutes统计失败尝试的时间窗口ban_timestring,integerduration5 minutes触发封禁后的封禁时长提示在文档站点中该示例块带有 “config-alert-example” 提示表示这是可复制到configuration.yml的推荐基线配置。其中同时启用了user与ip两种模式属于比较严格的双重防护配置。三、Options四个配置参数深度解析3.1 modes封禁对象user / ipmodes决定封禁的主体是谁。文档明确指出推荐使用ip模式并强调一个重要行为无论当前配置了哪种封禁模式只要数据库中已经存在有效的封禁记录该用户或 IP 都会被拒绝访问——也就是说modes只影响“自动产生新封禁”的判定路径而不影响“已存在的封禁是否生效”的检查路径。模式描述user封禁的对象是用户账号即max_retries次失败均发生在同一用户名下ip封禁的对象是远程来源 IP即max_retries次失败均来自同一 IP从源码看模式的解析发生在 regulator.go 的 NewRegulatorusers: config.MaxRetries 0 utils.IsStringInSlice(typeUser, config.Modes), ips: config.MaxRetries 0 utils.IsStringInSlice(typeIP, config.Modes),注意两个细节max_retries为 0 时无论modes配了什么users和ips都为falseRegulation 整体失效这与文档中 “Setting this option to 0 disables regulation entirely” 的描述完全一致modes的合法取值仅有user与ip其余值会在配置校验阶段直接报错。校验逻辑见 validator/regulation.gofor _, mode : range config.Regulation.Modes { switch mode { case ip, user: break default: validator.Push(fmt.Errorf(errFmtRegulationInvalidMode, mode)) } }对应测试 regulation_test.go 验证了单独ip、单独user、[ip,user]均合法[invalid]或混合非法值会被拒绝空modes列表则回落到默认值[user]。3.2 max_retries失败阈值max_retries是触发封禁所需的失败次数。默认值3即 3 次失败即可封禁。设置为0会完全禁用 Regulation如上文NewRegulator中所示0 会让users/ips同时为 false。阈值语义在 regulator.go 的 expires 方法 中体现得非常清晰// 如果 find_time 窗口内的失败次数小于 max_retries则不封禁 if len(failures) r.config.MaxRetries { return nil }也就是说失败次数必须达到max_retries才会封禁。3.3 find_time失败统计时间窗口find_time是“在多久的时间范围内统计失败尝试”。类型为string,integer语法为 Go duration 格式例如2m、30s、1h。默认值2 minutes。文档中的经典示例设置max_retries: 3、find_time: 2m意味着用户必须在2 分钟内累计 3 次失败登录才会被禁。底层实现中find_time被转换为一个“起始时间点”用于在存储层查询该时间点之后的认证日志。见 regulator.go 的 HandleAttemptsince : r.clock.Now().Add(-r.config.FindTime) r.handleAttemptPossibleBannedIP(ctx, since) r.handleAttemptPossibleBannedUser(ctx, since, username)而存储层的 SQL 查询按time ?过滤sql_provider_queries.goSELECT time, successful FROM authentication_logs WHERE time ? AND username ? AND auth_type 1FA AND banned ? ORDER BY time DESC LIMIT ?;注意查询条件auth_type 1FA——只有第一因素密码/用户名认证的失败才会计入 Regulation 统计这也印证了 Regulation 防的是“用户名/密码端点”的暴力破解。3.4 ban_time封禁时长ban_time是封禁持续的时间。默认值5 minutes到期后账户自动恢复登录。它同样使用 duration 语法。封禁到期时间的计算方式值得注意regulator.go 的 expires 方法expires : failures[0].Time.Add(r.config.BanTime) return expires即封禁的到期时间 窗口内第一次失败尝试的时间 ban_time而不是“触发封禁的时刻 ban_time”。因此封禁会在“首次失败后的ban_time”时点自动解除。3.5 配置校验规则find_time 与 ban_time 的关系校验器强制约束find_time必须小于或等于ban_time否则配置加载失败。错误信息定义在 validator/const.goregulation: option find_time must be less than or equal to option ban_time这一约束的合理性在于统计窗口find_time不应大于封禁周期ban_time否则可能出现“封禁已过期但统计窗口仍然覆盖着更早的失败记录”的语义混乱。对应测试见 regulation_test.go。同时find_time与ban_time若被设置为非正值如-1会被重置为默认值validator/regulation.go相关行为在TestShouldSetDefaultRegulationTimeDurationsWhenNegative中有覆盖。四、工作流程从一次失败登录到账户被禁将配置与源码串起来一次完整的 Regulation 判定流程如下认证前检查在FirstFactorPasswordPOST处理器执行密码校验之前先调用Regulator.BanCheck(ctx, username)检查该用户或来源 IP 是否已在封禁中handler_firstfactor_password.go。若命中封禁返回regulation.ErrUserIsBanned直接返回401 Unauthorized不再执行密码比对记录尝试无论密码校验成功与否都会通过doMarkAuthenticationAttempt→Regulator.HandleAttempt记录一条认证日志response.go写入AuthenticationAttempt结构对应的authentication_logs表model/regulation.go触发统计HandleAttempt中仅当满足“本次尝试失败 当前无生效封禁 Regulation 已启用ips || users 认证类型为 1FA”四个条件时才执行封禁判定regulator.go分别检查 IP 与用户handleAttemptPossibleBannedIP与handleAttemptPossibleBannedUser各自查询find_time窗口内的失败记录按 IP 或按用户名调用expires计算封禁到期时间写入封禁达到阈值后向banned_ips/banned_users表写入一条Source: regulation、Reason: Exceeding Maximum Retries的封禁记录regulator.go、model/regulation.go。expires判定算法的关键点regulator.go失败记录按时间倒序遍历遇到第一条成功记录立即停止计数——也就是说窗口内只要有一次成功登录之前的失败不再累计当失败计数达到max_retries后停止继续累加已经该禁了早于since即超出find_time窗口的记录被跳过最终以失败列表中的最早一条失败时间加上ban_time作为封禁到期时间。一个值得注意的行为成功登录会“重置”窗口内的失败累计。这在expires的break loop分支中体现——一旦遇到Successful true的记录就停止统计因此攻击者若在窗口内有一次成功登录其此前的失败将不计入封禁判定。五、封禁的解除与手动管理authelia storage bans文档明确提示无论当前配置的封禁模式如何数据库中已存在的封禁记录始终生效封禁条目可通过authelia storage bans命令族手动管理。该命令的定义见 commands/storage.go文档参考见 docs/content/reference/cli/authelia/authelia_storage_bans.md。命令层级结构authelia storage bans ├── user │ ├── list │ ├── add username │ └── revoke [username] └── ip ├── list ├── add ip └── revoke [ip]5.1 查看封禁列表authelia storage bans user list authelia storage bans ip list对应 SQL 只返回当前仍有效的封禁revoked FALSE AND (expires IS NULL OR expires NOW())见 sql_provider_queries.go。5.2 手动添加封禁authelia storage bans user add john --duration 1 day --reason suspicious activity authelia storage bans ip add 203.0.113.5 --permanent --reason abuseadd子命令支持的参数storage.go参数缩写默认值说明--duration-d1 day封禁时长与--permanent互斥--permanent-pfalse永久封禁expires为 NULL--reason-r空封禁原因写入reason字段若同时指定--permanent与--duration命令会报错拒绝执行。5.3 撤销封禁authelia storage bans user revoke john authelia storage bans ip revoke 203.0.113.5 # 按封禁记录 ID 撤销 authelia storage bans user revoke --id 42revoke可通过-i/--id指定封禁记录 ID或直接传用户名/IP 值。撤销后该条封禁的revoked标记为真不再影响登录。5.4 手动封禁 vs 自动封禁的差异手动添加的封禁与 Regulation 自动产生的封禁共用同一张banned_users/banned_ips表但Source字段不同自动封禁的Source恒为regulation、Reason为Exceeding Maximum Retries而手动封禁可以自定义Reason。由于文档明确“只要数据库中存在有效封禁记录即拒绝访问”手动封禁同样会立即生效可用于应急封禁某账号或某恶意 IP。六、最佳实践与注意事项推荐使用ip模式user模式容易被攻击者利用来“锁死”他人账号拒绝服务而ip模式对正常用户影响更小。文档明确推荐ip同时启用两种模式需谨慎userip双模式意味着同一来源 IP 和账号都可能被禁防护更严但误伤面更大max_retries: 0会彻底关闭 Regulation如果希望仅保留“已存在封禁仍然生效”的能力而不再自动产生新封禁可以这样配置但注意这会失去自动防爆破能力find_time与ban_time的关系find_time必须ban_time且封禁到期时间基于“窗口内最早一次失败 ban_time”调优时需结合真实登录频率封禁记录会一直保留在数据库中到期只是“失效”而非“删除”可通过authelia storage bans user list/authelia storage bans ip list定期审计必要时手动撤销Regulation 只统计 1FA 认证从 SQL 查询条件auth_type 1FA可以看出TOTP、WebAuthn 等第二因素的失败不计入封禁统计。七、相关源码与文档导航配置文档docs/content/configuration/security/regulation.md配置 Schema 与默认值internal/configuration/schema/regulation.go配置校验internal/configuration/validator/regulation.go、internal/configuration/validator/regulation_test.goRegulation 核心实现internal/regulation/regulator.go、internal/regulation/types.go、internal/regulation/const.go认证流程集成internal/handlers/handler_firstfactor_password.go、internal/handlers/response.go存储层结构与 SQLinternal/model/regulation.go、internal/storage/sql_provider_queries.go封禁管理命令internal/commands/storage.go、docs/content/reference/cli/authelia/authelia_storage_bans.md【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考