Installer un serveur XMPP (ejabberd + support MySQL)

220px-XMPP_logo.svg

 

Qui n'a jamais révé de briller en société avec son serveur de messagerie ?
C'est chose possible grâce au super protocole XMPP !

 

Qu'est ce que le XMPP ?

Sous ce bel acronyme ce cache : Extensible Messaging and Presence Protocol.
C'est donc un protocole de communication décentralisé et libre (ne dépend donc pas d'une marque, d'un seul serveur, d'une seule équipe de dev' …)
Par le biais de ce support, on peut transporter du texte, de la voie, de la vidéo … bref ça roxx du poney !
Il est utilisé par de très grands groupes sans que beaucoup d'entre nous ne le sachent (bien que parfois adapté à leurs besoins) : Google, Facebook, Apple …
(Je vous invite à consulter la page wiki du XMPP si vous cherchez plus d'infos.)

Et nous là dedans ?

On va installer notre propre serveur XMPP et rejoindre la grande famille d'internet cheeky

 

Pour ça on va utiliser ejabberd → http://www.ejabberd.im/
Serveur XMPP sous licence GPLv2 et compatible multi-plateforme.

ejabberd_logo

Comme d'habitude, je zap la partie installation de la VM, le reste du tuto est basé sur une Debian 7.0 en testing (soyons fous, vivons dangereux !).

Pour commencer, un classique (ça mange pas de pain) :

# aptitude update && aptitude upgrade

Pensez à adapter dès maintenant votre fichier hosts (ça peut poser pas mal de problèmes inutiles par la suite).

# nano /etc/hosts

Après vient le choix de la méthode d'installation, il y a 3 solutions possibles :

  1. Installation via paquet debian présent dans les dépots (actuellement en 2.1.10)
  2. installation via paquet binaire précompilé (disponible sur le site en 2.1.11)
  3. en compilant tout comme des barbus à partir des sources (il faudra penser à activer le support ODBC lors de la compilation)

J'aime bien compiler par moi même, mais le erlang n'est pas franchement ma tasse de thé, je vais donc choisir la solution n°1 (de toute façon on va vite devoir revenir aux sources pour compiler le connecteur MySQL).

c'est parti !!

# aptitude install ejabberd

ouf, c'est fini !! cool

 

Jusque là, ça va, maintenant, on va commencer à mettre les mains dedans !

# nano /etc/ejabberd/ejabberd.cfg

modifiez la partie :

{hosts, ["localhost"]}.

en (à vous d'adapter votre nom de domaine !) :

{hosts, ["sheldon.fr"]}.

Passons un peu ce fichier de conf (il est imbuvable hein ?), et arrêtons nous aux ACL.
Changez :

%% Admin user
{acl, admin, {user, "", "localhost"}}.

par :

%% Admin user
{acl, admin, {user, "monutilisateuradmin", "sheldon.fr"}}.

Si vous voulez vous arrêter là, et utiliser base de données interne Messina, vous n'avez qu'à créer votre utilisateur maintenant avec la commande :

# ejabberdctl register monutilisateuradmin sheldon.fr monsupermotdepasse

Mais ça serait être faible, et surtout utiliser une BDD très sensible, et pas facile à dépanner en cas de couille,
couille qui arrivera si vous modifier votre fichier hosts après avoir installé ejabberd !! (c'est du vécu !)

Vous êtes un barbus ? vous avez des couilles ?
Alors on va utiliser une BDD externe MySQL !

Je pars du principe que vous avez déjà un serveur MySQL et que vous savez vous en servir wink

tant que l'on a le nez dans notre fichier de conf (ejabberd.cfg), allez à la partie "Authentication", et commentez à l'aide de "%%" (et oui c'est du erlang) la ligne.
Ce qui donnera :

%%{auth_method, internal}.

Juste en dessous, cette fois décomenter, la partie ODBC (ainsi on indique à ejabberd, de ne pas utiliser ça base interne, mais une externe via connecteur ODBC).

%% Authentication using ODBC
%% Remember to setup a database in the next section.
%%
{auth_method, odbc}.

Comme nous l'indique si gentillement ejabberd, il nous faut configurer la BDD (on verra plus tard pour la remplir).
(n'oubliez pas de décommenter le début de la ligne !)

%%
%% MySQL server:
%%
{odbc_server, {mysql, "ip de mon serveur BDD", "nom BDD", "nom user BDD", "mot de passe user BDD"}}.

cette fois, c'est fini pour ce fichier de conf !
maintenant, commence les choses plus délicates, à savoir compiler le connecteur MySQL.

Commencez par installer subversion (pour récuper les fichiers sur le dépôt via svn).

# aptitude install subversion

on récupère les sources :

# cd /tmp
# svn co https://svn.process-one.net/ejabberd-modules/mysql trunk mysql

il va aussi nous falloir les sources de ejabberd (je vous avait bien dit qu'on allait y revenir ;) )
attention à bien récuper la bonne version des sources, il faut qu'elles correspondent à la version installée par le biais des paquets debian.

# wget http://www.process-one.net/downloads/ejabberd/2.1.10/ejabberd-2.1.10.tar.gz

on décompresse dans la foulé !

# tar xvzf ejabberd-2.1.10.tar.gz

bon les commandes qui suivent sont très simples, mais faute de doc/tuto j'ai pas mal cherché pour trouver comment procéder !
On retourne dans le répertoire du connecteur MySQL, et copie les fichiers sources dans le répertoire des sources de ejabberd.
Chez moi, ça donne :

# cd /tmp/mysql/mysql/trunk/src/
# cp * /tmp/ejabberd-2.1.10/src/

Maintenant on a besoin des outils pour compiler ce fameux connecteur :

# aptitude install erlang-tools make

ready ??

# cd /tmp/ejabberd-2.1.10/src/
# erl -pz ebin -make

Logiquement, si tout à bien fonctionné, on doit avoir nos fichiers *.beam dans le répertoire "ebin".

C'est bon pour moi cool

Capture d'écran - 21032013 - 12:13:14

Et on en fait quoi de ces fichiers ?

# cd /tmp/ejabberd-2.1.10/src/ebin/
# cp * /usr/lib/ejabberd/ebin/

Tant que l'on est dans le répertoire des sources de ejabberd, on récupère le script sql présent dans le répertoire "odbc".
Voici ce qu'il contient, vous allez devoir l'injecter dans la BDD que vous aurez créé à cet effet :

CREATE TABLE users (
    username varchar(250) PRIMARY KEY,
    password text NOT NULL,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;


CREATE TABLE last (
    username varchar(250) PRIMARY KEY,
    seconds text NOT NULL,
    state text NOT NULl
) CHARACTER SET utf8;


CREATE TABLE rosterusers (
    username varchar(250) NOT NULL,
    jid varchar(250) NOT NULL,
    nick text NOT NULL,
    subscription character(1) NOT NULL,
    ask character(1) NOT NULL,
    askmessage text NOT NULL,
    server character(1) NOT NULL,
    subscribe text NOT NULL,
    type text,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;

CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers(username(75), jid(75));
CREATE INDEX i_rosteru_username ON rosterusers(username);
CREATE INDEX i_rosteru_jid ON rosterusers(jid);

CREATE TABLE rostergroups (
    username varchar(250) NOT NULL,
    jid varchar(250) NOT NULL,
    grp text NOT NULL
) CHARACTER SET utf8;

CREATE INDEX pk_rosterg_user_jid ON rostergroups(username(75), jid(75));


CREATE TABLE spool (
    username varchar(250) NOT NULL,
    xml text NOT NULL,
    seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;

CREATE INDEX i_despool USING BTREE ON spool(username);


CREATE TABLE vcard (
    username varchar(250) PRIMARY KEY,
    vcard mediumtext NOT NULL,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;


CREATE TABLE vcard_search (
    username varchar(250) NOT NULL,
    lusername varchar(250) PRIMARY KEY,
    fn text NOT NULL,
    lfn varchar(250) NOT NULL,
    family text NOT NULL,
    lfamily varchar(250) NOT NULL,
    given text NOT NULL,
    lgiven varchar(250) NOT NULL,
    middle text NOT NULL,
    lmiddle varchar(250) NOT NULL,
    nickname text NOT NULL,
    lnickname varchar(250) NOT NULL,
    bday text NOT NULL,
    lbday varchar(250) NOT NULL,
    ctry text NOT NULL,
    lctry varchar(250) NOT NULL,
    locality text NOT NULL,
    llocality varchar(250) NOT NULL,
    email text NOT NULL,
    lemail varchar(250) NOT NULL,
    orgname text NOT NULL,
    lorgname varchar(250) NOT NULL,
    orgunit text NOT NULL,
    lorgunit varchar(250) NOT NULL
) CHARACTER SET utf8;

CREATE INDEX i_vcard_search_lfn       ON vcard_search(lfn);
CREATE INDEX i_vcard_search_lfamily   ON vcard_search(lfamily);
CREATE INDEX i_vcard_search_lgiven    ON vcard_search(lgiven);
CREATE INDEX i_vcard_search_lmiddle   ON vcard_search(lmiddle);
CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname);
CREATE INDEX i_vcard_search_lbday     ON vcard_search(lbday);
CREATE INDEX i_vcard_search_lctry     ON vcard_search(lctry);
CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality);
CREATE INDEX i_vcard_search_lemail    ON vcard_search(lemail);
CREATE INDEX i_vcard_search_lorgname  ON vcard_search(lorgname);
CREATE INDEX i_vcard_search_lorgunit  ON vcard_search(lorgunit);

CREATE TABLE privacy_default_list (
    username varchar(250) PRIMARY KEY,
    name varchar(250) NOT NULL
) CHARACTER SET utf8;

CREATE TABLE privacy_list (
    username varchar(250) NOT NULL,
    name varchar(250) NOT NULL,
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;

CREATE INDEX i_privacy_list_username  USING BTREE ON privacy_list(username);
CREATE UNIQUE INDEX i_privacy_list_username_name USING BTREE ON privacy_list (username(75), name(75));

CREATE TABLE privacy_list_data (
    id bigint,
    t character(1) NOT NULL,
    value text NOT NULL,
    action character(1) NOT NULL,
    ord NUMERIC NOT NULL,
    match_all boolean NOT NULL,
    match_iq boolean NOT NULL,
    match_message boolean NOT NULL,
    match_presence_in boolean NOT NULL,
    match_presence_out boolean NOT NULL
) CHARACTER SET utf8;

CREATE TABLE private_storage (
    username varchar(250) NOT NULL,
    namespace varchar(250) NOT NULL,
    data text NOT NULL,
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;

CREATE INDEX i_private_storage_username USING BTREE ON private_storage(username);
CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_storage(username(75), namespace(75));

-- Not tested in mysql
CREATE TABLE roster_version (
    username varchar(250) PRIMARY KEY,
    version text NOT NULL
) CHARACTER SET utf8;

-- To update from 1.x:
-- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask;
-- UPDATE rosterusers SET askmessage = '';
-- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL;

CREATE TABLE pubsub_node (
  host text,
  node text,
  parent text,
  type text,
  nodeid bigint auto_increment primary key
) CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120));
CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(20), node(120));

CREATE TABLE pubsub_node_option (
  nodeid bigint,
  name text,
  val text
) CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid);
ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;

CREATE TABLE pubsub_node_owner (
  nodeid bigint,
  owner text
) CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid);
ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;

CREATE TABLE pubsub_state (
  nodeid bigint,
  jid text,
  affiliation character(1),
  subscriptions text,
  stateid bigint auto_increment primary key
) CHARACTER SET utf8;
CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60));
CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state(nodeid, jid(60));
ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;

CREATE TABLE pubsub_item (
  nodeid bigint,
  itemid text,
  publisher text,
  creation text,
  modification text,
  payload text
) CHARACTER SET utf8;
CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36));
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36));
ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;

CREATE TABLE pubsub_subscription_opt (
  subid text,
  opt_name varchar(32),
  opt_value text
);
CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt(subid(32), opt_name(32));

 

Un dernier :

# /etc/init.d/ejabberd restart

Et tout devrait fonctionner !

Si pas d'erreur, on créé notre utilisateur (même commande qu'au début du tuto), vous pourrez aller faire un petit tour dans votre BDD vérifier si l'utilsateur est bien créé wink

# ejabberdctl register monutilisateuradmin sheldon.fr monsupermotdepasse

 

Et on va faire un petit essai à l'adresse suivante :

http://monserver:5280/admin

Et vous devriez obtenir l'interface web d'administration :

Capture d'écran - 21032013 - 13:19:30

 

Si cela ne fonctionne pas, il vous reste à aller faire un tour dans les logs (qui se trouvent dans /var/log/ejabberd/ ),
et vérifier que vous n'avez pas zappé une partie du tuto.

Si ça fonctionne et que vous êtes satisfait, vous pouvez vous connecter avec votre client favoris (comme Gajim, Pidgin …).
Ou via un client web comme Jappix (je ferais surement un article dessus plus tard.)

 

enjoy ;)

Vus : 581
Publié par Sheldon.fr : 17