From fbf51418ad2b9f2086195b5ee80e46db170fcc77 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Mon, 21 Sep 2015 15:31:35 +0200 Subject: [PATCH] MT#15303 add mod_limit_auth http://modules.prosody.im/mod_limit_auth.html limit_auth_period = 30 -- over 30 seconds limit_auth_max = 5 -- tolerate no more than 5 failed attempts Change-Id: I44932d643f124991948a26c2d80c8b40a9c155d2 (cherry picked from commit f672d8e3ecd675b9d3395fc74a17a14ab506b93a) --- plugins/mod_limit_auth.lua | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 plugins/mod_limit_auth.lua diff --git a/plugins/mod_limit_auth.lua b/plugins/mod_limit_auth.lua new file mode 100644 index 0000000..00981fb --- /dev/null +++ b/plugins/mod_limit_auth.lua @@ -0,0 +1,57 @@ +-- mod_limit_auth + +local st = require"util.stanza"; +local new_throttle = require "util.throttle".create; + +local period = math.max(module:get_option_number(module.name.."_period", 30), 0); +local max = math.max(module:get_option_number(module.name.."_max", 5), 1); + +local tarpit_delay = module:get_option_number(module.name.."_tarpit_delay", nil); +if tarpit_delay then + local waiter = require "util.async".waiter; + local delay = tarpit_delay; + function tarpit_delay() + local wait, done = waiter(); + module:add_timer(delay, done); + wait(); + end +else + function tarpit_delay() end +end + +local throttles = module:shared"throttles"; + +local reply = st.stanza("failure", { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):tag("temporary-auth-failure"); + +local function get_throttle(ip) + local throttle = throttles[ip]; + if not throttle then + throttle = new_throttle(max, period); + throttles[ip] = throttle; + end + return throttle; +end + +module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function (event) + local origin = event.origin; + if not get_throttle(origin.ip):peek(1) then + origin.log("warn", "Too many authentication attepmts for ip %s", origin.ip); + tarpit_delay(); + origin.send(reply); + return true; + end +end, 10); + +module:hook("authentication-failure", function (event) + get_throttle(event.session.ip):poll(1); +end); + +module:add_timer(14400, function (now) + local old = now - 86400; + for ip, throttle in pairs(throttles) do + if throttle.t < old then + throttles[ip] = nil; + end + end +end); +