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://blog.process-one.net/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

Web apps


Leave a Reply

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