Configuring ejabberd multi-user chatrooms

February 12, 2021 

Ejabberd is a very flexible and scalable XMPP server. We use it because it can be configured using a simple yaml configuration file and managed via ejabberdctl commands. This makes it a good fit for our infrastructure as code approach. That said, ejabberd does require one to understand the XMPP protocol/jargon as it does not abstract away any of it. So simple things like creating chatrooms, limiting access to them and playing history backlog to users who connected them can be an effort if you've never done it.

Ejabberd is very modular. To get an idea check the Module options page. Almost everything is a module, including multi-user chatroom support, which handled by mod_muc. To configure room options with ejabberdctl (e.g. make a room "members_only") you also need mod_muc_admin.

Access to the multi-user chat feature can be limited to certain users using mod_muc's access options that utilize access rules. These access controls are global so if a user is not in the allow list he/she will not have any access to any chat rooms on the server.

Multi-user chat room have a set of room options. These are documented well in the mod_muc documentation under "default room options" which get inherited by every new room. Changes made to default room options will not propagate to existing rooms, though.

In our case we wanted to have one public room and one private "members only" room where users were explicitly "affiliated" with the room. With the default ejabberd settings creating a public room is quite trivial:

ejabberdctl create-room public

To create a private (members only) room more work is needed. First get a list of users on your XMPP server (cluster):

ejabberdctl registered_users

Create the room:

ejabberdctl create-room private

Make the room members only:

ejabberdctl change_room_option private members_only true

Add members to the room:

ejabberdctl set_room_affiliation private [email protected] member
ejabberdctl set_room_affiliation private [email protected] member

Now poor Han Solo will not be able to join this "Jedi-only" room.

ejabberdctl get_room_affiliations private
luke.skywalker        member
obiwan.kenobi        member
yoda          owner

The creator of the room, here "yoda", is allowed access automatically. It seems that ejabberdctl makes the local system user the room was created as the room owner.

At this point it makes sense to verify the room options:

ejabberdctl get_room_options private

Cross-reference the options against mod_muc's default_room_options documentation to make sure everything is configured as you wish.

You may also want to make your rooms persistent, so that they don't get destroyed even if all members disconnect:

ejabberdctl change_room_option public persistent true
ejabberdctl change_room_option private persistent true

For a full list of multi-user chat admin commands refer to muc_admin documentation.

Samuli Seppänen
Samuli Seppänen
Author archive