Software / code / prosody
Annotate
plugins/mod_register_limits.lua @ 13801:a5d5fefb8b68 13.0
mod_tls: Enable Prosody's certificate checking for incoming s2s connections (fixes #1916) (thanks Damian, Zash)
Various options in Prosody allow control over the behaviour of the certificate
verification process For example, some deployments choose to allow falling
back to traditional "dialback" authentication (XEP-0220), while others verify
via DANE, hard-coded fingerprints, or other custom plugins.
Implementing this flexibility requires us to override OpenSSL's default
certificate verification, to allow Prosody to verify the certificate itself,
apply custom policies and make decisions based on the outcome.
To enable our custom logic, we have to suppress OpenSSL's default behaviour of
aborting the connection with a TLS alert message. With LuaSec, this can be
achieved by using the verifyext "lsec_continue" flag.
We also need to use the lsec_ignore_purpose flag, because XMPP s2s uses server
certificates as "client" certificates (for mutual TLS verification in outgoing
s2s connections).
Commit 99d2100d2918 moved these settings out of the defaults and into mod_s2s,
because we only really need these changes for s2s, and they should be opt-in,
rather than automatically applied to all TLS services we offer.
That commit was incomplete, because it only added the flags for incoming
direct TLS connections. StartTLS connections are handled by mod_tls, which was
not applying the lsec_* flags. It previously worked because they were already
in the defaults.
This resulted in incoming s2s connections with "invalid" certificates being
aborted early by OpenSSL, even if settings such as `s2s_secure_auth = false`
or DANE were present in the config.
Outgoing s2s connections inherit verify "none" from the defaults, which means
OpenSSL will receive the cert but will not terminate the connection when it is
deemed invalid. This means we don't need lsec_continue there, and we also
don't need lsec_ignore_purpose (because the remote peer is a "server").
Wondering why we can't just use verify "none" for incoming s2s? It's because
in that mode, OpenSSL won't request a certificate from the peer for incoming
connections. Setting verify "peer" is how you ask OpenSSL to request a
certificate from the client, but also what triggers its built-in verification.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 01 Apr 2025 17:26:56 +0100 |
| parent | 13213:50324f66ca2a |
| 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 | 5 -- This project is MIT/X11 licensed. Please see the |
| 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); |