plugins/mod_register_limits.lua
author Kim Alvefur <zash@zash.se>
Thu, 23 Apr 2020 19:00:48 +0200
changeset 10770 00d2a577204c
parent 10769 294923f45e25
child 10772 55a9e9bf6abb
permissions -rw-r--r--
mod_register_limits: Fix typo error name (fix #1539 p2) (thanks Ge0rG) Probably because autocomplete.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 1189
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2448
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2448
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5763
diff changeset
     4
--
758
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 691
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 691
diff changeset
     6
-- COPYING file in the source package for more information.
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
     7
--
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
     8
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
     9
7028
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    10
local create_throttle = require "util.throttle".create;
7029
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7028
diff changeset
    11
local new_cache = require "util.cache".new;
8455
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    12
local ip_util = require "util.ip";
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    13
local new_ip = ip_util.new_ip;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    14
local match_ip = ip_util.match;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    15
local parse_cidr = ip_util.parse_cidr;
10368
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    16
local errors = require "util.error";
3995
e504b06492c6 mod_register: Add registration_compat config option to allow account remove requests addressed to='host' (defaults to true)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
    17
5763
0e52f1d5ca71 mod_register: Use more specific get_option variants
Kim Alvefur <zash@zash.se>
parents: 5707
diff changeset
    18
local min_seconds_between_registrations = module:get_option_number("min_seconds_between_registrations");
0e52f1d5ca71 mod_register: Use more specific get_option variants
Kim Alvefur <zash@zash.se>
parents: 5707
diff changeset
    19
local whitelist_only = module:get_option_boolean("whitelist_registration_only");
8186
49a682d6b427 mod_register: Add ::1 to the default registration_whitelist.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8073
diff changeset
    20
local whitelisted_ips = module:get_option_set("registration_whitelist", { "127.0.0.1", "::1" })._items;
5763
0e52f1d5ca71 mod_register: Use more specific get_option variants
Kim Alvefur <zash@zash.se>
parents: 5707
diff changeset
    21
local blacklisted_ips = module:get_option_set("registration_blacklist", {})._items;
690
e901a0709005 Added rate limiting to in-band registration, and added IP [black/white]lists
Matthew Wild <mwild1@gmail.com>
parents: 665
diff changeset
    22
7028
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    23
local throttle_max = module:get_option_number("registration_throttle_max", min_seconds_between_registrations and 1);
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    24
local throttle_period = module:get_option_number("registration_throttle_period", min_seconds_between_registrations);
7029
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7028
diff changeset
    25
local throttle_cache_size = module:get_option_number("registration_throttle_cache_size", 100);
7040
5d52e4ee2ae1 mod_register: Fix typo
Kim Alvefur <zash@zash.se>
parents: 7030
diff changeset
    26
local blacklist_overflow = module:get_option_boolean("blacklist_on_registration_throttle_overload", false);
690
e901a0709005 Added rate limiting to in-band registration, and added IP [black/white]lists
Matthew Wild <mwild1@gmail.com>
parents: 665
diff changeset
    27
7030
77d838ba91c6 mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache
Kim Alvefur <zash@zash.se>
parents: 7029
diff changeset
    28
local throttle_cache = new_cache(throttle_cache_size, blacklist_overflow and function (ip, throttle)
77d838ba91c6 mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache
Kim Alvefur <zash@zash.se>
parents: 7029
diff changeset
    29
	if not throttle:peek() then
77d838ba91c6 mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache
Kim Alvefur <zash@zash.se>
parents: 7029
diff changeset
    30
		module:log("info", "Adding ip %s to registration blacklist", ip);
77d838ba91c6 mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache
Kim Alvefur <zash@zash.se>
parents: 7029
diff changeset
    31
		blacklisted_ips[ip] = true;
77d838ba91c6 mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache
Kim Alvefur <zash@zash.se>
parents: 7029
diff changeset
    32
	end
7296
c4af754d1e1b mod_register: Make sure only an on_evict function or nil is passed to util.cache
Kim Alvefur <zash@zash.se>
parents: 7040
diff changeset
    33
end or nil);
7028
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    34
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    35
local function check_throttle(ip)
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    36
	if not throttle_max then return true end
7029
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7028
diff changeset
    37
	local throttle = throttle_cache:get(ip);
7028
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    38
	if not throttle then
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    39
		throttle = create_throttle(throttle_max, throttle_period);
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    40
	end
7029
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7028
diff changeset
    41
	throttle_cache:set(ip, throttle);
7028
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    42
	return throttle:poll(1);
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7021
diff changeset
    43
end
690
e901a0709005 Added rate limiting to in-band registration, and added IP [black/white]lists
Matthew Wild <mwild1@gmail.com>
parents: 665
diff changeset
    44
8455
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    45
local function ip_in_set(set, ip)
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    46
	if set[ip] then
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    47
		return true;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    48
	end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    49
	ip = new_ip(ip);
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    50
	for in_set in pairs(set) do
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    51
		if match_ip(ip, parse_cidr(in_set)) then
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    52
			return true;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    53
		end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    54
	end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    55
	return false;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    56
end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8197
diff changeset
    57
10368
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    58
local err_registry = {
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    59
	blacklisted = {
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    60
		text = "Your IP address is blacklisted";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    61
		type = "auth";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    62
		condition = "forbidden";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    63
	};
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    64
	not_whitelisted = {
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    65
		text = "Your IP address is not whitelisted";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    66
		type = "auth";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    67
		condition = "forbidden";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    68
	};
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    69
	throttled = {
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    70
		reason = "Too many registrations from this IP address recently";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    71
		type = "wait";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    72
		condition = "policy-violation";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    73
	};
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    74
}
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    75
8488
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    76
module:hook("user-registering", function (event)
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    77
	local session = event.session;
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    78
	local ip = event.ip or session and session.ip;
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    79
	local log = session and session.log or module._log;
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    80
	if not ip then
8743
5dc8f509496c mod_register_limits: Promote log message about inability to apply black/whitelists to a warning
Kim Alvefur <zash@zash.se>
parents: 8742
diff changeset
    81
		log("warn", "IP not known; can't apply blacklist/whitelist");
8741
9f0dc1bbc83b mod_register_limits: Use existing local variable
Kim Alvefur <zash@zash.se>
parents: 8589
diff changeset
    82
	elseif ip_in_set(blacklisted_ips, ip) then
8588
046041a37c1e mod_register_limits: Log message for white- and blacklist hits separate
Kim Alvefur <zash@zash.se>
parents: 8587
diff changeset
    83
		log("debug", "Registration disallowed by blacklist");
046041a37c1e mod_register_limits: Log message for white- and blacklist hits separate
Kim Alvefur <zash@zash.se>
parents: 8587
diff changeset
    84
		event.allowed = false;
10769
294923f45e25 mod_register_limits: Fix order of arguments to util.error (fix #1539 p1) (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 10368
diff changeset
    85
		event.error = errors.new("blacklisted", event, err_registry);
8588
046041a37c1e mod_register_limits: Log message for white- and blacklist hits separate
Kim Alvefur <zash@zash.se>
parents: 8587
diff changeset
    86
	elseif (whitelist_only and not ip_in_set(whitelisted_ips, ip)) then
046041a37c1e mod_register_limits: Log message for white- and blacklist hits separate
Kim Alvefur <zash@zash.se>
parents: 8587
diff changeset
    87
		log("debug", "Registration disallowed by whitelist");
8488
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    88
		event.allowed = false;
10769
294923f45e25 mod_register_limits: Fix order of arguments to util.error (fix #1539 p1) (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 10368
diff changeset
    89
		event.error = errors.new("not_whitelisted", event, err_registry);
8488
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    90
	elseif throttle_max and not ip_in_set(whitelisted_ips, ip) then
8741
9f0dc1bbc83b mod_register_limits: Use existing local variable
Kim Alvefur <zash@zash.se>
parents: 8589
diff changeset
    91
		if not check_throttle(ip) then
8488
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    92
			log("debug", "Registrations over limit for ip %s", ip or "?");
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8487
diff changeset
    93
			event.allowed = false;
10770
00d2a577204c mod_register_limits: Fix typo error name (fix #1539 p2) (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 10769
diff changeset
    94
			event.error = errors.new("throttled", event, err_registry);
60
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    95
		end
3529
3f9cc12308aa mod_register: Updated to use the new events API.
Waqas Hussain <waqas20@gmail.com>
parents: 3394
diff changeset
    96
	end
10368
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    97
	if event.error then
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    98
		-- COMPAT pre-util.error
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
    99
		event.reason = event.error.text;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
   100
		event.error_type = event.error.type;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
   101
		event.error_condition = event.error.condition;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10290
diff changeset
   102
	end
60
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   103
end);