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:
define_macro: 'CIPHERS': "ECDH:DH:!3DES:!aNULL:!eNULL:!MEDIUM@STRENGTH:!AES128" 'TLSOPTS': - "no_sslv3" # generated with: openssl dhparam -out dhparams.pem 2048 'DHFILE': "/etc/ejabberd/dhparams.pem" certfiles: - "/etc/letsencrypt/live/*/fullchain.pem" - "/etc/letsencrypt/live/*/privkey.pem" s2s_use_starttls: required s2s_protocol_options: 'TLSOPTS' s2s_ciphers: 'CIPHERS' s2s_dhfile: 'DHFILE' c2s_dhfile: 'DHFILE' # Will be used for @HOST@ substitution as well hosts: - "example.ch" modules: # See manual # Ad-Hoc Commands (XEP-0050) mod_adhoc: {} # Additional ejabberdctl commands mod_admin_extra: {} # Send global announcements mod_announce: # recommends mod_adhoc access: announce # Transparently convert between vcard and pubsub avatars mod_avatar: {} # Requires ejabberd >= 17.09, mod_vcard, mod_vcard_xupdate, mod_pusub # Simple Communications Blocking (XEP-0191) mod_blocking: {} # requires mod_privacy # Exchange entity (client) capabilities, e.g. Jingle (XEP-0115) mod_caps: {} # Send messages to all clients of a user (XEP-0280) mod_carboncopy: {} # Queue and filter stanzas for inactive clients (improves mobile client battery life, XEP-0352) mod_client_state: {} # Server configuration with Ad-Hoc commands mod_configure: {} # requires mod_adhoc # Service discovery, e.g. for MUC, Pub/Sub, HTTP Upload (XEP-0030) mod_disco: {} # (XMPP over) BOSH: HTTP tunneling for web clients such as JSXC (XEP-0124, XEP-0206) mod_bosh: {} # Last activity (XEP-0012) mod_last: {} # Message Archive Management (XEP-0313): Allows clients to catch up mod_mam: default: roster # Queue messages for offline users (XEP-0160) mod_offline: access_max_user_messages: max_user_offline_messages # XMPP Ping and periodic keepalives (XEP-0199) mod_ping: {} # Limit status spam (a full presence authorization requires 4 messages) # See also Anti-Spam Workshop mod_pres_counter: count: 50 interval: 600 # Block some senders (XEP-0016) mod_privacy: {} # Private XML storage (XEP-0049) mod_private: {} # Allows clients to request push notifications mod_push: {} # Requires ejabberd >= 17.08 # The roster. You want this. mod_roster: {} # If you want to pre-configure rosters for workgroups mod_shared_roster: {} # Allow users to create a vcard, visible to authorized peers (XEP-0054) mod_vcard: search: false # Privacy # vcard-based Avatars (XEP-0153) mod_vcard_xupdate: {} # Stream management (XEP-0198): Continuity after network interruptions mod_stream_mgmt: {} # Ask for a dialback, if the certificate does not match (XEP-0220) mod_s2s_dialback: {} # Additional services # Publish/subscribe, e.g. for Movim mod_pubsub: host: "pubsub.@HOST@" # "hosts:" for multiple pubsub services 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" # Requires mod_caps. # Multi-User (group) Chat mod_muc: host: "conference.@HOST@" access: - allow access_admin: - allow: admin access_create: muc_create access_persistent: muc_create # File transfer via HTTP Upload mod_http_upload: host: "userdata.@HOST@" docroot: "/srv/userdata/" # Or wherever you would like to have them stored put_url: "https://userdata.@HOST@/ud" custom_headers: "Access-Control-Allow-Origin": "*" "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT" "Access-Control-Allow-Headers": "Content-Type" # Expire files on server after specified period mod_http_upload_quota: max_days: 30 listen: - port: 5222 ip: "::" module: ejabberd_c2s starttls_required: true protocol_options: 'TLSOPTS' dhfile: 'DHFILE' ciphers: 'CIPHERS'  max_stanza_size: 65536 shaper: c2s_shaper access: c2s - port: 5269 ip: "::" module: ejabberd_s2s_in max_stanza_size: 131072 shaper: s2s_shaper - port: 443 ip: "::" module: ejabberd_http tls: true request_handlers: "/websocket": ejabberd_http_ws "/ud": mod_http_upload http_bind: true # Will map to "/http-bind" - port: 3478 transport: udp module: ejabberd_stun auth_type: user  auth_realm: "example.ch" use_turn: true turn_ip: "192.2.0.1" # Your IP address - port: 3478 transport: tcp module: ejabberd_stun auth_type: user auth_realm: "example.ch" use_turn: true turn_ip: "192.2.0.1" # Your IP address
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
).
openssl dhparam -out /etc/ejabberd/dhparams.pem 2048 chown 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.