Annotate

mod_audit/mod_audit.lua @ 5296:0f5657db1cfc

mod_isolate_host: handle server-generated stanzas The hook for setting the no_host_isolation is only called for c2s sessions. This does not work for stanzas generated by the server, such as PEP notifications or presence probe answers. To handle that, we do per-stanza checks for the case that the origin is local.
author Jonas Schäfer <jonas@wielicki.name>
date Sat, 01 Apr 2023 12:03:08 +0200
parent 5251:f3123cbbd894
child 5298:12f7d8b901e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
1 module:set_global();
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
2
5115
4a5837591380 mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents: 4934
diff changeset
3 local audit_log_limit = module:get_option_number("audit_log_limit", 10000);
4a5837591380 mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents: 4934
diff changeset
4 local cleanup_after = module:get_option_string("audit_log_expires_after", "2w");
4a5837591380 mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents: 4934
diff changeset
5
5251
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
6 local attach_ips = module:get_option_boolean("audit_log_ips", true);
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
7 local attach_ipv4_prefix = module:get_option_number("audit_log_ipv4_prefix", nil);
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
8 local attach_ipv6_prefix = module:get_option_number("audit_log_ipv6_prefix", nil);
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
9
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
10 local time_now = os.time;
5251
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
11 local ip = require "util.ip";
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
12 local st = require "util.stanza";
4934
ae83200fb55f mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents: 4933
diff changeset
13 local moduleapi = require "core.moduleapi";
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
14
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
15 local host_wide_user = "@";
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
16
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
17 local stores = {};
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
18
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
19 local function get_store(self, host)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
20 local store = rawget(self, host);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
21 if store then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
22 return store
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
23 end
4933
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4932
diff changeset
24 store = module:context(host):open_store("audit", "archive");
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
25 rawset(self, host, store);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
26 return store;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
27 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
28
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
29 setmetatable(stores, { __index = get_store });
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
30
5251
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
31 local function get_ip_network(ip_addr)
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
32 local _ip = ip.new_ip(ip_addr);
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
33 local proto = _ip.proto;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
34 local network;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
35 if proto == "IPv4" and attach_ipv4_prefix then
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
36 network = ip.truncate(_ip, attach_ipv4_prefix).normal.."/"..attach_ipv4_prefix;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
37 elseif proto == "IPv6" and attach_ipv6_prefix then
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
38 network = ip.truncate(_ip, attach_ipv6_prefix).normal.."/"..attach_ipv6_prefix;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
39 end
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
40 return network;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
41 end
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
42
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
43 local function session_extra(session)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
44 local attr = {
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
45 xmlns = "xmpp:prosody.im/audit",
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
46 };
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
47 if session.id then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
48 attr.id = session.id;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
49 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
50 if session.type then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
51 attr.type = session.type;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
52 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
53 local stanza = st.stanza("session", attr);
5251
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
54 if attach_ips and session.ip then
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
55 local remote_ip, network = session.ip;
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
56 if attach_ipv4_prefix or attach_ipv6_prefix then
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
57 network = get_ip_network(remote_ip);
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
58 end
f3123cbbd894 mod_audit: Allow disabling IP logging, or limiting it to a prefix
Matthew Wild <mwild1@gmail.com>
parents: 5250
diff changeset
59 stanza:text_tag("remote-ip", network or remote_ip);
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
60 end
5250
d9577083c5f5 mod_audit: Include client id in audit log entries (if known)
Matthew Wild <mwild1@gmail.com>
parents: 5115
diff changeset
61 if session.client_id then
d9577083c5f5 mod_audit: Include client id in audit log entries (if known)
Matthew Wild <mwild1@gmail.com>
parents: 5115
diff changeset
62 stanza:text_tag("client", session.client_id);
d9577083c5f5 mod_audit: Include client id in audit log entries (if known)
Matthew Wild <mwild1@gmail.com>
parents: 5115
diff changeset
63 end
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
64 return stanza
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
65 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
66
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
67 local function audit(host, user, source, event_type, extra)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
68 if not host or host == "*" then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
69 error("cannot log audit events for global");
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
70 end
4933
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4932
diff changeset
71 local user_key = user or host_wide_user;
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
72
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
73 local attr = {
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
74 ["source"] = source,
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
75 ["type"] = event_type,
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
76 };
4933
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4932
diff changeset
77 if user_key ~= host_wide_user then
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4932
diff changeset
78 attr.user = user_key;
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
79 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
80 local stanza = st.stanza("audit-event", attr);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
81 if extra ~= nil then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
82 if extra.session then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
83 local child = session_extra(extra.session);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
84 if child then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
85 stanza:add_child(child);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
86 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
87 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
88 if extra.custom then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
89 for _, child in extra.custom do
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
90 if not st.is_stanza(child) then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
91 error("all extra.custom items must be stanzas")
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
92 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
93 stanza:add_child(child);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
94 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
95 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
96 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
97
4933
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4932
diff changeset
98 local id, err = stores[host]:append(nil, nil, stanza, time_now(), user_key);
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
99 if err then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
100 module:log("error", "failed to persist audit event: %s", err);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
101 return
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
102 else
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
103 module:log("debug", "persisted audit event %s as %s", stanza:top_tag(), id);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
104 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
105 end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
106
4934
ae83200fb55f mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents: 4933
diff changeset
107 function moduleapi.audit(module, user, event_type, extra)
ae83200fb55f mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents: 4933
diff changeset
108 audit(module.host, user, "mod_" .. module:get_name(), event_type, extra);
4932
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
109 end