Ejabberd

Ce document est inachevé !

Ejabberd est un serveur XMPP qui peut être passé à l'échelle facilement pour de gros serveurs, mais pas très lourd pour quand même permettre l'auto-hébergement. Il peut être installé sur Linux facilement et la configuration par défaut fonctionne raisonnablement bien. Malgré tout si vous souhaitez avoir accès à certaines fonctionnalités plus récentes vous pouvez avoir à y faire quelques modifications. La documentation officielle pour tous les paramètres des modules d'Ejabberd peut être trouvée ici.

Tutoriel

Prérequis :

  • Un nom de domaine
  • Un serveur

Ce tutoriel commence avec un seul virtualhost[^1]. Pour les besoins de cet exemple, example.net est le domaine. Remplacez toutes les occurences de example.net par votre propre nom de domaine.

[^1] : Les virtualhosts permettent à plus d'un service XMPP de tourner sur le même serveur. Par exemple, un service XMPP avec le domaine example.net et un autre service XMPP avec le domaine example.org, les deux quelque peu séparés l'un de l'autre comme s'ils étaient sur des serveurs différents.

Étape 1 : Configurer les enregistrements DNS

Les enregistrements DNS A/AAAA et SRV sont nécessaires pour chaque service sur le serveur XMPP.

Enregistrements A :

  • example.net
  • muc.example.net (pour les salons de discussions)
  • upload.example.net (pour l'upload de fichiers HTTP)
  • pubsub.example.net (pour le nœud pubsub)
  • proxy.example.net (pour le proxy de transfert de fichier)
  • turn.example.net (pour STUN/TURN)

Chacun pointant sur l'adresse IP du serveur faisant tourner Ejabberd.

Créez un enregistrement SRV pour chacun, pointant sur un nom de domaine qui résoud vers le serveur, comme ceci :

(Tous les enregistrements sont de la forme _service._proto.nom IN SRV priorité poids port cible)

_xmpp-client._tcp   IN SRV  5 0 5222 example.net.
_xmpps-client._tcp  IN SRV  5 0 5223 example.net.
_xmpp-server._tcp   IN SRV  5 0 5269 example.net.
_xmpps-server._tcp  IN SRV  5 0 5270 example.net.

et

_xmpp-client._tcp.muc   IN SRV  5 0 5222 example.net.
_xmpps-client._tcp.muc  IN SRV  5 0 5223 example.net.
_xmpp-server._tcp.muc   IN SRV  5 0 5269 example.net.
_xmpps-server._tcp.muc  IN SRV  5 0 5270 example.net.

pour chaque sous-domaine (commançant par muc). Excluant turn.example.net.

Enfin, ajoutez un ensemble d'enregistrements SRV, pour STUN/TURN.

_stun._udp   IN SRV  5 0 3478 turn.example.net.
_stun._tcp   IN SRV  5 0 3478 turn.example.net.
_stuns._tcp  IN SRV  5 0 5349 turn.example.net.

_turn._udp   IN SRV  5 0 3478 turn.example.net.
_turn._tcp   IN SRV  5 0 3478 turn.example.net.
_turns._tcp  IN SRV  5 0 5349 turn.example.net.

Info supplémentaire : comme résultat de cette délégation des enregistrements SRV, héberger XMPP sur un autre serveur que celui sur example.net est une possibilité (i.e. si on sépare les services sur un domaine entre serveurs). Plus d'informations peuvent être trouvés sur la XEP-0368.

Étape 2 : Ouvrir les ports dans le pare-feu

Ouvrir les ports :

TCP : 80 443 5222 5223 5269 5270 3478 5349 49152-65535

UDP : 3478 49152-65535

80 & 443 sont pour le serveur web, 5222, 5223, 5269 et 5270 sont pour XMPP, et les autres sont pour STUN/TURN.

Étape 3 : Configurer le serveur web et obtenir vos certificats SSL/TLS

  • obtenir un (des) certificat(s) pour votre nom de domaine, comme pour les sous-domaines, tous ensemble :

    • example.net
    • muc.example.net
    • upload.example.net
    • pubsub.example.net
    • proxy.example.net
    • turn.example.net
  • proxypass de http://127.0.0.1:5443 à travers :

    Assurez-vous que pour /xmpp vous avez ce qui est nécessaire pour proxifier les websocket aussi. Si ovus utilisez Nginx, augmentez client_max_body_size pour l'upload HTTP.

  • assurez-vous que les fichiers des certificats sont lisibles et/ou à un endroit lisible par l'utilisateur ejabberd.

Pour éviter d'utiliser quelque chose comme Nginx + Certbot, utilisez le module acme Ejabberd intégré, mais cet article part du principe qu'héberger les autres services web sur le même système est voulu, auquel cas chaque service HTTP serait proxifié vers un seul service web HTTPS.

Étape 4 : Installer Ejabberd

Enfin installez le paquet système. Assurez-vous que ce build supporte PostgreSQL.

Confirmez que le fichier /etc/ejabberd/ejabberd.yml existe, et est lisible par l'utilisateur qui fait tourner Ejabberd (certainement ejabberd), en, si nécessaire, copiant l'exemple ejabberd.yml ou wget/curlant le fichier depuis le dépôt github. S'il est obtenu depuis le dépôt, assurez-vous que la version correspond à la version de Ejabberd du paquet fournis par votre OS.

Étape 5 : Configurer la base de données PostgreSQL

Une base de données séparée devrait être créée pour chaque virtualhost, pour rendre les choses plus claires, et en plus, rendre les virtualhost plus facile à migrer dans le futur. Cependant, la possibilité d'en utiliser une seule, comme décrit ici, exists aussi à présent.

Suivez les instructions de l'installation standard de PostgreSQL pour votre OS. Une fois cela fait, connectez-vous à la base de données en tant qu'administrateurice et :

  1. créez un utilisateur de base de données Ejabberd avec CREATE USER ejabberd WITH PASSWORD 'votre_mot_de_passe';. N'oubliez pas de changer le mot de passe, et notez-le.
  2. créez une base de données pour le virtualhost avec CREATE DATABASE ejabberd_exemple OWNER ejabberd;. Remplacez exemple par quelque chose correspondant au virtualhost.
  3. quittez le shell psql, et importez le schéma de la base de données depuis GitHub avec la commande curl -s https://raw.githubusercontent.com/processone/ejabberd/master/sql/pg.sql | sudo -u ejabberd psql ejabberd_exemple (encore une fois remplacez exemple).

Étape 6 : Configuration de Ejabberd

Commencez par remplacer localhost sous hosts avec le virtualhost (e.g. example.net), puis listez les fichiers de certificats précédemment obtenus sous certfiles.

hosts:
  - example.net

certfiles:
  - "/etc/ejabberd/certs/*/*"

Maintenant mettez default_db: sql au niveau racine du fichier YAML. Ça devrait être suivis de host_config et de la configuration de base de données de votre virtualhost, comme montré ci-dessous. Personnalisez chaque valeur en fonction de la configuration.

host_config:
  example.net:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_exemple"
    auth_method: sql
    auth_password_format: scram

Sous listen, assurez-vous que tous les bons services sont activés sur chaque port, incluant le TLS s2s sur le port 5270 (qui n'est pas le défaut) :

listen:
  -
    port: 5222
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5223
    tls: true
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5269
    module: ejabberd_s2s_in
    max_stanza_size: 524288
  -
    port: 5270
    tls: true
    module: ejabberd_s2s_in
    max_stanza_size: 524288

Ensuite, activez les modules du serveur HTTP et du serveur STUN/TURN. Complétez turn_ipv4_address et ip avec l'adresse IPv4 de votre serveur. TLS sera désactivé pour le serveur HTTP car il est proxifié à travers le serveur web précédemment configuré.

  -
    port: 5443
    module: ejabberd_http
    request_handlers:
      /xmpp/admin: ejabberd_web_admin
      /xmpp/bosh: mod_bosh
      /xmpp/upload: mod_http_upload
      /xmpp/ws: ejabberd_http_ws
      /.well-known/host-meta: mod_host_meta
      /.well-known/host-meta.json: mod_host_meta
  -
    port: 3478
    transport: udp
    module: ejabberd_stun
    use_turn: true
    turn_min_port: 49152
    turn_max_port: 65535
    # The server's public IPv4 address:
    turn_ipv4_address: 0.0.0.0
  -
    port: 5349
    transport: tcp
    module: ejabberd_stun
    use_turn: true
    tls: true
    turn_min_port: 49152
    turn_max_port: 65535
    ip: 0.0.0.0
    turn_ipv4_address: 0.0.0.0

Mettez s2s_use_starttls: required à la racine.

À partir de là il est possible de configurer quelques ACLs. acls sont juste les access control lists, configurez access_rules en fonction de vos besoins, qui seront transmis aux paramètres des modules. Au minimum un·e utilisateurice admin est recommandé. Exemple :

acl:
  admin:
    user: juliet@example.net
  capulet:
    - user: juliet@example.net
	- user: tybalt@example.net
  nurse:
    - user: angelica@example.net

access_rules:
  household: 
    allow: capulet
    allow: nurse

Modules

Ajoutez une adresse d'abus sous mod_disco. Il est aussi possible d'ajouter d'autres adresses de contact d'après la XEP-0157 :

modules:
# ...
  mod_disco:
    server_info:
    -
      modules: all
      name: "abuse-addresses"
      urls: ["mailto:abuse@example.net"]

Ajoutez mod_host_meta :

  mod_host_meta:
    bosh_service_url: "https://@HOST@/xmpp/bosh"
    websocket_url: "wss://@HOST@/xmpp/ws"

Editez mod_mam, et changez assume_mam_usage à false et default à never s'il n'est pas souhaitable d'archiver par défaut les messages sur le serveur :

  mod_mam:
    db_type: sql
    assume_mam_usage: never
    default: never

Ajoutez mod_stun_disco pour signaler le service STUN aux clients, en changeant 0.0.0.0 et example.net pour respectivement l'adresse IP et le nom de domaine du serveur :

  mod_stun_disco: 
    credentials_lifetime: 12h
    services:
        -
          host: 0.0.0.0
          port: 3478
          type: stun
          transport: udp
          restricted: false
        -
          host: 0.0.0.0
          port: 3478
          type: turn
          transport: udp
          restricted: true
        -
          host: turn.example.net
          port: 5349
          type: stuns
          transport: tcp
          restricted: false
        -
          host: turn.example.net
          port: 5349
          type: turns
          transport: tcp
          restricted: true

Salons de discussions (MUC) :

Configurez l'hôte du sous-domaine muc, sinon il essayera d'utiliser conference.example.net. Configurer mam: false dans default_room_options désactivera l'archivage des messages côté serveur par défaut.

  mod_muc:
    host: muc.example.net
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    access_mam:
      - allow
    default_room_options:
      mam: false

Proxy de fichier :

  mod_proxy65:
    access: local
    max_connections: 5

Upload de fichier HTTP :

  mod_http_upload:
    put_url: https://@HOST@/xmpp/upload
    docroot: /var/www/ejabberdupload
    max_size: 1073741824
    custom_headers:
      "Access-Control-Allow-Origin": "https://@HOST@"
      "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
      "Access-Control-Allow-Headers": "Content-Type"

Créez le dossier pour le docroot, et assurez-vous qu'il appartient à l'utilisateur ejabberd. Changez max_size (la taille maximale d'upload) pour la valeur souhaité.

PubSub :

  mod_pubsub:
    access_createnode: pubsub_createnode
    plugins:
      - flat
      - pep
    force_node_config:
      ## Empêcher les clients bugués de rendre leurs favoris publics
      storage:bookmarks:
        access_model: whitelist

Étape 7 : Lancer le serveur et créer un· utilisateurice admin

démarrez le serveur Ejabberd !

Utilisez sudo -u ejabberd ejabberdctl register admin example.net mot-de-passe pour enregistrer admin@example.net avec le mot de passe mot-de-passe.

Il y a un vérificateur de conformité sur compliance.conversations.im pour tester le serveur. Après que tout ai été configuré correctement, changez potentiellement le loglevel à la racine de la configuration.

Il y aura une page d'administration accessible via https://example.net/xmpp/admin.

Cadeaux bonus !

Client web

Il est possible de configurer conversejs en utilisant mod_conversejs. Il peut être nécessaire de mettre à jour la configuration du serveur web pour proxyfier le nouveau point de terminaison (/chat ci-dessous).

listen:
  -
    port: 5443
    module: ejabberd_http
    request_handlers:
      /xmpp/bosh: mod_bosh
      /xmpp/ws: ejabberd_http_ws
      /chat: mod_conversejs

modules:
  mod_conversejs:
    websocket_url: "ws://@HOST@/xmpp/ws"
    bosh_service_url: "https://@HOST@/xmpp/bosh"

Virtualhosts supplémentaires

Pour chaque virtualhost supplémentaire une nouvelle base de données devrait être créée, et ajouté à la partie base de données de la configuration. exemple :

host_config:
  example.net:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_net"
    auth_method: sql
    auth_password_format: scram
  example.org:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_org"
    auth_method: sql
    auth_password_format: scram

Il ne peut pas y avoir de conflits entre les déclarations dans le fichier de configuration, donc si mod_muc, mod_proxy65, mod_http_upload et mod_pubsub sont declarés sous modules à la racine, ils (ainsi que d'autres différences de configuration entre les virtualhosts) doivent être supprimés et recopiés pour chaque virtualhost sous append_host_config, à la racine. Example :

append_host_config:
  example.org:
    modules:
      mod_muc:
        host: muc.example.org
        access_create: org_users
        access_persistent: org_users
        access:
          - allow
        access_admin:
          - allow: admin
        default_room_options:
          mam: false
      mod_proxy65:
        access: org_users
        max_connections: 5
      mod_http_upload:
        access: org_users
        put_url: https://@HOST@/xmpp/upload
        docroot: /var/www/ejabberdupload
        max_size: 1073741824
        custom_headers:
          "Access-Control-Allow-Origin": "https://@HOST@"
          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
          "Access-Control-Allow-Headers": "Content-Type"
      mod_pubsub:
        access_createnode: org_users
        plugins:
          - flat
          - pep
        force_node_config:
          ## Empêcher les clients bugués de rendre leurs favoris publics
          storage:bookmarks:
            access_model: whitelist
  example.net:
    modules:
      mod_muc:
        hosts: 
          - muc.example.net
        access_create: net_users
        access_persistent: net_users
        access:
          - allow
        access_admin:
          - allow: admin
        default_room_options:
          mam: false
      mod_proxy65:
        access: net_users
        max_connections: 5
      mod_http_upload:
        access: net_users
        put_url: https://@HOST@/xmpp/upload
        docroot: /var/www/ejabberdupload
        max_size: 1073741824
        custom_headers:
          "Access-Control-Allow-Origin": "https://@HOST@"
          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
          "Access-Control-Allow-Headers": "Content-Type"
      mod_pubsub:
        access_createnode: net_users
        plugins:
          - flat
          - pep
        force_node_config:
          ## Empêcher les clients bugués de rendre leurs favoris publics
          storage:bookmarks:
            access_model: whitelist

Comme ci-dessus, il est possible de désactiver l'accès à certains services par virtualhost à l'aide des ACL, pour par exemple éviter que des utilisateurices de example.net ne créent des salons sur muc.example.org.

Separer les serveurs TURN (Coturn)

Dans ce cas, changez mod_stun_disco en ceci, et n'activez pas l'option listen pour STUN/TURN. Générez un secret d'authentification et partagez-le avec l'instance du serveur TURN.

  mod_stun_disco:
    secret: "auth_secret"
    services:
      -
        host: turn.example.net
        type: stun
      -
        host: turn.example.net
        type: turn

À la base adapté depuis : blos.sm

Salon de support

Ceci n'est évidemment pas une liste exhaustive et si vous avez une très bonne recommandation merci de nous contacter ici : servers@joinjabber.org (web chat) (xmpp)