Difference between revisions of "Prosody"

From Organic Design wiki
(SSL certificates: https)
(See also: Experimental OMEMO plugin for Pidgin)
 
(35 intermediate revisions by the same user not shown)
Line 1: Line 1:
[https://prosody.im Prosody] is a light-weight, easy to configure, [[XMPP]] server. XMPP is an open and extensible Internet protocol used for communications, presence, identification, authentication etc. It's a big part of the [[Semantic Web]] movement which is all about achieving the functionality we need using open standards instead of specific applications.
+
[https://prosody.im Prosody] is a light-weight, easy to configure, [[XMPP]] server. XMPP is an open and extensible Internet protocol used for communications, presence, identification, authentication etc. It's a big part of the [[Semantic Web]] movement which is all about achieving the functionality we need using open standards instead of specific applications. It's important to remember that even an application that is entirely [[libre software]] can still be a kind of "walled garden" if the application's functionality is not built on top of a common open standard. Any number of things can go wrong such as the author retiring or selling out, the development moving in an undesired direction etc, and these problems mean that you're stranded if you rely on that particular application for your operations.
  
 
== Configuration ==
 
== Configuration ==
The ''prosody'' configuration is in ''/etc/prosody'' with a similar style to ''Apache'' or ''Nginx'' where individual site's configuration each exist in their own file in the ''conf.avail'' sub-directory usually having a filename matching the domain name. Sites are then enabled by creating sym-links in the ''conf.d'' sub-directory pointing to the available sites.
+
The ''prosody'' configuration is in ''/etc/prosody'' and all the data is stored in ''/var/lib/prosody''. The configuration style is similar to popular web-servers where individual site's configuration each exist in their own file in the ''conf.avail'' sub-directory usually having a filename matching the domain name. Sites are then enabled by creating sym-links in the ''conf.d'' sub-directory pointing to the available sites.
  
 
Here's an example configuration file for a specific domain which is set up as a chatroom server starting with the familiar ''VirtualHost'' directive to indicate the domain that this configuration covers. If you're only hosting users and don't need to host any chatrooms, then only the ''VirtualHost'' and SSL (and possibly admins) directives are needed.
 
Here's an example configuration file for a specific domain which is set up as a chatroom server starting with the familiar ''VirtualHost'' directive to indicate the domain that this configuration covers. If you're only hosting users and don't need to host any chatrooms, then only the ''VirtualHost'' and SSL (and possibly admins) directives are needed.
Line 18: Line 18:
 
admins = { "foo@example.com" }
 
admins = { "foo@example.com" }
  
 +
-- enable chatrooms under this domain
 
Component "muc.example.com" "muc"
 
Component "muc.example.com" "muc"
 
name = "The example.com chatrooms server"
 
name = "The example.com chatrooms server"
 +
 +
-- close the server to public registration
 
allow_registration = false
 
allow_registration = false
 +
 +
-- ensure that client and server connections are all ssl
 
c2s_require_encryption = true
 
c2s_require_encryption = true
 
s2s_require_encryption = true
 
s2s_require_encryption = true
Line 30: Line 35:
  
 
modules_enabled = {
 
modules_enabled = {
"vcard_muc"
+
"vcard_muc"; -- support for chatroom avatars
 +
"muc_mam";  -- storage of chatroom history
 
}
 
}
  
Component "mucfiles.example.com" "http_upload"
+
-- enable file uploads by users under this domain
 +
Component "files.example.com" "http_upload"
 
</source>
 
</source>
  
== SSL certificates ==
+
 
 +
In addition we have the following adjustments to the main ''/etc/prosody/prosody.cfg.lua'' file:
 +
<source lang="lua">
 +
-- Disable the public plain HTTP file service
 +
http_interfaces = { "127.0.0.1" }
 +
 
 +
-- Send offline messages to email addresses in 15min chunks
 +
queue_offline_emails = 900
 +
 
 +
...
 +
 
 +
-- Our path to the community modules
 +
plugin_paths = { "/etc/prosody/modules-enabled" }
 +
 
 +
modules_enabled = {
 +
"mam";            -- a core module for storing individual message history
 +
"offline_email";  -- a community module for notifying offline users of messages via email
 +
"offline_hints";  -- account for account XEP-334 tags when storing messages
 +
...
 +
}
 +
</source>
 +
 
 +
== SSL ==
 
If using ''LetsEncrypt'' certificates, then you need to ensure that the private keys are readable by ''Prosody'' (they same thing applies when using them with other services like ''Exim'' and ''Dovecot'' too).
 
If using ''LetsEncrypt'' certificates, then you need to ensure that the private keys are readable by ''Prosody'' (they same thing applies when using them with other services like ''Exim'' and ''Dovecot'' too).
  
The configuration is far simpler if there is a pair of certificate files of the form ''/etc/prosody/certs/example.com.crt''' and '''/etc/prosody/certs/example.com.key'', or in the case of ''pem'' format, a single directory containing the ''fullchain.pem'' and the ''privkey.pem'' is fine. If this method is used, the certs are handled automatically without any ''ssl'' directives being necessary in the configuration. In the case of a ''LetsEncrypt'' certificate covering many domains (which is ''pem'' format), each domain's certificate can be a single symlink pointing to the ''LetsEncrypt'' location containing the ''pem'' files for the multi-domain certificate. In our configuration these symlinks all link to ''/var/www/ssl/le-latest'' which is automatically updated to the current certificate files.
+
The configuration is far simpler if there is a pair of certificate files of the form '''/etc/prosody/certs/example.com.crt''' and '''/etc/prosody/certs/example.com.key''', or in the case of ''pem'' format, a single directory containing the ''fullchain.pem'' and the ''privkey.pem'' is fine. If this method is used, the certs are handled automatically without any ''ssl'' directives being necessary in the configuration. In the case of a ''LetsEncrypt'' certificate covering many domains (which is ''pem'' format), each domain's certificate can be a single symlink pointing to the ''LetsEncrypt'' location containing the ''pem'' files for the multi-domain certificate. In our configuration these symlinks all link to ''/var/www/ssl/le-latest'' which is automatically updated to the current certificate files.
  
 
Note that for any services that rely on the ''http'' module such as ''http_upload'' above, you will need a certificate that uses the name of the service, in this case '''https''' (or ''https.crt'' and ''https.key'' if not using ''pem'' format).
 
Note that for any services that rely on the ''http'' module such as ''http_upload'' above, you will need a certificate that uses the name of the service, in this case '''https''' (or ''https.crt'' and ''https.key'' if not using ''pem'' format).
  
 
For server-to-server communications to work (which is needed for when users from other servers wish to join a room), there must be a valid certificate defined for the MUC sub-domain as well. The main certificate specified in the virtual host container can be used without any specific settings in the MUC component as long as it's a wild-card certificate or it covers the sub-domain in it's alt-name field.
 
For server-to-server communications to work (which is needed for when users from other servers wish to join a room), there must be a valid certificate defined for the MUC sub-domain as well. The main certificate specified in the virtual host container can be used without any specific settings in the MUC component as long as it's a wild-card certificate or it covers the sub-domain in it's alt-name field.
 +
 +
There is an http service which is enabled by default and used for things like file transfers in chats, by default it is available as plain http on port 5280 and https on port 5281. To make the service only available by https you can set the http interface to local only. This has to be done at the top of ''/etc/prosody/prosody.cfg.lua'':
 +
<source lang="lua">
 +
http_interfaces = { "127.0.0.1" }
 +
</source>
  
 
== Modules ==
 
== Modules ==
''Prosody'' uses modules to extend its functionality and ships with many useful, some like ''roster'', ''offline'', ''pep'', ''sasl'', ''tls'' and ''register'' are loaded by default, and other need to be specifically included in the ''modules'' configuration directive.
+
''Prosody'' uses modules to extend its functionality and ships with many useful [https://prosody.im/doc/modules core modules], some like ''roster'', ''offline'', ''pep'', ''sasl'', ''tls'' and ''register'' are loaded by default, and other need to be specifically included in the ''modules'' configuration directive. There are also many [https://modules.prosody.im/ community modules] available which can be installed separately.
  
There are also many [https://modules.prosody.im/ community modules] available which can be installed separately. We use [https://modules.prosody.im/mod_vcard_muc.html card_muc] which allows supporting clients to display avatars for chatrooms.
+
To install community modules, install ''Mercurial'', clone the repo and make a directory for enabled modules, then add symlinks for the ones you want to use.
 +
<source lang="bash">
 +
apt install mercurial
 +
cd /etc/prosody
 +
hg clone https://hg.prosody.im/prosody-modules/ modules
 +
mkdir modules-enabled
 +
ln -s /etc/prosody/modules/mod_vcard_muc modules-enabled/
 +
ln -s /etc/prosody/modules/mod_http_upload modules-enabled/
 +
ln -s /etc/prosody/modules/mod_offline_email modules-enabled/
 +
</source>
 +
 
 +
 
 +
Then change the modules path in ''/etc/prosody/prosody.cfg.lua'' to use your new enabled path. Note that some of the specific host configurations such as Jitsi may override this setting, if so merge their setting into the main configuration.
 +
<source lang="lua">
 +
plugin_paths = { "/etc/prosody/modules-enabled" }
 +
</source>
 +
 
 +
These are the modules we use that have some configuration options:
 +
*[https://prosody.im/doc/modules/mod_mam mam]: a core module (disabled by default) that stores histories for individual contacts.
 +
*[https://prosody.im/doc/modules/mod_muc_mam muc_mam]: a core module (disabled by default) that stores chatroom histories.
 +
*[https://modules.prosody.im/mod_vcard_muc.html vcard_muc]: this allows supporting-clients to display avatars for chatrooms.
 +
*[https://modules.prosody.im/mod_http_upload.html http_upload]: this modules allows accounts in the parent scope to upload files.
 +
*[https://modules.prosody.im/mod_offline_email.html offline_email]: forwards offline messages to email (using JID as the email address)
  
 
== Users ==
 
== Users ==
Line 62: Line 118:
  
 
== Setting up notifications via email of offline messages ==
 
== Setting up notifications via email of offline messages ==
Todo
+
The [https://modules.prosody.im/mod_offline_email.html offline_email] module is a very simple module that sends offline messages to an email address that matches the user's JID. The module's code blocks while during the connection to the SMTP server so this should only be used with an SMTP server running on the same host. If the SMTP server is running on standard ports and requires no authentication for local requests, then no setup is required apart from enabling the module.
  
== Using the Prosody server that ships with Jitsi ==
+
Most users probably do not use their JID as an email address, but since the domain is obviously controlled by the local server, it should be simple to have the email server manage that domain as well and forward messages to the JIB user's proper address. By default the module will send a separate email for every offline message which can be a pain when users type many successive messages, so the ''queue_offline_emails'' can be set to a number of seconds of silence to wait and then send a single email with all the accumulated messages during that time at once.
[[Jitsi]] comes needs an XMPP server as part of its infrastructure and uses ''Prosody'', so if you're running a Jitsi, then you can easily add another virtual hosts configuration for a dedicated XMPP server as well using the same procedure shown above.
 
  
 
== Troubleshooting ==
 
== Troubleshooting ==
 
Familiarise yourself with the default configuration in ''/etc/prosody/prosody.cfg.lua'' so you know what settings and modules are available and what the defaults are. You can set the logging level to "debug", and check the output of ''prosodyctl about'', ''prosodyctl status'' and ''prosodyctl check''.
 
Familiarise yourself with the default configuration in ''/etc/prosody/prosody.cfg.lua'' so you know what settings and modules are available and what the defaults are. You can set the logging level to "debug", and check the output of ''prosodyctl about'', ''prosodyctl status'' and ''prosodyctl check''.
 +
 +
== Clients ==
 +
We're currently using the [https://gajim.org Gajim] client which has [https://xmpp.org/extensions/xep-0384.html OMEMO] (an improvement on OTR and PGP for IM encryption) and inline image support. First install the program and the ''plugin-installer'' plugin via ''apt'' as follows. The OMEMO encryption plugin is best initially installed via ''apt'', because it has some dependencies.
 +
<source lang="bash">
 +
apt install gajim gajim-plugininstaller gajim-omemo
 +
</source>
 +
 +
 +
Then enable the OMEMO and ''plugin-installer'' from the plugin menu and restart Gajim. You will then see a list of available plugins in the plugin menu where you can install, enable and configure ''Url Image Preview'' and ''Source Code Syntax Highlighting''.
 +
 +
[[File:Gajim.jpg|500px]]
 +
 +
On Linux, Gajim stores the app preferences and state in ''~/.config/gajim'', and the main data for contacts, history and plugins in ''~/.local/.share/gajim''.
  
 
== See also ==
 
== See also ==
*[https://prosody.im/doc/modules Prosody modules]
+
*[[XMPP]]
 +
*[[Jitsi]]
 +
*[[Fediverse]]
 
*[https://prosody.im/doc/example_config Official example configuration]
 
*[https://prosody.im/doc/example_config Official example configuration]
 
*[https://wiki.debian.org/InstallingProsody Debian's Prosody installation page]
 
*[https://wiki.debian.org/InstallingProsody Debian's Prosody installation page]
 
*[https://www.cyberpunk.rs/prosody-server-setup-0-10-xmpp Some good configuration examples]
 
*[https://www.cyberpunk.rs/prosody-server-setup-0-10-xmpp Some good configuration examples]
*[[Jitsi]]
+
*[https://github.com/gkdr/lurch Experimental OMEMO plugin for Pidgin]
 
[[Category:Libre software]]
 
[[Category:Libre software]]

Latest revision as of 19:30, 28 May 2020

Prosody is a light-weight, easy to configure, XMPP server. XMPP is an open and extensible Internet protocol used for communications, presence, identification, authentication etc. It's a big part of the Semantic Web movement which is all about achieving the functionality we need using open standards instead of specific applications. It's important to remember that even an application that is entirely libre software can still be a kind of "walled garden" if the application's functionality is not built on top of a common open standard. Any number of things can go wrong such as the author retiring or selling out, the development moving in an undesired direction etc, and these problems mean that you're stranded if you rely on that particular application for your operations.

Configuration

The prosody configuration is in /etc/prosody and all the data is stored in /var/lib/prosody. The configuration style is similar to popular web-servers where individual site's configuration each exist in their own file in the conf.avail sub-directory usually having a filename matching the domain name. Sites are then enabled by creating sym-links in the conf.d sub-directory pointing to the available sites.

Here's an example configuration file for a specific domain which is set up as a chatroom server starting with the familiar VirtualHost directive to indicate the domain that this configuration covers. If you're only hosting users and don't need to host any chatrooms, then only the VirtualHost and SSL (and possibly admins) directives are needed.

VirtualHost "example.com"

	-- this is only necessary if not using certs in /etc/prosody/certs
	ssl = { 
		key = "/var/www/ssl/le-latest/privkey.pem";
		certificate = "/var/www/ssl/le-latest/fullchain.pem";
	}

-- use an empty admins list to disable all remote administration functions
-- admins from any domain can be used here
admins = { "foo@example.com" }

-- enable chatrooms under this domain
Component "muc.example.com" "muc"
	name = "The example.com chatrooms server"

	-- close the server to public registration
	allow_registration = false

	-- ensure that client and server connections are all ssl
	c2s_require_encryption = true
	s2s_require_encryption = true

	-- set admins for the room and ensure only they can create new rooms
	-- note that admins in the main scope do not apply here
	admins = { "foo@example.com" }
	restrict_room_creation = true

	modules_enabled = {
		"vcard_muc"; -- support for chatroom avatars
		"muc_mam";   -- storage of chatroom history
	}

-- enable file uploads by users under this domain
Component "files.example.com" "http_upload"


In addition we have the following adjustments to the main /etc/prosody/prosody.cfg.lua file:

-- Disable the public plain HTTP file service
http_interfaces = { "127.0.0.1" }

-- Send offline messages to email addresses in 15min chunks
queue_offline_emails = 900

	...

-- Our path to the community modules
plugin_paths = { "/etc/prosody/modules-enabled" }

modules_enabled = {
	"mam";            -- a core module for storing individual message history
	"offline_email";  -- a community module for notifying offline users of messages via email
	"offline_hints";  -- account for account XEP-334 tags when storing messages
	...
}

SSL

If using LetsEncrypt certificates, then you need to ensure that the private keys are readable by Prosody (they same thing applies when using them with other services like Exim and Dovecot too).

The configuration is far simpler if there is a pair of certificate files of the form /etc/prosody/certs/example.com.crt and /etc/prosody/certs/example.com.key, or in the case of pem format, a single directory containing the fullchain.pem and the privkey.pem is fine. If this method is used, the certs are handled automatically without any ssl directives being necessary in the configuration. In the case of a LetsEncrypt certificate covering many domains (which is pem format), each domain's certificate can be a single symlink pointing to the LetsEncrypt location containing the pem files for the multi-domain certificate. In our configuration these symlinks all link to /var/www/ssl/le-latest which is automatically updated to the current certificate files.

Note that for any services that rely on the http module such as http_upload above, you will need a certificate that uses the name of the service, in this case https (or https.crt and https.key if not using pem format).

For server-to-server communications to work (which is needed for when users from other servers wish to join a room), there must be a valid certificate defined for the MUC sub-domain as well. The main certificate specified in the virtual host container can be used without any specific settings in the MUC component as long as it's a wild-card certificate or it covers the sub-domain in it's alt-name field.

There is an http service which is enabled by default and used for things like file transfers in chats, by default it is available as plain http on port 5280 and https on port 5281. To make the service only available by https you can set the http interface to local only. This has to be done at the top of /etc/prosody/prosody.cfg.lua:

http_interfaces = { "127.0.0.1" }

Modules

Prosody uses modules to extend its functionality and ships with many useful core modules, some like roster, offline, pep, sasl, tls and register are loaded by default, and other need to be specifically included in the modules configuration directive. There are also many community modules available which can be installed separately.

To install community modules, install Mercurial, clone the repo and make a directory for enabled modules, then add symlinks for the ones you want to use.

apt install mercurial
cd /etc/prosody
hg clone https://hg.prosody.im/prosody-modules/ modules
mkdir modules-enabled
ln -s /etc/prosody/modules/mod_vcard_muc modules-enabled/
ln -s /etc/prosody/modules/mod_http_upload modules-enabled/
ln -s /etc/prosody/modules/mod_offline_email modules-enabled/


Then change the modules path in /etc/prosody/prosody.cfg.lua to use your new enabled path. Note that some of the specific host configurations such as Jitsi may override this setting, if so merge their setting into the main configuration.

plugin_paths = { "/etc/prosody/modules-enabled" }

These are the modules we use that have some configuration options:

  • mam: a core module (disabled by default) that stores histories for individual contacts.
  • muc_mam: a core module (disabled by default) that stores chatroom histories.
  • vcard_muc: this allows supporting-clients to display avatars for chatrooms.
  • http_upload: this modules allows accounts in the parent scope to upload files.
  • offline_email: forwards offline messages to email (using JID as the email address)

Users

Users are managed from the CLI with prosodyctl, or can be added from a client with sufficient capabilities such as Pidgin if you're using an administrator account. Users can also change their own passwords and other personal information if the client supports it.

prosodyctl adduser foo@example.com

Chatrooms

The domain of the chat server is the domain of the "muc" component as as defined in the config, in our case muc.xmpp.organicdesign.nz. Using the configuration above, administrators of the MUC component are able to create new rooms from within their client if it has sufficient capabilities such as Pidgin or Dino.

Chatrooms can use OMEMO if they are non-anonymous, which means that member's JIDs should be set to be viewable by anyone no just moderators. Rooms can be kept private by adding a password or making them members-only. Members are added to the room either from the server, or using a client with sufficient room configuration capabilities.

Setting up notifications via email of offline messages

The offline_email module is a very simple module that sends offline messages to an email address that matches the user's JID. The module's code blocks while during the connection to the SMTP server so this should only be used with an SMTP server running on the same host. If the SMTP server is running on standard ports and requires no authentication for local requests, then no setup is required apart from enabling the module.

Most users probably do not use their JID as an email address, but since the domain is obviously controlled by the local server, it should be simple to have the email server manage that domain as well and forward messages to the JIB user's proper address. By default the module will send a separate email for every offline message which can be a pain when users type many successive messages, so the queue_offline_emails can be set to a number of seconds of silence to wait and then send a single email with all the accumulated messages during that time at once.

Troubleshooting

Familiarise yourself with the default configuration in /etc/prosody/prosody.cfg.lua so you know what settings and modules are available and what the defaults are. You can set the logging level to "debug", and check the output of prosodyctl about, prosodyctl status and prosodyctl check.

Clients

We're currently using the Gajim client which has OMEMO (an improvement on OTR and PGP for IM encryption) and inline image support. First install the program and the plugin-installer plugin via apt as follows. The OMEMO encryption plugin is best initially installed via apt, because it has some dependencies.

apt install gajim gajim-plugininstaller gajim-omemo


Then enable the OMEMO and plugin-installer from the plugin menu and restart Gajim. You will then see a list of available plugins in the plugin menu where you can install, enable and configure Url Image Preview and Source Code Syntax Highlighting.

Gajim.jpg

On Linux, Gajim stores the app preferences and state in ~/.config/gajim, and the main data for contacts, history and plugins in ~/.local/.share/gajim.

See also