Modern ejabberd configuration


ejabberd is one of the most widely used XMPP servers. It is easy to get it running for text-based messaging with a few configuration changes. However, to obtain a smoothly running modern feature set is harder. The configuration documentation is detailed, but even for a seasoned systems administrator or XMPP guru, a lot of questions remain. Here is an attempt at a simple how-to.

Single-host configuration

Configuration for a single virtual host for ejabberd 17.11.

/etc/ejabberd/ejabberd.yml

Replace the modules: section and other variables with the following:

<span style="color: #800000;"><span style="color: #003300;">define_macro:</span>
</span> 'CIPHERS': <span style="color: #000080;">"ECDH:DH:!3DES:!aNULL:!eNULL:!MEDIUM@STRENGTH:!AES128"</span>
 'TLSOPTS':
  - <span style="color: #000080;">"no_sslv3"</span>
<span style="color: #993300;">  # generated with: openssl dhparam -out dhparams.pem 2048</span>
  'DHFILE': <span style="color: #000080;">"/etc/ejabberd/dhparams.pem"</span> 

<span style="color: #000000;">certfiles:</span>
  - "/etc/letsencrypt/live/*/fullchain.pem"
  - "/etc/letsencrypt/live/*/privkey.pem"
<span style="color: #000000;">s2s_use_starttls:</span> required
<span style="color: #000000;">s2s_protocol_options:</span> <span style="color: #993300;">'TLSOPTS'</span>
<span style="color: #000000;">s2s_ciphers:</span> <span style="color: #993300;">'CIPHERS'</span>
<span style="color: #000000;">s2s_dhfile:</span> <span style="color: #993300;">'DHFILE'</span>
<span style="color: #000000;">c2s_dhfile:</span> <span style="color: #993300;">'DHFILE'</span>

<span style="color: #000080;"><span style="color: #800000;"># Will be used for @HOST@ substitution as well</span>
</span><span style="color: #003300;">hosts:</span><span style="color: #000080;">
  - "example.ch"
</span>
<span style="color: #003300;">modules:</span> <span style="color: #800000;"># See <a href="https://docs.ejabberd.im/admin/configuration/#modules-overview">manual</a></span>
  <span style="color: #800000;"># Ad-Hoc Commands (<a href="https://xmpp.org/extensions/xep-0050.html">XEP-0050</a>)</span>
<span style="color: #000000;">  mod_adhoc:</span> {}
  <span style="color: #800000;"># Additional ejabberdctl commands</span>
<span style="color: #000000;">  mod_admin_extra:</span> {}
  <span style="color: #800000;"># Send global announcements</span>
<span style="color: #000000;">  mod_announce:</span> <span style="color: #800000;"># recommends mod_adhoc</span>
    access: announce
  <span style="color: #800000;"># Transparently convert between vcard and pubsub avatars</span>
<span style="color: #000000;">  mod_avatar:</span> {} <span style="color: #800000;"># Requires ejabberd >= 17.09, mod_vcard, mod_vcard_xupdate, mod_pusub</span>
<span style="color: #800000;">  # Simple Communications Blocking (<a href="https://xmpp.org/extensions/xep-0191.html">XEP-0191</a>)</span>
<span style="color: #000000;">  mod_blocking:</span> {} <span style="color: #800000;"># requires mod_privacy</span>
<span style="color: #800000;">  # Exchange entity (client) capabilities, e.g. Jingle (<a href="http://xmpp.org/extensions/xep-0115.html">XEP-0115</a>)</span>
<span style="color: #000000;">  mod_caps:</span> {}
<span style="color: #800000;">  # Send messages to all clients of a user (<a href="http://xmpp.org/extensions/xep-0280.html">XEP-0280</a>)</span>
<span style="color: #000000;">  mod_carboncopy:</span> {}
<span style="color: #800000;">  # Queue and filter stanzas for inactive clients (improves mobile client battery life, <a href="http://xmpp.org/extensions/xep-0352.html">XEP-0352</a>)</span>
<span style="color: #000000;">  mod_client_state:</span> {}
<span style="color: #800000;">  # Server configuration with Ad-Hoc commands</span>
<span style="color: #000000;">  mod_configure:</span> {} <span style="color: #800000;"># requires mod_adhoc</span>
<span style="color: #800000;">  # Service discovery, e.g. for MUC, Pub/Sub, HTTP Upload (<a href="http://xmpp.org/extensions/xep-0030.html">XEP-0030</a>)</span>
<span style="color: #000000;">  mod_disco:</span> {}
<span style="color: #800000;">  # (XMPP over) BOSH: HTTP tunneling for web clients such as <a href="https://netfuture.ch/tag/jsxc">JSXC</a> (<a href="http://xmpp.org/extensions/xep-0124.html">XEP-0124</a>, <a href="http://xmpp.org/extensions/xep-0206.html">XEP-0206</a>)</span>
<span style="color: #000000;">  mod_bosh:</span> {}
<span style="color: #800000;">  # Last activity (<a href="http://xmpp.org/extensions/xep-0012.html">XEP-0012</a>)</span>
<span style="color: #000000;">  mod_last:</span> {}
<span style="color: #800000;">  # Message Archive Management (XEP-0313): Allows clients to catch up</span>
<span style="color: #000000;">  mod_mam:</span>
    default: roster
