Annotate

plugins/mod_register_limits.lua @ 13721:8170dd8f370c

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Sun, 16 Feb 2025 13:44:23 +0000
parent 13213:50324f66ca2a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
12977
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11807
diff changeset
10 local create_throttle = require "prosody.util.throttle".create;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11807
diff changeset
11 local new_cache = require "prosody.util.cache".new;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11807
diff changeset
12 local ip_util = require "prosody.util.ip";
8452
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
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: 8194
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: 8194
diff changeset
15 local parse_cidr = ip_util.parse_cidr;
12977
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11807
diff changeset
16 local errors = require "prosody.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
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
18 -- COMPAT drop old option names
13209
c8d949cf6b09 plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents: 12977
diff changeset
19 local min_seconds_between_registrations = module:get_option_period("min_seconds_between_registrations");
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
20 local allowlist_only = module:get_option_boolean("allowlist_registration_only", module:get_option_boolean("whitelist_registration_only"));
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
21 local allowlisted_ips = module:get_option_set("registration_allowlist", module:get_option("registration_whitelist", { "127.0.0.1", "::1" }))._items;
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
22 local blocklisted_ips = module:get_option_set("registration_blocklist", 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
23
13213
50324f66ca2a plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
24 local throttle_max = module:get_option_number("registration_throttle_max", min_seconds_between_registrations and 1, 0);
13209
c8d949cf6b09 plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents: 12977
diff changeset
25 local throttle_period = module:get_option_period("registration_throttle_period", min_seconds_between_registrations);
13213
50324f66ca2a plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
26 local throttle_cache_size = module:get_option_integer("registration_throttle_cache_size", 100, 1);
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
27 local blocklist_overflow = module:get_option_boolean("blocklist_on_registration_throttle_overload",
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
28 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
29
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
30 local throttle_cache = new_cache(throttle_cache_size, blocklist_overflow and function (ip, throttle)
7027
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: 7026
diff changeset
31 if not throttle:peek() then
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
32 module:log("info", "Adding ip %s to registration blocklist", ip);
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
33 blocklisted_ips[ip] = true;
7027
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: 7026
diff changeset
34 end
7293
c4af754d1e1b mod_register: Make sure only an on_evict function or nil is passed to util.cache
Kim Alvefur <zash@zash.se>
parents: 7037
diff changeset
35 end or nil);
7025
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7018
diff changeset
36
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7018
diff changeset
37 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: 7018
diff changeset
38 if not throttle_max then return true end
7026
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7025
diff changeset
39 local throttle = throttle_cache:get(ip);
7025
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7018
diff changeset
40 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: 7018
diff changeset
41 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: 7018
diff changeset
42 end
7026
f0dc5cc11d0e mod_register: Use util.cache to limit the number of per-ip throttles kept
Kim Alvefur <zash@zash.se>
parents: 7025
diff changeset
43 throttle_cache:set(ip, throttle);
7025
236e8d1ee96c mod_register: Switch to using util.throttle for limiting registrations per ip per time
Kim Alvefur <zash@zash.se>
parents: 7018
diff changeset
44 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: 7018
diff changeset
45 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
46
8452
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
47 local function ip_in_set(set, ip)
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
48 if set[ip] then
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
49 return true;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
50 end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
51 ip = new_ip(ip);
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
52 for in_set in pairs(set) do
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
53 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: 8194
diff changeset
54 return true;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
55 end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
56 end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
57 return false;
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
58 end
4796fdcb7146 mod_register: Support CIDR notation in white-/blacklists (closes #941)
Kim Alvefur <zash@zash.se>
parents: 8194
diff changeset
59
10364
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
60 local err_registry = {
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
61 blocklisted = {
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
62 text = "Your IP address is blocklisted";
10364
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
63 type = "auth";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
64 condition = "forbidden";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
65 };
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
66 not_allowlisted = {
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
67 text = "Your IP address is not allowlisted";
10364
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
68 type = "auth";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
69 condition = "forbidden";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
70 };
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
71 throttled = {
10768
55a9e9bf6abb mod_register_limits: Fix text reason field name for 'throttled'
Kim Alvefur <zash@zash.se>
parents: 10766
diff changeset
72 text = "Too many registrations from this IP address recently";
10364
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
73 type = "wait";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
74 condition = "policy-violation";
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
75 };
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
76 }
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
77
8485
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8484
diff changeset
78 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: 8484
diff changeset
79 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: 8484
diff changeset
80 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: 8484
diff changeset
81 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: 8484
diff changeset
82 if not ip then
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
83 log("warn", "IP not known; can't apply blocklist/allowlist");
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
84 elseif ip_in_set(blocklisted_ips, ip) then
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
85 log("debug", "Registration disallowed by blocklist");
8585
046041a37c1e mod_register_limits: Log message for white- and blacklist hits separate
Kim Alvefur <zash@zash.se>
parents: 8584
diff changeset
86 event.allowed = false;
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
87 event.error = errors.new("blocklisted", event, err_registry);
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
88 elseif (allowlist_only and not ip_in_set(allowlisted_ips, ip)) then
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
89 log("debug", "Registration disallowed by allowlist");
8485
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8484
diff changeset
90 event.allowed = false;
11807
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
91 event.error = errors.new("not_allowlisted", event, err_registry);
f5295e59ca78 mod_register_limits: Reword some options
Kim Alvefur <zash@zash.se>
parents: 10768
diff changeset
92 elseif throttle_max and not ip_in_set(allowlisted_ips, ip) then
8738
9f0dc1bbc83b mod_register_limits: Use existing local variable
Kim Alvefur <zash@zash.se>
parents: 8586
diff changeset
93 if not check_throttle(ip) then
8485
0e02c6de5c02 mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Kim Alvefur <zash@zash.se>
parents: 8484
diff changeset
94 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: 8484
diff changeset
95 event.allowed = false;
10766
00d2a577204c mod_register_limits: Fix typo error name (fix #1539 p2) (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 10765
diff changeset
96 event.error = errors.new("throttled", event, err_registry);
60
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
97 end
3529
3f9cc12308aa mod_register: Updated to use the new events API.
Waqas Hussain <waqas20@gmail.com>
parents: 3394
diff changeset
98 end
10364
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
99 if event.error then
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
100 -- COMPAT pre-util.error
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
101 event.reason = event.error.text;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
102 event.error_type = event.error.type;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
103 event.error_condition = event.error.condition;
66943afdd7f3 mod_register_limits: Use util.error for managing rejection reasons
Kim Alvefur <zash@zash.se>
parents: 10286
diff changeset
104 end
60
44800be871f5 User registration, etc (jabber:iq:register)
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
105 end);