diff options
-rwxr-xr-x | index.fr.html | 932 | ||||
-rwxr-xr-x | index.html | 855 | ||||
-rwxr-xr-x | styles.css | 192 |
3 files changed, 1979 insertions, 0 deletions
diff --git a/index.fr.html b/index.fr.html new file mode 100755 index 0000000..f0e62dc --- /dev/null +++ b/index.fr.html @@ -0,0 +1,932 @@ +<!DOCTYPE html> +<html lang="fr"> +<head> +<title>Mise en place d'un client web XMPP avec liens de création de compte (conversejs+prosody)</title> +<link rel='stylesheet' type='text/css' href='styles.css'> +<meta charset='utf-8'/> +</head> +<body> +<h1>Mise en place d'un client web XMPP avec liens de création de compte (conversejs+prosody)</h1> +<small>[<a href='partage.les-miquelots.net/blog/2021/index.html#mise-en-place-dun-client-web-xmpp-avec-liens-de-creation-de-compte-conversejsprosody'>lien</a>—<a href='index.fr.html'>billet seul</a>]</small> +<p><b>maj 28/05/2021</b>: corrections des iptables (régles dupliqués), ajout de liens de +documentation, ajout d'une entrée de DNS pour websocket. <samp>http_altconnect</samp> rajouté en module prosody +pour éviter les erreurs dans la console du navigateur +<p><b>maj 22/05/2021</b>: OMEMO par pas défaut au final, on laisse le choix à +l'utilisateur de l'activer dans ses discussions, et c'est mieux niveau historique des messages +sur plusieurs appareils. On améliore aussi la commande apt (-y --no-install-recommends). <br><br> +<p>Bonjour à tous, <br><br> +<p>Aujourd'hui je vais vous montrer comment mettre en place un serveur XMPP avec un +client Web sur la même machine, avec la +possibilité +d'envoyer des liens d'invitations de création de comptes ou d'ajout +en contact pour faciliter l'embarquement de vos proches et amis. +Je ne fais pas de présentation du protocole XMPP, c'est hors de la +portée de ce guide et des gens l'explique mieux que moi, je pense +surtout à <a +href="https://www.goffi.org/b/S%C3%A0T_DOTCLEAR_IMPORT_BLOG_default_goffi_99%3A2015%2F06%2F24%2FParlons-XMPP-%C3%A9pisode-1-les-bases">cette + suite d'articles de chez goffi.org</a>.<br> +<b>pavé césar gépalu lol</b>: c'est un protocole +composé d'une myriade de standards permettant +la construction de réseaux de messagerie instantanée +décentralisés et sécurisés. Possibilité d'avoir +des salons publics et privés. +<br><br> + +<p><div id="guide-sommaire"> + <u>Sommaire:</u> + <ol> + <li><a href="#xmpp-guide-prereq">Prérequis</a></li> + <li><a href="#xmpp-guide-dnszone">Configuration zone DNS</a></li> + <li><a href="#xmpp-guide-iptables">Configuration pare-feu</a></li> + <li><a href="#xmpp-guide-pkgs">Installation des + paquets</a></li> + <li><a href="#xmpp-guide-certs">Installation des + certificats</a></li> + <li><a href="#xmpp-guide-confpkgs">Configuration des + paquets</a></li> + <li><a href="#xmpp-guide-con">Connexion à l'interface web</a></li> + <li><a href="#xmpp-guide-genlinks">Génération des liens d'invitation</a></li> + + <li><a href="#xmpp-guide-remarks">Remarques</a></li> + <li><a href="#xmpp-guide-docs">Documentations</a></li> + <li><a href="#xmpp-guide-thanks">Remerciements</a></li> + </ol> + </div> + <br><br> + +<h3 id="xmpp-guide-prereq"><a href="#xmpp-guide-prereq">1. +Prérequis</a></h3> + +<p>Trêve de bavardages, voici ce que l'on va devoir installer: +<ul> + <li><samp>certbot</samp>: génération des certificats + pour renforcer la sécurité de la communication + client=>serveur et serveur<=>serveur.</li> + <li><samp>prosody</samp>: le serveur XMPP, la pièce maîtresse.</li> + <li><samp>nginx</samp>: le proxy inversé qui gérera les + connexions à l'interface web et les connexions <span + style="color:green"><b>HTTPS</b></span>.</li> + <li><samp>conversejs</samp>: l'interface web pour notre serveur XMPP.</li> + <li><samp>libjs-bootstrap4 libjs-jquery</samp>: le module + <samp><a + href="https://modules.prosody.im/mod_invites.html#external-dependencies" + target="_blank" rel="noopener" >mod_invites</a></samp> de Prosody a + besoin de ces bibliothèques pour le CSS et bouts de JavaScript. + <li><samp>hg</samp>: pour cloner le dépôt des modules de + <samp>prosody</samp> et les maintenir à jour.</li> +</ul><br> + + +<p>Mettez-vous d'accord sur votre nom de domaine: vous remplacerez les +occurences de <samp>exemple.fr</samp> dans ce guide par votre +nom de domaine. On va aussi utiliser un sous-domaine pour +l'interface web, <samp>chat.exemple.fr</samp>, un qui contiendra les +salons publics et privés, <samp>salons.exemple.fr</samp> et un +autre pour le serveur d'envoi de fichiers, +<samp>f.exemple.fr</samp>.<br> +N'oubliez pas de rajouter des entrées DNS type A pour ces +sous-domaines. +<br><br> + +<h3 id="xmpp-guide-dnszone"><a href="#xmpp-guide-dnszone">2. Configuration zone DNS</a></h3> +<p>Tout d'abord, rendez-vous dans la zone DNS de votre nom de domaine, on va +rajouter quelques entrées de type SRV et TXT pour faciliter la +communication des clients et serveurs XMPP avec nous (plus de +détails en anglais <a +href="https://wiki.xmpp.org/web/SRV_Records">par là</a> ou <a +href="https://prosody.im/doc/dns">encore ici</a>): +<pre> +_xmpp-client._tcp.exemple.fr 86400 SRV 1 1 5222 exemple.fr. +_xmpps-client._tcp.exemple.fr 86400 SRV 1 1 5223 exemple.fr. +_xmpp-server._tcp.exemple.fr 86400 SRV 1 1 5269 exemple.fr. +_xmppconnect.exemple.fr TXT _xmpp-client-xbosh=https://chat.exemple.fr/http-bind +_xmppconnect.exemple.fr TXT _xmpp-client-websocket=wss://chat.example.fr/xmpp-websocket +</pre> + +<p><b>À noter:</b> le <samp>exemple.fr</samp> à de gauche +reprénte le domaine XMPP, celui de droite est le serveur qui +répondra aux requêtes et une entrée DNS de type A +doit exister pour celui-ci, pas de raccourci type CNAME autorisé. +C'est pratique quand vous voulez des adresses utilisateurs "propres" tel +que <u>vous@exemple.fr</u> mais que le serveur est en fait sur le +sous-domaine <samp>xmpp.exemple.fr</samp>. Si c'est le cas, changez +alors le <samp>exemple.fr</samp> de droite par +<samp>xmpp.exemple.fr</samp>.<br><br> + + +<h3 id="xmpp-guide-iptables"><a href="#xmpp-guide-iptables">3. Configuration pare-feu</a></h3> +<p><b><u>IMPORTANT</u>:Connectez-vous en tant que root avant d'exécutez les +commandes contenues dans +ce tutoriel</b>. On va ensuite configurer des règles +<samp>iptables</samp> pour éviter de se mordre les doigts +de rage par la suite. Je pars du principe que vous avez déjà + configuré quelques règles vous permettant de SSH tranquillou. + +<pre> +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT # on accepte les connexions client à serveur +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT # pareil que le dessus mais celles qui sont chiffrés. +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT # connexions serveur à serveur. +iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web +iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requête DNS +iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilisant l'HTTP upload pour les pjs +iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT + +iptables-save > /etc/iptables/iptables.rules + + +# pareil pour l'ipv6 +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT +ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web +ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +ip6tables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requête DNS +ip6tables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilise l'HTTP upload pour les pjs +ip6tables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT + +ip6tables-save > /etc/iptables/ip6tables.rules +systemctl enable --now iptables # activation du service iptables si pas +# déjà fait pour garder la config du pare-feu après reboot. +</pre><br> + +<h3 id="xmpp-guide-pkgs"><a href="#xmpp-guide-pkgs">4. Installation des paquets</a></h3> + +<p>Après ceci, installez <samp>prosody</samp> depuis <a +href="https://prosody.im/doc/installing_from_source">les sources</a> ou +votre <a href="https://prosody.im/download/start">installeur de +paquets</a>. On en profitera pour installer les autres composants requis +à ce guide. Sur un Debian classique celà donnera:<br> +<pre>sudo apt-get install -y --no-install-recommends prosody nginx-full \ +certbot python3-certbot-nginx \ +mercurial libjs-bootstrap4 libjs-jquery</pre><br> + +<p>On va maintenant cloner les <samp>prosody-modules</samp> depuis la +source. Il n'est pas toujours à jour dans les dépôts de +paquets: +<pre> +hg clone https://hg.prosody.im/prosody-modules/ /usr/lib/prosody/modules/ +</pre> +<p>On prépare en même temps un script pour mettre +à automatiquement via la crontab. Créez le fichier +<samp>/usr/local/sbin/maj_prosodymods.sh</samp> avec le contenu suivant: +<pre> +#!/bin/sh +MODDIR="/usr/lib/prosody/modules/" + +if test -d $MODDIR; then + cd $MODDIR + hg pull --update +else + mkdir -p /usr/lib/prosody + hg clone https://hg.prosody.im/prosody-modules/ $MODDIR +fi +</pre> +<p>N'oubliez pas de faire un coup de <samp>chmod +x</samp> dessus... +<br><br> + +<p>On va ensuite télécharger <samp>conversejs</samp>. +À ce jour sur Debian Buster, il n'y a pas de paquet à jour +officiel pour <samp>conversejs</samp>, donc on va faire un script qu'on +intégrera dans notre crontab.<br> +Insérez le contenu suivant +dans le fichier <samp>/usr/local/sbin/update_conversejs.sh</samp> puis +rendez-le exécutable: +<pre> +#!/bin/sh +TEMPDIR="$(mktemp -d)" +LOG=/var/log/update_conversejs.log +WWWDIR='/var/www/chat.exemple.fr' +WWWUSER='www-data' # cette valeur sera sûrement différente + # si vous n'êtes pas sur Debian avec nginx. + # par ex. ça sera 'http' sous Arch avec nginx. + +mkdir -p $WWWDIR/dist +cd $TEMPDIR +printf "\n\n$(date) - INFO - Starting updating conversejs..." | tee -a $LOG +CURL_ERR=$(curl -s \ + https://api.github.com/repos/conversejs/converse.js/releases/latest | \ + grep -o "https://.*\.tgz" | \ + grep converse\.js- | \ + xargs curl -fsOJL) || \ + (printf "\n$(date) - ERR - Updating conversejs failed." | tee -a $LOG && exit) + +# on installe libsignal pour pouvoir utiliser OMEMO +# dans le client web +if test -e "$WWWDIR/dist/libsignal-protocol.min.js"; then + printf "\n$(date) - TOK - Libsignal already installed, skipping." | tee -a $LOG +else + curl -fsOJL \ + https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js || \ + (printf "\n$(date) - ERR - Updating libsignal-protocol-javascript failed." | \ + tee -a $LOG) + cp libsignal*.js $WWWDIR/dist/ +fi + +tar xzf *.tgz +cp -rf package/dist $WWWDIR/ +sed "s/fullscreen\.html/index\.html/g" package/manifest.json > $WWWDIR/manifest.json +chown $WWWUSER:$WWWUSER -R $WWWDIR/ +chmod 755 -R $WWWDIR/ +rm -rf $TEMPDIR +printf "\n$(date) - TOK - Done." | tee -a $LOG +</pre> +<p>Exécutez ce fichier pour gagner du temps dans l'<a +href="#xmpp-guide-confpkgs">étape 6</a>, vous n'aurez pas à +créer le <samp>$WWWDIR</samp>. + +<h3 id="xmpp-guide-certs"><a href="#xmpp-guide-certs">5. Installation des +certificats</a></h3> + + +<p>On va ensuite lancer certbot pour générer des certificats. +Je pars du principe que vous avez configuré les entrées de +type A pour <samp>exemple.fr</samp>, <samp>chat.exemple.fr</samp> +et <samp>f.exemple.fr</samp> dans votre zone DNS: +<pre>certbot certonly --agree-tos --nginx --deploy-hook "prosodyctl --root cert import /etc/letsencrypt/live" -d chat.exemple.fr -d exemple.fr -d f.exemple.fr -d salons.exemple.fr </pre> +<p>Une fois que cette commande s'exécute avec succés, des +dossiers correspondants aux domaines demandés devrait +apparaître dans <samp>/etc/letsencrypt/live/</samp>. +<br><br> + +<h3 id="xmpp-guide-confpkgs"><a href="#xmpp-guide-confpkgs">6. Configuration des +paquets</a></h3> + +<p>Le moment est venu! On va tâter â prosody et sa +configuration.<br> +Ouvrez le fichier <samp>/usr/lib/prosody/net/http/server.lua</samp>, on va simplifier la +connexion entre l'interface HTTP de prosody (BOSH) et nginx.<br> +Dans le +fichier, trouver la ligne suivante: +<pre> +headers = { date = date_header, connection = response_conn_header }; +</pre> +<p>et remplaçez la par: +<pre> +headers = { date = date_header, connection = response_conn_header, + access_control_allow_origin = "exemple.fr" }; +-- si 'exemple.fr' ne résout pas le soucis de connexion, mettez +-- un '*' à la place. Pour rappel, c'est l'adresse du serveur XMPP +-- qui faut mettre, et non celle du domaine. +</pre><br> + +<p>Ensuite, on va s'occuper du script qui permettra d'envoyer des fichiers +à d'autres utilisateurs. Exécutez ceci: +<pre> +mkdir -p /var/www/upload +chown www-data:www-data /var/www/upload # l'utilisateur de nginx peut + # différer selon la distrib, faites gaffe +mkdir -p /usr/local/lib/perl +wget -O /usr/local/lib/perl/upload.pm https://raw.githubusercontent.com/weiss/ngx_http_upload/master/upload.pm +</pre> +<p>Ouvrez le fichier <samp>upload.pm</samp>, cherchez un bout de texte +ressemblant à <samp>my $external_secret = 'it-is-secret';</samp> +et changez le <samp>it-is-secret</samp> par un mot de passe fort, de +préfèrence sans apostrophe ou antislash pour éviter +que le programme en Perl plantouille quand on va tout démarrer.<br> +Notez-vous ce mot de passe sur un bout de papier, on va en avoir besoin +derechef.<br><br> + +<p>Passons à la configuration de prosody: éditez le fichier + <samp>/etc/prosody/prosody.cfg.lua</samp> avec les informations +suivantes: +<pre> +admins = { "vous@exemple.fr" } + +-- For more information see: https://prosody.im/doc/libevent +-- use_libevent = true + +plugin_paths = { "/usr/lib/prosody/modules" } + +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "carbons"; -- Keep multiple clients in sync + "carbons_copies"; + "carbons_copies_adhoc"; + "pep"; -- Enables users to publish their avatar, mood, activity, playing music and more + "private"; -- Private XML storage (for room bookmarks, etc.) + "blocklist"; -- Allow users to block communications with other users + "vcard4"; -- User profiles (stored in PEP) + "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard + "smacks"; + "bookmarks"; -- vieux module mais compatible avec la + -- majorité des clients XMPP contrairement + -- à bookmarks2 + --"bookmarks2"; + "presence"; -- voir l'état de l'utilisateur (en ligne, hors + -- ligne, etc...) + "offline"; + + -- Nice to have + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "register"; -- Allow users to register on this server using a client and change passwords + "mam"; -- Store messages in an archive and allow users to access it + "csi"; + "csi_simple"; -- Simple Mobile optimizations + "csi_battery_saver"; + "vjud"; -- recherche d'utilisateurs dans les salons + + -- Admin interfaces + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + + -- HTTP modules + "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + "websocket"; -- XMPP over WebSockets + "http_altconnect"; + + -- Other specific functionality + "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + "limits"; -- Enable bandwidth limiting for XMPP connections + "groups"; -- Shared roster support + "server_contact_info"; -- Publish contact information for this service + "announce"; -- Send announcement to all online users + "welcome"; -- Welcome users who register accounts + "watchregistrations"; -- Alert admins of registrations + "motd"; -- Send a message to users when they log in + --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use +} + +-- These modules are auto-loaded, but should you want +-- to disable them then uncomment them here: +modules_disabled = { + -- "offline"; -- Store offline messages + -- "c2s"; -- Handle client connections + -- "s2s"; -- Handle server-to-server connections +} + +motd_text = [[Bonjour à tous ! Bienvenue sur mon serveur XMPP. Clavardez heureux !]] +welcome_message = "C'est ta première connexion, $username. Bienvenue à toi." + +daemonize = false; +pidfile = "/run/prosody/prosody.pid"; +trusted_proxies = { "127.0.0.1", "::1" } + +-- Force certificate authentication for server-to-server connections +c2s_require_encryption = true -- chiffrement requis pour connexion client à serveur +s2s_require_encryption = true -- chiffrement requis pour connexion entre serveurs +s2s_secure_auth = true +authentication = "internal_hashed" + +-- mam settings +archive_expires_after = "never" -- historique permanent des chats + +log = { + -- Log files (change 'info' to 'debug' for debug logs): + info = "/var/log/prosody/prosody.log"; + error = "/var/log/prosody/prosody.err"; + -- Syslog: + { levels = { "error" }; to = "syslog"; }; +} + +-- http and certificate shenanigans +certificates = "certs" + +-- Include "conf.d/*.cfg.lua" + +legacy_ssl_ports = { 5223 } +-- http_ports = { 5280 } +-- http_interface = { "*" } +-- https_ports = { 5281 } +-- https_interfaces { "*" } + + +cross_domain_bosh = { "https://chat.exemple.fr" } +cross_domain_websocket = { "https://chat.exemple.fr" } +consider_bosh_secure = true +consider_websocket_secure = true +allow_registration = true -- nécessaire pour mod_invites +registration_invite_only = true -- inscription autorisé seulement avec les invitations +vjud_mode = "opt-in" -- l'utilisateur doit consentir pour que la recherche vjud + -- le fasse remonter dans les résultats. + +-- https://prosody.im/security/advisory_20210512/ +gc = { + speed = 500; +} +c2s_stanza_size_limit = 256 * 1024 +s2s_stanza_size_limit = 512 * 1024 + +limits = { + c2s = { + rate = "10kb/s"; + }; + s2sin = { + rate = "3kb/s"; + }; +} +-- https://prosody.im/security/advisory_20210512/ + +ssl = { + key = "certs/exemple.fr.key"; + certificate = "certs/exemple.fr.crt"; +} + +VirtualHost "exemple.fr" + invites_page = "https://chat.exemple.fr/invite?{invite.token}" + webchat_url = "https://chat.exemple.fr/" + http_external_url = "https://chat.exemple.fr/" + invite_expiry = 86400 * 7 -- 7 jours avant qu'un lien d'invitation expire + http_paths = { + invites_page = "/invite"; + invites_register_web = "/register"; + } + + modules_enabled = { + "invites"; + "invites_adhoc"; + "invites_page"; + "invites_register"; + "invites_register_web"; + "http_libjs"; + } + + contact_info = { + abuse = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + admin = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + security = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + support = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + }; + + https_certificate = "certs/exemple.fr.crt"; + ssl = { + key = "certs/exemple.fr.key"; + certificate = "certs/exemple.fr.crt"; + } + + Component "f.exemple.fr" "http_upload_external" + http_upload_external_base_url = "https://f.exemple.fr/" + http_upload_external_secret = "its-a-secret" + http_upload_external_file_size_limit = 104857600 -- limite de à 100Mo pour les envois de pjs + ssl = { + key = "certs/f.exemple.fr.key"; + certificate = "certs/f.exemple.fr.crt"; + } + + Component "salons.exemple.fr" "muc" + name = "Salons (chatrooms) chez exemple.fr" + modules_enabled = { "muc_mam", "vcard_muc" } + muc_room_default_language = "fr" + muc_log_expires_after = "never" -- histo permanent des groupes de + -- chats + log_all_rooms = true + muc_log_by_default = true + muc_log_presences = false + restrict_room_creation = "admin" -- seul l'admin peut créer des salons + ssl = { + key = "certs/salons.exemple.fr.key"; + certificate = "certs/salons.exemple.fr.crt"; + } +</pre> +<p>Oui, il faut remplaçer <u><samp>its-a-secret</samp></u> par le +mot de passe que vous avez noté tout à l'heure.<br> +Certains auront aussi remarqué qu'on a défini un utilisateur +administrateur au début du fichier de config, +<u>vous@exemple.fr</u>. On va donc créer l'utilisateur avec la +commande: +<pre> +prosodyctl check # ça va vérifier si y'a des soucis dans la configuration +prosodyctl adduser vous@exemple.fr +</pre><br> + +<p>Créez le fichier +<samp>/var/www/chat.exemple.fr/index.html</samp> avec le texte suivant: +<pre> +<!DOCTYPE html> +<html class="no-js" lang="en"> + <head> + <title>Converse</title> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content="Converse XMPP/Jabber Chat"/> + <meta name="keywords" content="xmpp chat webchat converse.js" /> + <link rel="manifest" href="/manifest.json"> + <link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" /> + <script src="/dist/libsignal-protocol.min.js"></script> + <script src="/dist/converse.min.js"></script> + </head> + <body class="converse-fullscreen"> + <noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript> + <div id="conversejs-bg"></div> + <script> + /* + @licstart + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to <http://unlicense.org/> + @licend + */ + converse.initialize({ + auto_away: 300, //absent au bout de 5minutes + auto_list_rooms: true, + auto_reconnect: true, + auto_xa: 600, //absence prolongée au bout de 10minutes + bosh_service_url: 'https://chat.exemple.fr/http-bind/', + csi_waiting_time: 60, + enable_smacks: true, + i18n: 'fr', // pour avoir l'interface en français + locked_domain: exemple.fr, // on verouille le domaine autoriséà se connecter + message_archiving: 'always', + persistent_store: 'IndexedDB', // jcbrand a dit qu'en 8.0.0 + play_sounds: true, + // ça va aller plus vite avec l'IndexedDB + theme: 'concord', + view_mode: 'fullscreen', + websocket_url: 'wss://chat.exemple.fr/xmpp-websocket', + }); + </script> + </body> +</html> +</pre><br> + +<p>C'est presque la fin de ce guide ! On va maintenant créer les +fichiers de configuration nginx. <br> +Créons <samp>/etc/nginx/sites-enabled/exemple.fr.conf</samp> pour +commencer: +<pre> +server { + listen 80; + server_name exemple.fr; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl; + server_nam exemple.fr; + ssl_certificate /etc/letsencrypt/live/exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/exemple.fr/privkey.pem; + + # this block is for the prosody's http_altconnect module + location ~* host-(meta|meta\.json) { + proxy_pass http://example.com:5280$uri; + proxy_http_version 1.1; + } +} +</pre><br> + +<p>Ensuite, créez +<samp>/etc/nginx/sites-enabled/f.exemple.fr.conf</samp>, ce sera pour le +composant +qui gérera les pièces jointes: +<pre> +perl_modules /usr/local/lib/perl; # Path to upload.pm. +perl_require upload.pm; + +server { + listen 80; + server_name f.exemple.fr; + location / { + return 301 https://$host$request_uri; + } +} + +server { + # Specify directives such as "listen", "server_name", and TLS-related + # settings for the "server" that handles the uploads. + listen 443 ssl http2; + server_name f.exemple.fr; + + ssl_certificate /etc/letsencrypt/live/f.exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/f.exemple.fr/privkey.pem; + # Uploaded files will be stored below the "root" directory. To minimize + # disk I/O, make sure the specified path is on the same file system as + # the directory used by Nginx to store temporary files holding request + # bodies ("client_body_temp_path", often some directory below /var). + root /var/www/upload; + index index.html; + # Specify this "location" block (if you don't use "/", see below): + location / { + perl upload::handle; + } + + # Upload file size limit (default: 1m), also specified in your XMPP + # server's upload module configuration (see below): + client_max_body_size 100m; +} +</pre> +<p>Exécutez <samp>nginx -t</samp> pour tester la configuration. Si +aucune erreur n'est détectée, créer le fichier +<samp>/etc/nginx/sites-enabled/chat.exemple.fr.conf</samp>: +<pre> +server { + listen 80; + server_name chat.exemple.fr; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl http2; + ssl_certificate /etc/letsencrypt/live/chat.exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/chat.exemple.fr/privkey.pem; + root /var/www/chat.exemple.fr; + index index.html; + + # XMPP BOSH + location ^~ /http-bind { + proxy_pass https://exemple.fr:5281/http-bind; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP HTTP-Upload + location ^~ /upload { + proxy_pass https://f.exemple.fr; proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP Websockets + location /xmpp-websocket { + proxy_pass http://exemple.fr:5280/xmpp-websocket; + proxy_http_version 1.1; + proxy_buffering off; + proxy_set_header Connection "Upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900s; + } + + # XMPP Account invite + location ^~ /invite { + proxy_pass https://exemple.fr:5281/invite; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP account register + location ^~ /register { + proxy_pass https://exemple.fr:5281/register; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # sur mon vps debian j'ai eu besoin de ça pour + # que les pages d'invitation soit bien + # formatées + location = /share/bootstrap4/css/bootstrap.min.css { + alias /usr/lib/nodejs/bootstrap/dist/css/bootstrap.min.css; + } + + location = /share/jquery/jquery.min.js { + alias /usr/lib/nodejs/jquery/dist/jquery.min.js; + } + + location = /share/bootstrap4/js/bootstrap.min.js { + alias /usr/lib/nodejs/bootstrap/dist/js/bootstrap.min.js; + } + +} +</pre> +<p>Exécutez de nouveau <samp>nginx -t</samp> pour détecter +d'éventuels problèmes de configuration. Une fois que tout +est OK, ajoutez la ligne <samp>127.0.0.1 exemple.fr</samp> +dans le fichier <samp>/etc/hosts</samp>.<br> +Redémarrez le serveur Prosody et Nginx: +<pre> +systemctl start prosody nginx +# ou +prosodyctl start && nginx -s reload +</pre><br> + +<h3 id="xmpp-guide-con"><a +href="#xmpp-guide-con">7. Connexion à l'interface web:</a></h3> +<p>Rendez-vous maintenant sur la page web du chat: pour notre +guide ça serait <a +href="https://chat.exemple.fr">https://chat.exemple.fr</a> +, adaptez avec ce que vous avez.<br> +Vous devriez voir quelque chose comme ça:<br> +<a href="img/conversejs_login.png"><img +src="img/conversejs_login.png"></a> + +<p><b>Petite astuce</b>: si vous voulez vous connecter avec l'utilisateur +<u><samp>vous@exemple.fr</samp></u> vous pouvez omettre la partie droite +de votre adresse, comme ceci:<br> +<a href="img/conversejs_logintrick.png"><img +src="img/conversejs_logintrick.png"></a> + +<p>C'est grâce à la configuration de +<samp><a +href="https://conversejs.org/docs/html/configuration.html?highlight=locked_domain#locked-domain" +target="_blank" rel="noopener">locked_domain</a></samp> lors de l'initialisation de Converse.js.<br> +Une fois connecté, l'interface ressemblera a ceci:<br> +<a href="img/conversejs_main.png"><img +src="img/conversejs_main.png"></a> + +<p>Vous pouvez alors commencer à utiliser XMPP et rejoindre ou +créer des salons, ajouter des contacts et bien sûr discuter depuis +cette interface web !<br><br> + +<h3 id="xmpp-guide-genlinks"><a href="#xmpp-guide-genlinks">8. +Génération des liens d'invitation</a></h3> + +<p>La chose qui nous intéresse surtout c'est la création +de liens d'invitation accessible depuis le Web.<br> +Pour ce faire, cliquez gauche sur la roue dentée en haut à gauche +à côté de votre nom, cliquez sur <u>Commandes</u>. +Dans le champ <u>"Sur quelle entité voulez-vous lancer des +commandes ?"</u> rentrez le nom de votre serveur XMPP, puis cliquez sur +<u>"Lister les commandes disponibles"</u>. Vous devez avoir quelque chose +de similaire à ceci:<br> +<a href="img/conversejs_adhoc1.png"><img +src="img/conversejs_adhoc1.png"></a><br> + +<p>Descendez un peu jusqu'à voir <u>"Create new contact invite"</u> +et cliquez dessus:<br> +<a href="img/conversejs_adhoc2.png"><img +src="img/conversejs_adhoc2.png"></a><br> +Une invitation s'est créée ! Vous pouvez alors copier le texte +contenu dans <u>"Invite web page"</u> et l'envoyer à l'un de vos amis, +proches, etc...<br> +Une fois ouvert, le lien amène sur une page de ce type:<br> +<a href="img/conversejs_invitepage.png"><img +src="img/conversejs_invitepage.png"></a><br> +<p>La page détecte automatiquement votre plateforme et vous propose +des applications XMPP natives en fonction. Dans le cas ou la plateforme +est un smartphone, ça aménera sur la page de +téléchargement de l'application puis ouvrira celle-ci tout +en continuant l'inscription.<br> +Le lien entouré de rouge +en bas avec le texte <u>"register an account manually"</u> permet de +s'inscrire via un formulaire web. Pratique pour juste créer le +compte et le tester plus tard. Voici à quoi ça +ressemble:<br> +<a href="img/conversejs_register1.png"><img +src="img/conversejs_register1.png"></a><br> +<p>Vous pouvez voir que j'ai commencé a remplir le formulaire: une +fois l'inscription envoyée en cliquant sur le bouton +<u>"Submit"</u>, vous serez accueilli par l'écran +suivant:<br> +<a href="img/conversejs_register2.png"><img +src="img/conversejs_register2.png"></a><br> +<p>Une page vous confirmant votre inscription s'affiche, avec la +possibilité de montrer de nouveau le mot de passe saisie lors de +l'inscription ou cas où (le bouton <u>"Show"</u>).<br> +Le bouton entoûré de rouge, <u>"Log in via web"</u>, +permettra +à l'utilisateur inscrit de se connecter à l'interface web +configurée pendant ce tutoriel, et il vous aura en tant que +contact.<br> +<a href="img/conversejs_chatting.png"><img +src="img/conversejs_chatting.png"></a><br> + +<h3 id="xmpp-guide-remarks"><a href="#xmpp-guide-remarks">9. Remarques</a></h3> +<p>Le guide se finit ici! Je reviendrais pour corriger quelques fautes, +étourderies et oublis si j'en aperçois. +J'ai des remarques à faire sur le logiciel: +<ul style="list-style:disclosure-closed"> + <li>Les messages chiffrés OMEMO ne semblent pas lisibles entres + clients Converse.js. L'envoyeur peut lire son message OMEMO, mais si + le destinataire utilise uniquement converse.js, il y a de fortes + chances qu'il voit un message du type <u>"Ceci est un message chiffré + avec OMEMO, que votre client ne semble pas prendre en charge..."</u>. + Des clients tel que Gajim ou Dino n'ont pas de soucis de ce + côté là d'aprés mon expérience. J'ai + peut-être aussi une erreur de configuration...</li> + <li>Je vous conseille d'utilisateur un seul navigateur pour + Converse.js si vous aimez avoir un historique des messages consistant.</li> + <li>Le chiffrement des pièces jointes n'est pas encore + implémenté (source: @jcbrand dans le salon + discuss@conference.conversejs.org).</li> + <li>Si vous voulez traduire en français les pages + d'inscriptions, je vous invite à regarder le code source des + modules <samp>mod_invites_pages</samp>, <samp>mod_register_web</samp> + et <samp>mod_register_apps</samp>. +</ul> + +<h3 id="xmpp-guide-docs"><a href="#xmpp-guide-docs">10. +Documentations</a></h3> +<p>Ces liens m'ont bien aidé: + <ul style="list-style:square"> + <li><b>Converse.js</b>: <a + href="https://conversejs.org/docs/html/index.html" target="_blank" + rel="noopener">Général</a>, <a + href="https://conversejs.org/docs/html/configuration.html#configuration-settings" + target="_blank" + rel="noopener">paramétrage et initialisation</a>, lire le code source HTML de la page <a + href="https://inverse.chat" target="_blank" rel="noopener">https://inverse.chat</a> + + </li> + <li><b>Prosody</b>: <a + href="https://prosody.im/doc" target="_blank" rel="noopener">Général</a>, <a + href="https://prosody.im/doc/setting_up_bosh" target="_blank" + rel="noopener">BOSH+Nginx</a>, + <a href="https://prosody.im/doc/websocket" target="_blank" + rel="noopener">Websockets+Nginx</a>, + <a href="https://modules.prosody.im/xeps.html" target="_blank" + rel="noopener">Liens XEPs <=> + modules</a>, le <a + href="https://modules.prosody.im/mod_invites.html" target="_blank" + rel="noopener">module d'inscription via invitation</a>, le <a + href="https://modules.prosody.im/mod_http_upload_external.html" + target="_blank" rel="noopener">module d'envoi de fichiers via + script externe</a> et l'implémentation d'Holger (<a + href="https://github.com/weiss/ngx_http_upload" target="_blank" + rel="noopener">upload.pm</a>).</li> + + <li><b>XMPP</b>: <a href="https://wiki.xmpp.org/">le wiki officiel</a>, <a href="https://compliance.conversations.im/"> + tests de compliance des serveurs</a>. + </ul> + +<h3 id="xmpp-guide-thanks"><a href="#xmpp-guide-thanks">11. +Remerciements</a></h3> +<p>Tout ceci n'aurait pas été possible sans les logiciels +libres et leurs collaborateurs. Merci à vous.<br> +Plus spécifiquement: +<ol style="list-style:square"> + <li><a href="https://blog.laxu.de">laxu.de</a>, l'auteur de <a + href="https://blog.laxu.de/2018/09/08/conversejs-prosody/"> + https://blog.laxu.de/2018/09/08/conversejs-prosody/</a>, pour le patch de + <samp>net/http/server.lua</samp> et les bouts de configuration nginx</li> + <li><a href="https://qorg11.net/">qorg</a> pour son guide sur XMPP, plus + particulièrement l'"HTTP upload" + (<a + href="https://kill-9.xyz/guides/xmpp_server" target="_blank" + rel="noopener">https://kill-9.xyz/guides/xmpp_server</a>)</li> + <li> <a + href="https://wiki.xmpp.org/web/Jan-Carel_Brand_Application_2021" + target="_blank" rel="noopener">jcbrand</a>, l'auteur et + développeur principal de <a + href="https://conversejs.org/" target="_blank" + rel="noopener">Converse.js</a>. Très réactif aux + questions concernant XMPP et Converse.js dans le salon <a + href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>.</li> + <li><a href="xmpp:holger@jabber.fu-berlin.de?message">Holger Weiß</a>, + développeur travaillant sur le serveur XMPP ejabberd et admin du salon + <a + href="xmpp:ejabberd@conference.process-one.net?join">ejabberd@conference.process-one.net</a> + qui a pris de son temps pour me dépanner (<a + href="https://partage.les-miquelots.net/blog/un-rappel-lorsque-vous-mettez-en-place-un-serveur-xmpp-avec-prosody.html">le + problème en question</a>).</li> +</ol><br> + +<p>À bientôt, passez une excellente journée et si vous +avez des questions, remarques, suggestions ou améliorations +à me faire part, n'hésitez pas à me contacter via +mail ou XMPP à l'adresse <u>lionel ( @ ) les-miquelots ( . ) +net</u>. +<footer>par <strong><a href='http://partage.les-miquelots.net/'>Miquel Lionel</a></strong></footer> +</body> + +</html> diff --git a/index.html b/index.html new file mode 100755 index 0000000..ab6b6e2 --- /dev/null +++ b/index.html @@ -0,0 +1,855 @@ +<!DOCTYPE html> +<html + lang="en"> +<head> +<title>Setting up a XMPP server with a web client (converse.js+nginx+prosody on Debian)</title> +<link rel='stylesheet' + type='text/css' href='styles.css'> +<meta + charset='utf-8'/> +</head> +<body> +<h1>Setting up a XMPP server with a web client (converse.js+nginx+prosody on Debian)</h1> +<small>[<a + href='partage.les-miquelots.net/blog/2021/index.html#setting-up-a-xmpp-server-with-a-web-client-conversejsnginxprosody-on-debian'>link</a>—<a href='index.html'>standalone</a>]</small> +<p><b>27/05/2021</b>: add the <samp>http_altconnect</samp> module to prosody config to avoid errors whining about <samp>/.well-known/host-meta</samp> not being present<br> +<p><b>22/05/2021</b>: don't enable OMEMO by default, we let the users make its own choices and it can be better +for multi-device history. I improved the apt command too (with <samp>-y --no-install-recommends</samp>).<br><br> + +<p>Hi everyone,<br><br> +<p>Today we're going to install a XMPP server with a web client that is capable to +send invites links to ease the onboarding of your friends and family.<br> +I won't explain what is XMPP in great details, because it's outside the scope of this +guide and some people will explain <i>faaar</i> better than me. I'm thinking about <a +href="https://www.goffi.org/b/S%C3%A0T_DOTCLEAR_IMPORT_BLOG_default_goffi_99%3A2015%2F06%2F24%2FParlons-XMPP-%C3%A9pisode-1-les-bases">these +articles on goffi.org (french blog)</a>. For english readers, the <a href="https://wiki.xmpp.org/web/Technology_overview" target="_blank" rel="noopener">official wiki</a> is a good start.<br> +<b>tl;dr</b>: it's a protocol made of various standards and it's possible to build + secure decentralized instant messaging networks with it. There are possibilities + to create public and private rooms too, like any popular modern instant messaging software. +<br><br> + +<p><div id="guide-sommaire"> + <u>Table of matters:</u> + <ol> + <li><a href="#xmpp-guide-prereq">Prerequisites</a></li> + <li><a href="#xmpp-guide-dnszone">DNS zone configuration</a></li> + <li><a href="#xmpp-guide-iptables">Firewall configuration</a></li> + <li><a href="#xmpp-guide-pkgs">Packages setup</a></li> + <li><a href="#xmpp-guide-certs">Certificates setup</a></li> + <li><a href="#xmpp-guide-confpkgs">Packages configuration</a></li> + <li><a href="#xmpp-guide-con">Discovering the webclient</a></li> + <li><a href="#xmpp-guide-genlinks">Invite links generation</a></li> + + <li><a href="#xmpp-guide-remarks">Remarks</a></li> + <li><a href="#xmpp-guide-docs">Documentations</a></li> + <li><a href="#xmpp-guide-thanks">Thanks</a></li> + + + </ol> + </div> + <br><br> + +<h3 id="xmpp-guide-prereq"><a href="#xmpp-guide-prereq">1. +Prerequisites</a></h3> + +<p>Enough talking, this is what we're going to install: +<ul> + <li><samp>certbot</samp>: to generate certificates to secure client=>server and server<=>server communication.</li> + <li><samp>prosody</samp>: the XMPP server and the most important piece.</li> + <li><samp>nginx</samp>: reverse proxy that'll handle <span + style="color:green"><b>HTTPS</b></span> and connecting to the XMPP web client.</li> + <li><samp>conversejs</samp>: the web client for our XMPP server.</li> + <li><samp>libjs-bootstrap4 libjs-jquery</samp>: the + <samp><a + href="https://modules.prosody.im/mod_invites.html#external-dependencies" + target="_blank" rel="noopener" >mod_invites</a></samp> module for Prosody needs + these CSS and Javascript libraries for UI. + <li><samp>hg</samp>: thanks to it we'll clone the prosody module repo and keep it updated .</li> +</ul><br> + +<p>Agree on a domain name: you'll replace mentions of <samp>example.com</samp> in this +guide by your chosen domain name. You'll also need subdomains: one for the web client, <samp>chat.example.com</samp> +, one for groups chats, <samp>salons.example.com</samp>, and finally another for uploading files <samp>f.example.com</samp>.<br> +Don't forget to add type A records for these subdomains too. +<br><br> + +<h3 id="xmpp-guide-dnszone"><a href="#xmpp-guide-dnszone">2. DNS zone configuration</a></h3> +<p>First, stay on the DNS zone configuration of your registrar, we'll add some SRV and TXT type entries +to ease XMPP clients and servers communications with us (more details about this +<a href="https://wiki.xmpp.org/web/SRV_Records">on the XMPP wiki</a> or <a +href="https://prosody.im/doc/dns">prosody docs</a>): +<pre> +_xmpp-client._tcp.example.com 86400 SRV 1 1 5222 example.com. +_xmpps-client._tcp.example.com 86400 SRV 1 1 5223 example.com. +_xmpp-server._tcp.example.com 86400 SRV 1 1 5269 example.com. +_xmppconnect.example.com TXT _xmpp-client-xbosh=https://chat.example.com/http-bind +_xmppconnect.example.com TXT _xmpp-client-websocket=wss://chat.example.com/xmpp-websocket +</pre> + +<p><b>NB:</b> the left <samp>example.com</samp> is the XMPP <i>domain</i>, the one +on the right is the <i>server</i> that'll actually answer requests and you'll need a +type A record for it, not a CNAME. These records can come in handy when you want +"clean" users adresses like <u>you@example.com</u> but <samp>example.com</samp> is used for something +else, for example a website or mailserver, and the XMPP server is set up on <samp>xmpp.example.com</samp> .<br> +If that's the case, change the <samp>example.com</samp> on the right to <samp>xmpp.example.com</samp>.<br><br> + + +<h3 id="xmpp-guide-iptables"><a href="#xmpp-guide-iptables">3. Firewall configuration</a></h3> +<p><b><u>IMPORTANT</u>:Log in as root before running the commands in this tutorial.</b> +We'll then configure the <samp>iptables</samp> rules to avoid eating our fingers +in rage and confusion later. I'm assuming your default <samp>iptables</samp> policy is set to +<samp>DROP</samp> and you have some rules set allowing you to SSH into your server: +<pre> +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT # client<=>server comms +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT # same as above but for encrypted ones +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT # server<=>servers comms +iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # for access to webclient +iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # DNS requests +iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # useful for updating packages and letsencrypt +iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT # same as above but we HTTPS + +iptables-save > /etc/iptables/iptables.rules + + +# pareil pour l'ipv6 +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT +ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT +ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT +ip6tables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT +ip6tables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT +ip6tables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT + +ip6tables-save > /etc/iptables/ip6tables.rules +systemctl enable --now iptables # enable iptables services so rules persists after reboots +</pre><br> + +<h3 id="xmpp-guide-pkgs"><a href="#xmpp-guide-pkgs">4. Packages setup</a></h3> + +<p>Next, install <samp>prosody</samp> from + <a href="https://prosody.im/doc/installing_from_source">sources</a> or +<a href="https://prosody.im/download/start">your package manager</a>. +Two birds one stone, we'll install other needed packages too: +<pre>sudo apt-get install -y --no-install-recommends prosody nginx-full \ +certbot python3-certbot-nginx \ +mercurial libjs-bootstrap4 libjs-jquery</pre><br> + +<p>We'll now clone the <samp>prosody-modules</samp> repo from source. Some distro package managers haven't always this one up to date (looking at you, Debian, stable branch). Execute the following: +<pre> +hg clone https://hg.prosody.im/prosody-modules/ /usr/lib/prosody/modules/ +</pre> +<p>And here below is an updating script that you can put on your <samp>/etc/cron.daily/</samp> folder if it exists, or root crontab. On my server, I created the following file at <samp>/usr/local/sbin/maj_prosodymods.sh</samp>: +<pre> +#!/bin/sh +MODDIR="/usr/lib/prosody/modules/" + +if test -d $MODDIR; then + cd $MODDIR + hg pull --update +else + mkdir -p /usr/lib/prosody + hg clone https://hg.prosody.im/prosody-modules/ $MODDIR +fi +</pre> +<p>Don't forget to flip the executable bit with <samp>chmod +x</samp>... +<br><br> + +<p>Then, we'll download <samp>converse.js</samp>. +On Debian Buster as of 23-05-2021 there isn't an official +package for it, so we'll whip up another script that we can +put in a crontab. On my server, I created the file <samp>/usr/local/sbin/update_conversejs.sh</samp> with the following: +<pre> +#!/bin/sh +TEMPDIR="$(mktemp -d)" +LOG=/var/log/update_conversejs.log # update log path +WWWDIR='/var/www/chat.example.com' # where static and js files will be downloaded +WWWUSER='www-data' # this value will differ on the + # distro you're using: it'll be 'http' for + # Arch Linux nginx for example. + +mkdir -p $WWWDIR/dist +cd $TEMPDIR +printf "\n\n$(date) - INFO - Starting updating conversejs..." | tee -a $LOG +CURL_ERR=$(curl -s \ # get latest release tarball + https://api.github.com/repos/conversejs/converse.js/releases/latest | \ + grep -o "https://.*\.tgz" | \ + grep converse\.js- | \ + xargs curl -fsOJL) || \ + (printf "\n$(date) - ERR - Updating conversejs failed." | tee -a $LOG && exit) + +# download libsignal for OMEMO support in conversejs webclient +if test -e "$WWWDIR/dist/libsignal-protocol.min.js"; then + printf "\n$(date) - TOK - Libsignal already installed, skipping." | tee -a $LOG +else + curl -fsOJL \ + https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js || \ + (printf "\n$(date) - ERR - Updating libsignal-protocol-javascript failed." | \ + tee -a $LOG) + cp libsignal*.js $WWWDIR/dist/ +fi + +tar xzf *.tgz +cp -rf package/dist $WWWDIR/ +sed "s/fullscreen\.html/index\.html/g" package/manifest.json > $WWWDIR/manifest.json +chown $WWWUSER:$WWWUSER -R $WWWDIR/ +chmod 755 -R $WWWDIR/ +rm -rf $TEMPDIR +printf "\n$(date) - TOK - Done." | tee -a $LOG +</pre> +<p>Execute this script after fitting it to your taste, it'll make you +save time for <a href="#xmpp-guide-confpkgs">step 6</a> because you won't have to create the <samp>$WWWDIR</samp> + +<h3 id="xmpp-guide-certs"><a href="#xmpp-guide-certs">5. Certificates setup</a></h3> + +<p>It's time to launch certbot to get our certificates. +I'm assuming and I hope that you already have set up A records for +the main domain <samp>example.com</samp> and subdomains too (<samp>chat.example.com</samp>, <samp>f.example.com</samp> and <samp>salons.example.com</samp>) in your registrar DNS zone: +<pre>certbot certonly --agree-tos --nginx --deploy-hook "prosodyctl --root cert import /etc/letsencrypt/live" -d chat.example.com -d example.com -d f.example.com -d salons.example.com </pre> +<p>Once it executes successfully, the certificates should be in +<samp>/etc/letsencrypt/live</samp>. +<br><br> + + +<h3 id="xmpp-guide-confpkgs"><a href="#xmpp-guide-confpkgs">6. Packages configuration</a></h3> + +<p>It's time we dive into <samp>prosody</samp> config files.<br> +Open the file <samp>/usr/lib/prosody/net/http/server.lua</samp>, we'll modify it +in order to ease connecting nginx with the http interface of prosody (BOSH). In the +file, find the following line: +<pre> +headers = { date = date_header, connection = response_conn_header }; +</pre> +<p>and replace it by: +<pre> +headers = { date = date_header, connection = response_conn_header, + access_control_allow_origin = "example.com" }; +-- if 'example.com' dont fix it, replace it by '*'. Remember that your +-- XMPP server domain name goes here. +</pre><br> + +<p>Then, we'll configure the script that'll allow us to send files to others. +Execute this: +<pre> +mkdir -p /var/www/upload +chown www-data:www-data /var/www/upload # l'utilisateur de nginx peut + # différer selon la distrib, faites gaffe +mkdir -p /usr/local/lib/perl +wget -O /usr/local/lib/perl/upload.pm https://raw.githubusercontent.com/weiss/ngx_http_upload/master/upload.pm +</pre> +<p>Open the downloaded file <samp>upload.pm</samp> and search for +a line like this: <samp>my $external_secret = 'it-is-secret'</samp>. +Replace <samp>it-is-secret</samp> by a strong passphrase without backslashes +or quotes to avoid crashing the script due to syntax error later.<br> +Save or write it down somewhere, it'll be useful very soon. +<br><br> + +<p>Let's now get to write the <samp>prosody</samp> configuration file +<samp>/etc/prosody/prosody.cfg.lua</samp> with the following: +<pre> +admins = { "you@example.com" } + +-- For more information see: https://prosody.im/doc/libevent +-- use_libevent = true + +plugin_paths = { "/usr/lib/prosody/modules" } + +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "carbons"; -- Keep multiple clients in sync + "carbons_copies"; + "carbons_copies_adhoc"; + "pep"; -- Enables users to publish their avatar, mood, activity, playing music and more + "private"; -- Private XML storage (for room bookmarks, etc.) + "blocklist"; -- Allow users to block communications with other users + "vcard4"; -- User profiles (stored in PEP) + "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard + "smacks"; + "bookmarks"; -- old module but compatible with most clients + --"bookmarks2"; + "presence"; -- see user status (online, offline, etc) + "offline"; + + -- Nice to have + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "register"; -- Allow users to register on this server using a client and change passwords + "mam"; -- Store messages in an archive and allow users to access it + "csi"; + "csi_simple"; -- Simple Mobile optimizations + "csi_battery_saver"; + "vjud"; -- recherche d'utilisateurs dans les salons + + -- Admin interfaces + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + + -- HTTP modules + "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + "websocket"; -- XMPP over WebSockets + "http_altconnect"; -- BOSH and WebSocket connection endpoints discoverable via HTTP + + -- Other specific functionality + "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + "limits"; -- Enable bandwidth limiting for XMPP connections + "groups"; -- Shared roster support + "server_contact_info"; -- Publish contact information for this service + "announce"; -- Send announcement to all online users + "welcome"; -- Welcome users who register accounts + "watchregistrations"; -- Alert admins of registrations + "motd"; -- Send a message to users when they log in + --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use +} + +-- These modules are auto-loaded, but should you want +-- to disable them then uncomment them here: +modules_disabled = { + -- "offline"; -- Store offline messages + -- "c2s"; -- Handle client connections + -- "s2s"; -- Handle server-to-server connections +} + +motd_text = [[Hi everyone ! Welcome to my XMPP server. Have an happy chat !]] +welcome_message = "It seems it's your first logging in, $username. Welcome and enjoy your stay at $host." + +daemonize = false; +pidfile = "/run/prosody/prosody.pid"; +trusted_proxies = { "127.0.0.1", "::1" } + +-- Force certificate authentication for server-to-server connections +c2s_require_encryption = true -- client to server require encryption +s2s_require_encryption = true -- server to server require encryption +s2s_secure_auth = true +authentication = "internal_hashed" + +-- mam settings +archive_expires_after = "never" -- permanent message history + +log = { + -- Log files (change 'info' to 'debug' for debug logs): + info = "/var/log/prosody/prosody.log"; + error = "/var/log/prosody/prosody.err"; + -- Syslog: + { levels = { "error" }; to = "syslog"; }; +} + +-- http and certificate shenanigans +certificates = "certs" + +-- Include "conf.d/*.cfg.lua" + +legacy_ssl_ports = { 5223 } +-- http_ports = { 5280 } +-- http_interface = { "*" } +-- https_ports = { 5281 } +-- https_interfaces { "*" } + + +cross_domain_bosh = { "https://chat.example.com" } +cross_domain_websocket = { "https://chat.example.com" } +consider_bosh_secure = true +consider_websocket_secure = true +allow_registration = true -- needed for mod_invites +registration_invite_only = true -- registration is only permitted through invites +vjud_mode = "opt-in" -- public search is opt-in + +-- https://prosody.im/security/advisory_20210512/ +gc = { + speed = 500; +} +c2s_stanza_size_limit = 256 * 1024 +s2s_stanza_size_limit = 512 * 1024 + +limits = { + c2s = { + rate = "10kb/s"; + }; + s2sin = { + rate = "3kb/s"; + }; +} +-- https://prosody.im/security/advisory_20210512/ + +ssl = { + key = "certs/example.com.key"; + certificate = "certs/example.com.crt"; +} + +VirtualHost "example.com" + invites_page = "https://chat.example.com/invite?{invite.token}" + webchat_url = "https://chat.example.com/" + http_external_url = "https://chat.example.com/" + invite_expiry = 86400 * 7 + http_paths = { + invites_page = "/invite"; + invites_register_web = "/register"; + } + + modules_enabled = { + "invites"; + "invites_adhoc"; + "invites_page"; + "invites_register"; + "invites_register_web"; + "http_libjs"; + } + + contact_info = { + abuse = { "mailto:you@example.com", "xmpp:you@example.com" }; + admin = { "mailto:you@example.com", "xmpp:you@example.com" }; + security = { "mailto:you@example.com", "xmpp:you@example.com" }; + support = { "mailto:you@example.com", "xmpp:you@example.com" }; + }; + + https_certificate = "certs/example.com.crt"; + ssl = { + key = "certs/example.com.key"; + certificate = "certs/example.com.crt"; + } + + Component "f.example.com" "http_upload_external" + http_upload_external_base_url = "https://f.example.com/" + http_upload_external_secret = "its-a-secret" + http_upload_external_file_size_limit = 104857600 -- limite de à 100Mo pour les envois de pjs + ssl = { + key = "certs/f.example.com.key"; + certificate = "certs/f.example.com.crt"; + } + + Component "salons.example.com" "muc" + name = "Salons (chatrooms) chez example.com" + modules_enabled = { "muc_mam", "vcard_muc" } + muc_room_default_language = "fr" + muc_log_expires_after = "never" -- perm hist for gcs + log_all_rooms = true + muc_log_by_default = true + muc_log_presences = false + restrict_room_creation = "admin" -- only admin can create gcs + ssl = { + key = "certs/salons.example.com.key"; + certificate = "certs/salons.example.com.crt"; + } +</pre> +<p>As you can guess the <samp>its-a-secret</samp> value there must be replaced +by the passphrase you wrote down earlier.<br> +Some of you probably have noticed that the user <u>you@example.com</u> +was listed as an admin, so let's create him with the following command line: +<pre> +prosodyctl check # checks config file +prosodyctl adduser you@example.com # adapt to your username@domain +</pre><br> + +<p>We'll now start to configure our web client, <samp>converse.js</samp>. Create + <samp>/var/www/chat.example.com/index.html</samp> with the following text: +<pre> +<!DOCTYPE html> +<html class="no-js" lang="en"> + <head> + <title>Converse</title> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content="Converse XMPP/Jabber Chat"/> + <meta name="keywords" content="xmpp chat webchat converse.js" /> + <link rel="manifest" href="/manifest.json"> + <link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" /> + <script src="/dist/libsignal-protocol.min.js"></script> + <script src="/dist/converse.min.js"></script> + </head> + <body class="converse-fullscreen"> + <noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript> + <div id="conversejs-bg"></div> + <script> + /* + @licstart + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to <http://unlicense.org/> + @licend + */ + converse.initialize({ + auto_away: 300, // in seconds + auto_list_rooms: true, + auto_reconnect: true, + auto_xa: 600, // extended away, in seconds + bosh_service_url: 'https://chat.example.com/http-bind/', + csi_waiting_time: 60, // smartphone battery optimizations + enable_smacks: true, + locked_domain: example.com, // xmpp server that the client will only be allowed to connect to + message_archiving: 'always', + persistent_store: 'IndexedDB', // jcbrand said it'll be fast in 8.0.0 and better than localStorage + play_sounds: true, + theme: 'concord', // dark theme + view_mode: 'fullscreen', + websocket_url: 'wss://chat.example.com/xmpp-websocket', // can be unstable, if you got problems + // don't hesitate to comment it + }); + </script> + </body> +</html> +</pre><br> + +<p>This guide is almost done ! We now need to do the nginx config files.<br> +Let's start with <samp>/etc/nginx/sites-enabled/example.com.conf</samp>: +<pre> +server { + listen 80; + server_name example.com; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl; + server_nam example.com; + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + proxy_set_header Access-Control-Allow-Origin 'chat.example.com'; + + # this block is for the prosody's http_altconnect module + location ~* host-(meta|meta\.json) { + proxy_pass http://example.com:5280$uri; + proxy_http_version 1.1; + } +} +</pre><br> + +<p>Next, let's continue with + <samp>/etc/nginx/sites-enabled/f.example.com.conf</samp>, it's the config file for + uploading files: +<pre> +perl_modules /usr/local/lib/perl; # Path to upload.pm. +perl_require upload.pm; + +server { + listen 80; + server_name f.example.com; + location / { + return 301 https://$host$request_uri; + } +} + +server { + # Specify directives such as "listen", "server_name", and TLS-related + # settings for the "server" that handles the uploads. + listen 443 ssl http2; + server_name f.example.com; + + ssl_certificate /etc/letsencrypt/live/f.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/f.example.com/privkey.pem; + # Uploaded files will be stored below the "root" directory. To minimize + # disk I/O, make sure the specified path is on the same file system as + # the directory used by Nginx to store temporary files holding request + # bodies ("client_body_temp_path", often some directory below /var). + root /var/www/upload; + index index.html; + # Specify this "location" block (if you don't use "/", see below): + location / { + perl upload::handle; + } + + # Upload file size limit (default: 1m), also specified in your XMPP + # server's upload module configuration (see below): + client_max_body_size 100m; +} +</pre> + +<p>Execute <samp>nginx -t</samp> to test the config files created so far. +Once no errors are detected create + <samp>/etc/nginx/sites-enabled/chat.example.com.conf</samp>: +<pre> +server { + listen 80; + server_name chat.example.com; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl http2; + ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem; + root /var/www/chat.example.com; + index index.html; + + # XMPP BOSH + location ^~ /http-bind { + proxy_pass https://example.com:5281/http-bind; + proxy_http_version 1.1; + proxy_set_header Host example.com; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP HTTP-Upload + location ^~ /upload { + proxy_pass https://f.example.com; proxy_http_version 1.1; + proxy_set_header Host example.com; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP Websockets + location /xmpp-websocket { + proxy_pass http://example.com:5280/xmpp-websocket; + proxy_http_version 1.1; + proxy_buffering off; + proxy_set_header Connection "Upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900s; + } + + # XMPP Account invite + location ^~ /invite { + proxy_pass https://example.com:5281/invite; + proxy_http_version 1.1; + proxy_set_header Host example.com; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP account register + location ^~ /register { + proxy_pass https://example.com:5281/register; + proxy_http_version 1.1; + proxy_set_header Host example.com; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # sur mon vps debian j'ai eu besoin de ça pour + # que les pages d'invitation soit bien + # formatées + location = /share/bootstrap4/css/bootstrap.min.css { + alias /usr/lib/nodejs/bootstrap/dist/css/bootstrap.min.css; + } + + location = /share/jquery/jquery.min.js { + alias /usr/lib/nodejs/jquery/dist/jquery.min.js; + } + + location = /share/bootstrap4/js/bootstrap.min.js { + alias /usr/lib/nodejs/bootstrap/dist/js/bootstrap.min.js; + } + +} +</pre> +<p>Execute again <samp>nginx -t</samp> to spot any troubles with your +config files. Once all is OK, add the line +<pre> +# XMPP server domain name here, i.e it +# could be xmpp.example.com in your case +127.0.0.1 example.com +</pre> + +<p>in your <samp>/etc/hosts</samp>.<br> +Restart <samp>nginx</samp> and <samp>prosody</samp>: +<pre> +systemctl start prosody nginx +# or +prosodyctl start && nginx -s reload +</pre><br> + +<h3 id="xmpp-guide-con"><a +href="#xmpp-guide-con">7. Discovering the webclient</a></h3> + +<p>Let's see the results of our work! Open a web browser and navigate +to <a href="https://chat.example.com">https://chat.example.com</a>, YMMV. +You should see something like this: +<a href="img/0conversejs_login.png"><img +src="img/0conversejs_login.png"></a> + +<p><b>Small trick</b>: if you want to login as +<u><samp>you@example.com</samp></u>, you can omit the right part of your adress like +this:<br> +<a href="img/0conversejs_logintrick.png"><img +src="img/0conversejs_logintrick.png"></a> +<p>It's thanks to the +<samp><a +href="https://conversejs.org/docs/html/configuration.html?highlight=locked_domain#locked-domain" +target="_blank" rel="noopener">locked_domain</a></samp> parameter.<br> + +Once logged in your view should be like this:<br> +<a href="img/0conversejs_main.png"><img +src="img/0conversejs_main.png"></a> + +<p>You can then start to use XMPP and join or create group chats, add friends and chat +with them from there !<br><br> + +<h3 id="xmpp-guide-genlinks"><a href="#xmpp-guide-genlinks">8. Invite links generation</a></h3> + +<p>The really interesting thing is that we can create invite links from +Converse.js thanks to the <samp>admin_adhoc</samp> module.<br> +To do so, left click on the gear icon on the top left next to your +username, then click <u>Commands</u>. +In the <u>'On which entity do you want to run commands?'</u> field, type +in your XMPP server domain name and left click <u>'List available commands'</u>. +You should have something similar to this:<br> +<a href="img/0conversejs_adhoc1.png"><img +src="img/0conversejs_adhoc1.png"></a><br> + +<p>Scroll down a bit and left click on <u>"Create new contact invite"</u>:<br> +<a href="img/0conversejs_adhoc2.png"><img +src="img/0conversejs_adhoc2.png"></a><br> + +<p>An invite link has been created ! You can now copy and send it to your +friends, family, etc...<br> +Once opened, the link will lead to this kind of page: +<a href="img/0conversejs_invitepage.png"><img +src="img/0conversejs_invitepage.png"></a><br> +<p>The web page auto-detects your OS platform and will +suggest you compatible XMPP software to download. In the +case you're on a smartphone, the links will download the apps +on their respective stores and continue the registration +after opening thanks to the <u>Invite URI</u>.<br> +The text squared in red in the bottom left, <u>'register an account manually'</u>, +allows you to register via the web browser. It's handy when you want to create +an account and test it later. Here how it looks:<br> +<a href="img/0conversejs_register1.png"><img +src="img/0conversejs_register1.png"></a><br> + +<p>As you can see I started to fill in the form: once submitted succesfully, + you'll be greeted with this: +<a href="img/0conversejs_register2.png"><img +src="img/0conversejs_register2.png"></a><br> + +<p>A page confirming your registration is shown, with the possibility to view your chat adress and password again to +write them down somewhere. The user can then log in with +Converse.js by clicking on the <u>"Log in via web"</u> button. +Once logged in, you will be added to his roster (because we did a <i>contact</i> invite) and he can start to chat with you.<br> +<a href="img/0conversejs_chatting.png"><img +src="img/0conversejs_chatting.png"></a><br> + +<h3 id="xmpp-guide-remarks"><a href="#xmpp-guide-remarks">9. Remarks</a></h3> +<p>The guide ends there! I'll get back from time to time to fix some typos and inconstencies when I spot them. +I've got some notes and remarks: +<ul style="list-style:disclosure-closed"> + <li>OMEMO encrypted chats don't seem readable between converse.js clients. + The sender can read it fine, but if the recipient only uses converse.js, there's + an high probability he sees the dreaded <u>I sent you an OMEMO encrypted message but your client doesn't seem to support that...</u> message. + From my experience, Dino and Gajim can decrypt these chats just fine. I've maybe + misconfigured something ?</li> + <li>Due to reliance on the browser cache to display last messages, I recommend + to dedicate a browser (and maybe ideally a browser <i>profile</i>) to your converse.js + client if you like having a consistent messaging history.</li> + <li>File encryption via OMEMO isn't implemented yet (source: @jcbrand in <a href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>). + <li>If you want to translate the invites pages in your language, + look into the source code of <samp>mod_invites_pages</samp>, + <samp>mod_register_web</samp> and <samp>mod_register_apps</samp>.</li> +</ul> + + +<h3 id="xmpp-guide-docs"><a href="#xmpp-guide-docs">10. Documentations</a></h3> + +<p>Those links greatly helped me: + <ul style="list-style:square"> + <li><b>Converse.js</b>: <a + href="https://conversejs.org/docs/html/index.html" target="_blank" + rel="noopener">General</a>, <a + href="https://conversejs.org/docs/html/configuration.html#configuration-settings" + target="_blank" + rel="noopener">config and initilization</a><br> + Reading the HTML source code of<a + href="https://inverse.chat" target="_blank" rel="noopener">https://inverse.chat</a> + + </li> + <li><b>Prosody</b>: <a + href="https://prosody.im/doc" target="_blank" rel="noopener">General</a>, <a + href="https://prosody.im/doc/setting_up_bosh" target="_blank" + rel="noopener">BOSH+Nginx</a>, + <a href="https://prosody.im/doc/websocket" target="_blank" + rel="noopener">Websockets+Nginx</a>, + <a href="https://modules.prosody.im/xeps.html" target="_blank" + rel="noopener">Links between XEPs and modules</a>, <a + href="https://modules.prosody.im/mod_invites.html" target="_blank" + rel="noopener">mod_invites docs</a>, <a + href="https://modules.prosody.im/mod_http_upload_external.html" + target="_blank" rel="noopener">mod_http_upload_external docs</a> and Holger's implementation ,<a + href="https://github.com/weiss/ngx_http_upload" target="_blank" + rel="noopener">upload.pm</a>.</li> + <li><b>XMPP</b>: <a href="https://wiki.xmpp.org/web/Main_Page" target="_blank" rel="noopener">the Wiki</a>, <a href="https://compliance.conversations.im/" target="_blank" rel="noopener">compliance tester</a>. + </ul> + + +<h3 id="xmpp-guide-thanks"><a href="#xmpp-guide-thanks">11. +Thanks</a></h3> + +<p>This wouldn't have been possible without free software and their contributors. Thanks you so much.<br> +To be more specific: +<ol style="list-style:square"> + <li><a href="https://blog.laxu.de">laxu.de</a>, author of + <a href="https://blog.laxu.de/2018/09/08/conversejs-prosody/"> + https://blog.laxu.de/2018/09/08/conversejs-prosody/</a> which walks through the patching of <samp>net/http/server.lua</samp> and gives some related nginx configuration snippets</li> + <li><a href="https://qorg11.net/">qorg</a> for <a href="https://kill-9.xyz/guides/xmpp_server" target="_blank" rel="noopener">his XMPP guide</a>, in particular the part dealing about <samp>mod_http_upload_external</samp> + <li> <a + href="https://wiki.xmpp.org/web/Jan-Carel_Brand_Application_2021" + target="_blank" rel="noopener">jcbrand</a>, creator and main developer of <a + href="https://conversejs.org/" target="_blank" + rel="noopener">Converse.js</a>. Very quick to respond to questions + relating to XMPP and Converse.js in <a href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>.</li> + <li><a href="xmpp:holger@jabber.fu-berlin.de?message">Holger Weiß</a>, + a developer working on the ejabberd XMPP server and admin of + <a + href="xmpp:ejabberd@conference.process-one.net?join">ejabberd@conference.process-one.net</a> who took his time + to help me (<a href="https://partage.les-miquelots.net/engver/blog/reminder-when-setting-up-a-xmpp-server-with-prosody.html">problem and fix here</a>).</li> +</ol><br> + +<p>See you soon and have a great day ! If you have any questions, remarks, suggestions or improvements to point out, don't hesitate to message me via XMPP or email at <u>lionel ( @ ) les-miquelots ( . ) net</u>. +<footer>by <strong><a href='http://partage.les-miquelots.net/'>Miquel Lionel</a></strong></footer> +</body> + +</html> diff --git a/styles.css b/styles.css new file mode 100755 index 0000000..4ca9777 --- /dev/null +++ b/styles.css @@ -0,0 +1,192 @@ +*{ + line-height:24px; +} + +img{ + padding:10px; + height:60%; + width:70%; +} + +#spinthonk{ + padding:1px; + height:50px; + width:50px; +} + +#gitimg, #rssimg, #rssimg2 { + height:24px; + width:24px; + padding:2px; + +} + +.pagetoplink { + position: fixed; + width: 20%; + bottom: 0; + left: 0; + padding: 0.5em; +} + + +#omemo_fpts { +margin-left:17%; +} + +#guide-sommaire{ + padding:5px; + border:1px solid black; +} + +body{ + background-color:beige; + color:#222222; + font-family: Sans-Serif; + font-style: normal; + font-weight: 375; + font-size:12pt; +} + +h1,h2,h3{ + line-height:30px; + text-align:center; + margin:auto; + width:70%; +} + +h2,h3{ + text-align:left; + margin-top:2.5%; +} + +p,table,pre,ol,ul,#guide-sommaire{ + color: #222222; + width:70%; + margin:auto; +} + +p{ +text-indent:3%; + +} + +#footnotes { + font-size:0.85em; +} + +pre{ + overflow:auto; + padding:10px; + border-radius:10px; + border:1px solid grey; + line-height:15px; + color:white; + background-color:#222236; + font-size:0.9em; +} + +pre, code{ + font-family:monospace; +} + +pre a { + color:cyan; +} + +table{ + width:85%; + padding:5px; +} + +td,tr{ + width:25%; + text-align:center; + padding:5px; +} + +td,th{ + border-bottom:1px solid black; +} + +th{ + border:2px solid #222222; + border-width:2px; +} + +li{ + width:90%; + margin:auto; +} + +a{ + color:teal; + text-decoration:none; +} + +a:hover{ + text-decoration:underline; +} + +.blogentry{ + width:65%; + margin:auto; +} + +.blogentry h2, .blogentry p{ + width:100%; +} + +footer{ + width:70%; + margin:auto; + padding-top:15px; +} + +.blogentry small, body small{ + width:100%; + display:block; + text-align:center; +} + + +blockquote{ + width:65%; + margin:auto; + padding:10px; + margin-top:10px; + margin-bottom:10px; + border-left:3px solid grey; + text-align:none; +} + +blockquote small{ + text-align:inherit; +} + +/*ripped from mozilla MDN, thx lol*/ +kbd { + background-color: #eee; + border-radius: 3px; + border: 1px solid #b4b4b4; + box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255, + 255, 255, .7) inset; + color: #333; + display: inline-block; + font-size: .85em; + font-weight: 700; + line-height: 1; + padding: 2px 4px; + white-space: nowrap; +} +figcaption { + text-align: center; + font-style: italic; + font-size: 90%; +} + +@media screen and (max-width: 740px) { + #omemo_fpts { + margin-left:25%; + } +} |