mod_limit_auth/mod_limit_auth.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 14 Jan 2023 14:31:37 +0000
changeset 5153 fa56ed2bacab
parent 1945 2a5a44d5b935
permissions -rw-r--r--
mod_unified_push: Add support for multiple token backends, including stoage Now that we have ACLs by default, it is no longer necessary to be completely stateless. On 0.12, using storage has benefits over JWT, because it does not expose client JIDs to the push apps/services. In trunk, PASETO is stateless and does not expose client JIDs.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1583
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- mod_limit_auth
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local st = require"util.stanza";
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local new_throttle = require "util.throttle".create;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local period = math.max(module:get_option_number(module.name.."_period", 30), 0);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local max = math.max(module:get_option_number(module.name.."_max", 5), 1);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local tarpit_delay = module:get_option_number(module.name.."_tarpit_delay", nil);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
if tarpit_delay then
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	local waiter = require "util.async".waiter;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
	local delay = tarpit_delay;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
	function tarpit_delay()
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
		local wait, done = waiter();
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
		module:add_timer(delay, done);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
		wait();
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
	end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
else
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	function tarpit_delay() end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
local throttles = module:shared"throttles";
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
local reply = st.stanza("failure", { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):tag("temporary-auth-failure");
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
local function get_throttle(ip)
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
	local throttle = throttles[ip];
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	if not throttle then
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
		throttle = new_throttle(max, period);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
		throttles[ip] = throttle;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
	end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	return throttle;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function (event)
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	local origin = event.origin;
1945
2a5a44d5b935 mod_limit_auth: Only apply limit to normal c2s sessions (thanks cuc)
Kim Alvefur <zash@zash.se>
parents: 1858
diff changeset
    37
	if origin.type ~= "c2s_unauthed" then return end
1583
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
	if not get_throttle(origin.ip):peek(1) then
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
		origin.log("warn", "Too many authentication attepmts for ip %s", origin.ip);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
		tarpit_delay();
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
		origin.send(reply);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
		return true;
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
	end
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
end, 10);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
module:hook("authentication-failure", function (event)
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	get_throttle(event.session.ip):poll(1);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
end);
c1bb2a64aabb mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
1858
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    50
module:add_timer(14400, function (now)
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    51
	local old = now - 86400;
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    52
	for ip, throttle in pairs(throttles) do
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    53
		if throttle.t < old then
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    54
			throttles[ip] = nil;
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    55
		end
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    56
	end
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    57
end);
450ada5bb1b5 mod_limit_auth: Get rid of old inactive throttle objects
Kim Alvefur <zash@zash.se>
parents: 1583
diff changeset
    58