Guide how to limit users with mod_muc_max_occupants.lua

Thanks for persisting @Mohamed_Abada, here are the full prosody.log and jvb.log post prosody update.

The jicofo.log was too large for Gist! So I’ve uploaded a redacted version of it here.

I can’t say that I have had cause to regret my stay-current method, that is, use containers to get the ‘best’ flavour used for a particular server project. If I want to use a project using centos, I spin a Centos container. If I want to use a project using Ubuntu, I spin the latest Ubuntu container unless it’ too recent then I spin the previous LTS. Upgrading libraries by hand is a pain, even more to maintain. Learning to use containers is not as hard in the long run.

On a less metaphysical plane, working Prosody is listening on port 5280 and 5347 while your custom upgrade is not, it’s definitely a show stopper.

@danmaby in your prosody logs I can see the following :

> Jun 06 23:06:35 certmanager	error	SSL/TLS: Failed to load '/etc/prosody/certs/localhost.key': Check that the permissions allow Prosody to read this file. (for localhost)
> Jun 06 23:06:35 localhost:tls	error	Error creating context for c2s: error loading private key (Permission denied)
> Jun 06 23:06:35 certmanager	error	SSL/TLS: Failed to load '/etc/prosody/certs/localhost.key': Previous error (see logs), or other system error. (for localhost)
> Jun 06 23:06:35 localhost:tls	error	Error creating contexts for s2sout: error loading private key (system lib)
> Jun 06 23:06:35 certmanager	error	SSL/TLS: Failed to load '/etc/prosody/certs/localhost.key': Previous error (see logs), or other system error. (for localhost)
> Jun 06 23:06:35 localhost:tls	error	Error creating contexts for s2sin: error loading private key (system lib)

To fix the above you need to execute the below :

sudo chown prosody:prosody /etc/prosody/certs/ -R
sudo /etc/init.d/prosody restart
sudo /etc/init.d/jicofo restart
sudo /etc/init.d/jitsi-videobridge2 restart

Most likely this will mitegate the errors and exception you’re getting in Jicofo and JVB logs, if not then clear the logs of prosody, jicofo and JVBs as follwoing then share the logs again