<span style="color: #800000;">  # Queue messages for offline users (<a href="http://xmpp.org/extensions/xep-0160.html">XEP-0160</a>)</span>
<span style="color: #000000;">  mod_offline:</span>
    access_max_user_messages: max_user_offline_messages
<span style="color: #800000;">  # XMPP Ping and periodic keepalives (XEP-0199)</span>
<span style="color: #000000;">  mod_ping:</span> {}
<span style="color: #800000;">  # Limit status spam (a full presence authorization requires 4 messages)</span>
<span style="color: #800000;">  # See also <a href="https://www.process-one.net/blog/fighting-xmpp-abuse-and-spam-with-ejabberd-ejabberd-workshop-1/">Anti-Spam Workshop</a></span>
<span style="color: #000000;">  mod_pres_counter:</span>
    count: 50
    interval: 600
<span style="color: #800000;">  # Block some senders (<a href="http://xmpp.org/extensions/xep-0016.html">XEP-0016</a>)</span>
<span style="color: #000000;">  mod_privacy:</span> {}
<span style="color: #800000;">  # Private XML storage (<a href="http://xmpp.org/extensions/xep-0049.html">XEP-0049</a>)</span>
<span style="color: #000000;">  mod_private:</span> {}
<span style="color: #800000;">  # Allows clients to request push notifications</span>
<span style="color: #000000;">  mod_push:</span> {} <span style="color: #800000;"># Requires ejabberd >= 17.08</span>
<span style="color: #800000;">  # The roster. You want this.</span>
<span style="color: #000000;">  mod_roster:</span> {}
<span style="color: #800000;">  # If you want to pre-configure rosters for workgroups</span>
<span style="color: #000000;">  mod_shared_roster:</span> {}
<span style="color: #800000;">  # Allow users to create a vcard, visible to authorized peers (<a href="http://xmpp.org/extensions/xep-0054.html">XEP-0054</a>)</span>
<span style="color: #000000;">  mod_vcard:</span>
    search: false <span style="color: #800000;"># Privacy</span>
<span style="color: #800000;">  # vcard-based Avatars (<a href="http://xmpp.org/extensions/xep-0153.html">XEP-0153</a>)</span>
<span style="color: #000000;">  mod_vcard_xupdate:</span> {}
<span style="color: #800000;">  # Stream management (<a href="http://xmpp.org/extensions/xep-0198.html">XEP-0198</a>): Continuity after network interruptions</span>
<span style="color: #000000;">  mod_stream_mgmt:</span> {}
<span style="color: #800000;">  # Ask for a dialback, if the certificate does not match (<a href="http://xmpp.org/extensions/xep-0220.html">XEP-0220</a>)</span>
<span style="color: #000000;">  mod_s2s_dialback:</span> {}

<span style="color: #800000;">  # Additional services</span>

  <span style="color: #800000;"># Publish/subscribe, e.g. for <a href="https://movim.eu">Movim</a></span>
<span style="color: #000000;">  mod_pubsub:</span>
    host: <span style="color: #000080;">"pubsub.@HOST@"</span> <span style="color: #800000;"># "hosts:" for multiple pubsub services</span>
    access_createnode: local
    ignore_pep_from_offline: false
    last_item_cache: false
    max_items_node: 1000
    default_node_config:
      max_items: 1000
    plugins:
      - "flat"
      - "pep" <span style="color: #800000;"># Requires mod_caps.
  # Multi-User (group) Chat</span>
