plugin/antibrute: exclude
Massimo Melina committed
Feb 16, 2026 at 12:11 UTC
86ac04265f8d46f25af9ffdfc9f4262a8c475506
1 file changed
+14
-3
plugins/antibrute/plugin.js
+14
-3
@@ -1,4 +1,4 @@
1
-exports.version = 3
1
+exports.version = 3.1
2
exports.description = "Introduce increasing delays between login attempts."
3
exports.apiRequired = 9.6 // addBlock
4
@@ -7,6 +7,7 @@ exports.config = {
7
max: { type: 'number', min: 1, defaultValue: 60, label: "Max delay", unit: "seconds", helperText: "Max seconds to delay before next login is allowed" },
8
blockAfter: { type: 'number', xs: 6, min: 1, max: 9999, defaultValue: 100, label: "Block IP after", unit: "attempts", helperText: "localhost excluded" },
9
blockForHours: { type: 'number', xs: 6, min: 0, defaultValue: 24, label: "Block for", unit: "hours" },
10
+ exclude: { type: 'string', defaultValue: '', label: "Exclude IPs", helperText: "Net mask syntax" },
11
}
12
exports.configDialog = {
13
maxWidth: 'xs',
@@ -15,7 +16,7 @@ exports.configDialog = {
16
const byIp = {}
17
18
exports.init = api => {
18
- const { isLocalHost, HOUR } = api.misc
19
+ const { isLocalHost, HOUR, netMatches } = api.misc
20
api.events.multi({
21
async attemptingLogin({ ctx }) {
22
const { ip } = ctx
@@ -25,7 +26,7 @@ exports.init = api => {
26
const delay = Math.min(max, 1000 * api.getConfig('increment') * ++rec.attempts)
27
const wait = rec.next - now
28
rec.next = new Date(+rec.next + delay)
28
- if (rec.attempts > api.getConfig('blockAfter') && !isLocalHost(ctx)) {
29
+ if (rec.attempts > api.getConfig('blockAfter') && !isLocalHost(ctx) && !isExcluded(ip)) {
30
const hours = api.getConfig('blockForHours')
31
api.addBlock({ ip, comment: "From antibrute plugin", expire: hours ? new Date(now.getTime() + hours * HOUR) : undefined })
32
}
@@ -42,4 +43,14 @@ exports.init = api => {
43
delete byIp[ctx.ip] // reset if login was successful
44
}
45
})
46
+
47
+ function isExcluded(ip) {
48
+ const mask = api.getConfig('exclude')
49
+ if (!mask) return false
50
+ try { return netMatches(ip, mask) }
51
+ catch (e) {
52
+ api.log("bad exclude mask:", String(e))
53
+ return false
54
+ }
55
+ }
56
}