sudo /etc/init.d/prosody stop
sudo /etc/init.d/jicofo stop
sudo /etc/init.d/jitsi-videobridge2 stop
sudo rm -rf /var/log/jitsi/*
sudo rm -rf /var/log/prosody/*
sudo /etc/init.d/prosody start
sudo /etc/init.d/jicofo start
sudo /etc/init.d/jitsi-videobridge2 start

You can also reach me privatly and we can troubleshoot this issue together.

Best Regards,
Mohamed Abada

@Mohamed_Abada and @gpatel-fr thank you both again.

I’ve made the changes you suggested Mohamed and these are the logs:

I’m not sure how to resolve this. I’ve tried adding component_ports = { 5347 } to prosody.cfg.lua

highly dubious that this could be a fix. Why don’t you post also prosody.err ? it’s clear that prosody don’t work, so jicofo and jvb are not likely to work anyway, but prosody.err may have more interesting info.

prosody.err is empty, which I thought was strange?

your prosody seems to be doing so little it can’t even throw a decent error.
Right, here is my prosody.conf

grep -v “--” prosody.cfg.lua | grep -v -e ‘^$’

admins = { }
modules_enabled = {
}
modules_disabled = {
}
allow_registration = false
daemonize = true;
pidfile = "/var/run/prosody/prosody.pid";
c2s_require_encryption = true
s2s_require_encryption = true
s2s_secure_auth = false
authentication = "internal_hashed"
log = {
	info = "/var/log/prosody/prosody.log";
	error = "/var/log/prosody/prosody.err";
	{ levels = { "error" }; to = "syslog";  };
}
certificates = "certs"
Include "conf.d/*.cfg.lua"

do you see a significant difference ?
is there only symbolic links in conf.d to files in conf.available ?

I can limit the number of users :pray:

@gpatel-fr this was my prosody.cfg.lua, I added Include "conf.d/*.cfg.lua" to the bottom of the file, restarted and was able to limit the users.

admins = { }
cross_domain_bosh = false;
component_ports = { 5347 }
modules_enabled = {
		"roster";
		"saslauth"; 
		"tls"; 
		"dialback"; 
		"disco"; 
		"carbons"; 
		"pep"; 
		"private"; 
		"blocklist";
		"vcard4"; 
		"vcard_legacy"; 
		"version"; 
		"uptime"; 
		"time"; 
		"ping"; 
		"register";
		"admin_adhoc";
}
modules_disabled = {
}
allow_registration = false
c2s_require_encryption = true
s2s_require_encryption = true
s2s_secure_auth = false
pidfile = "/var/run/prosody/prosody.pid"
authentication = "internal_hashed"
archive_expires_after = "1w"
log = {
	info = "/var/log/prosody/prosody.log";
	error = "/var/log/prosody/prosody.err";
}
certificates = "certs"
VirtualHost "localhost"

My prosody.err is still empty and there are errors in the console but it feels like progress! These are my jvb.log, jicofo.log and prosody.log following the successful limit of users.

In the jvb.log I’m seeing the following being reported every 10 seconds:

2020-06-07 16:06:15.672 INFO: [18] Videobridge.createConference#320: create_conf, id=b88b2478c2e8f036 gid=null logging=false
2020-06-07 16:06:15.679 INFO: [18] AbstractHealthCheckService.run#171: Performed a successful health check in PT0.007S. Sticky failure: false

why is this bothering you ? it’s an INFO message - FYI.
I have the same and I use standard Debian install.

Wasn’t sure if it was something to be concerned about with it reporting every 10 seconds. Thank you very much for all your assistance, and patients with me. First time really interacting with the community here and it’s been a very positive experience.

Hi @danmaby,

I’m also trying to enable mod_muc_max_occupants.lua, in my jitsi meet settings and still had no luck.
Here is my /etc/prosody/conf.avail/mydomain.org:
Component “conference.mydomain.org” “muc”
storage = “memory”
muc_max_occupants = 3
modules_enabled = {
“muc_meeting_id”;
“muc_domain_mapper”;
– “token_verification”;
“muc_max_occupants”;
}
admins = { “focus@mydomain.org” }
muc_room_locking = false
muc_room_default_public_jids = true

And here is the contents of mod_muc_max_occupants.lua in /usr/share/jitsi-meet/prosody-plugins:
– MUC Max Occupants
– Configuring muc_max_occupants will set a limit of the maximum number
– of participants that will be able to join in a room.
– Participants in muc_access_whitelist will not be counted for the
– max occupants value (values are jids like recorder@jitsi.meeet.example.com).
– This module is configured under the muc component that is used for jitsi-meet
local split_jid = require “util.jid”.split;
local st = require “util.stanza”;
local it = require “util.iterators”;

local whitelist = module:get_option_set(“muc_access_whitelist”);
local MAX_OCCUPANTS = module:get_option_number(“muc_max_occupants”, -1);

local function count_keys(t)
return it.count(it.keys(t));
end

local function check_for_max_occupants(event)
local room, origin, stanza = event.room, event.origin, event.stanza;

    local actor = stanza.attr.from;

local user, domain, res = split_jid(stanza.attr.from);

–no user object means no way to check for max occupants
if user == nil then
return
end
– If we’re a whitelisted user joining the room, don’t bother checking the max
– occupants.
if whitelist and whitelist:contains(domain) or whitelist:contains(user…’@’…domain) then
return;
end

    if room and not room._jid_nick[stanza.attr.from] then
            local count = count_keys(room._occupants);
            local slots = MAX_OCCUPANTS;

            -- If there is no whitelist, just check the count.
            if not whitelist and count >= MAX_OCCUPANTS then
                    module:log("info", "Attempt to enter a maxed out MUC");
                    origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
                    return true;
            end

            -- TODO: Are Prosody hooks atomic, or is this a race condition?
            -- For each person in the room that's not on the whitelist, subtract one
            -- from the count.
            for _, occupant in room:each_occupant() do
                    user, domain, res = split_jid(occupant.bare_jid);
                    if not whitelist:contains(domain) and not whitelist:contains(user..'@'..domain) then
                            slots = slots - 1
                    end
            end

            -- If the room is full (<0 slots left), error out.
            if slots <= 0 then
                    module:log("info", "Attempt to enter a maxed out MUC");
                    origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
                    return true;
            end
    end

end

if MAX_OCCUPANTS > 0 then
module:hook(“muc-occupant-pre-join”, check_for_max_occupants, 3);
end

I’ve already set check_for_max_occupants, 3 the default value is 10 and i’ve already update prosody version to: 11.5.

Here is the content of the log files:

  • prosody.err:
    Jun 30 08:45:30 c2s55facaaf2760 error Traceback[c2s]: …are/jitsi-meet/prosody-plugins/mod_muc_max_occupants.lua:30: attempt to index upvalue ‘whitelist’ (a nil value)
    stack traceback:
    …are/jitsi-meet/prosody-plugins/mod_muc_max_occupants.lua:30: in function ‘?’
    /usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
    (…tail calls…)
    /usr/lib/prosody/modules/muc/muc.lib.lua:561: in function </usr/lib/prosody/modules/muc/muc.lib.lua:498>
    (…tail calls…)
    /usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
    (…tail calls…)
    /usr/lib/prosody/core/stanza_router.lua:180: in function ‘core_post_stanza’
    /usr/lib/prosody/core/stanza_router.lua:127: in function ‘core_process_stanza’
    /usr/lib/prosody/modules/mod_c2s.lua:275: in function ‘func’
    /usr/lib/prosody/util/async.lua:127: in function </usr/lib/prosody/util/async.lua:125>

  • prosody.log:
    Jun 30 08:45:17 bosh7dfaee98-c39a-4c64-8642-cff0074ebba6 info BOSH client disconnected: session close
    Jun 30 08:45:30 c2s55facaaf2760 error Traceback[c2s]: …are/jitsi-meet/prosody-plugins/mod_muc_max_occupants.lua:30: attempt to index upvalue ‘whitelist’ (a nil value)
    stack traceback:
    …are/jitsi-meet/prosody-plugins/mod_muc_max_occupants.lua:30: in function ‘?’
    /usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
    (…tail calls…)
    /usr/lib/prosody/modules/muc/muc.lib.lua:561: in function </usr/lib/prosody/modules/muc/muc.lib.lua:498>
    (…tail calls…)
    /usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
    (…tail calls…)
    /usr/lib/prosody/core/stanza_router.lua:180: in function ‘core_post_stanza’
    /usr/lib/prosody/core/stanza_router.lua:127: in function ‘core_process_stanza’
    /usr/lib/prosody/modules/mod_c2s.lua:275: in function ‘func’
    /usr/lib/prosody/util/async.lua:127: in function </usr/lib/prosody/util/async.lua:125>

Could anyone give some advices regarding this problem? :pray:

Thanks