<span style="color: #000000;">  mod_muc:</span>
    host: <span style="color: #000080;">"conference.@HOST@"</span>
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
<span style="color: #800000;">  # File transfer via HTTP Upload</span>
<span style="color: #000000;">  mod_http_upload:</span>
    host: <span style="color: #000080;">"userdata.@HOST@"</span>
    docroot: <span style="color: #000080;">"/srv/userdata/" <span style="color: #800000;"># Or wherever you would like to have them stored</span></span>
    put_url: <span style="color: #000080;">"https://userdata.@HOST@/ud"</span>
    custom_headers:
      "Access-Control-Allow-Origin": "*"
      "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT"
      "Access-Control-Allow-Headers": "Content-Type"<span style="color: #800000;">
  # Expire files on server after specified period</span>
  <span style="color: #000000;">mod_http_upload_quota:</span>
    max_days: 30

<span style="color: #003300;">listen:</span>
  -
    port: 5222
    ip: <span style="color: #000080;">"::"</span>
    module: ejabberd_c2s
    starttls_required: true
    protocol_options: <span style="color: #993300;">'TLSOPTS'</span>
    dhfile: <span style="color: #993300;">'DHFILE'</span>
    ciphers: <span style="color: #993300;">'CIPHERS'</span>
    max_stanza_size: 65536
    shaper: c2s_shaper
    access: c2s
  - 
    port: 5269
    ip: <span style="color: #000080;">"::"</span>
    module: ejabberd_s2s_in
    max_stanza_size: 131072
    shaper: s2s_shaper
  -
    port: 443
    ip: <span style="color: #000080;">"::"</span>
    module: ejabberd_http
    tls: true
    request_handlers:
      <span style="color: #000080;">"/websocket"</span>: ejabberd_http_ws
      <span style="color: #000080;">"/ud"</span>: mod_http_upload
    http_bind: true <span style="color: #800000;"># Will map to "/http-bind"</span>
  -
    port: 3478
    transport: udp
    module: ejabberd_stun
    auth_type: user
    auth_realm: <span style="color: #000080;">"example.ch"</span>
    use_turn: true
    turn_ip: <span style="color: #000080;">"192.2.0.1"</span> <span style="color: #800000;"># Your IP address</span>
  - 
    port: 3478
    transport: tcp
    module: ejabberd_stun
    auth_type: user
    auth_realm: <span style="color: #000080;">"example.ch"</span>
    use_turn: true
    turn_ip: <span style="color: #000080;">"192.2.0.1" <span style="color: #800000;"># Your IP address</span></span>

DNS configuration

You will also require the following entries in the Domain Name System. xmpp.example.ch can be any name you like.

xmpp.example.ch.                         A     192.2.0.1
xmpp.example.ch.                         AAAA  2001:db8::1
userdata.example.ch.                     CNAME xmpp.example.ch.
turn.example.ch.                         CNAME xmpp.example.ch.
_xmpp-client._tcp.example.ch.            SRV   10 1 5222 xmpp.example.ch.
_xmpp-server._tcp.example.ch.            SRV   10 1 5269 xmpp.example.ch.
_xmpp-server._tcp.conference.example.ch. SRV   10 1 5269 xmpp.example.ch.
_xmpp-server._tcp.pubsub.example.ch.     SRV   10 1 5269 xmpp.example.ch.

Certificate requirements

Your certificate should cover example.ch, userdata.example.ch, conference.example.ch, and pubsub.example.ch (and turn.example.ch).

<span style="color: #000000;">openssl dhparam</span> -out /etc/ejabberd/dhparams.pem 2048
<span style="color: #000000;">chown</span> ejabberd /etc/ejabberd/dhparams.pem

Updated 2018-01-22: Added c2s_dhfile.

Updated 2018-02-23: Removed thumbnail (useless with modern encrypted uploads), switched to certfiles (available as of ejabberd 17.11), and included dhparam creation.

,

Let’s stay in touch!

Receive a mail whenever I publish a new post.

About 1-2 Mails per month, no Spam.

Follow me on the Fediverse

Netfuture: The future is networked
Netfuture: The future is networked
@blog@netfuture.ch

The future of networking

206 posts
6 followers

Web apps


Leave a Reply

Only people in my network can comment.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Find out more about Webmentions.)