Build
This commit is contained in:
parent
6a8c8c68e0
commit
51c7de8d1f
5 changed files with 561 additions and 9 deletions
|
@ -96,11 +96,11 @@
|
||||||
<p>Les besoins sont simple : les utilisateurs ayant un compte sur mon service de SSO devraient pouvoir se connecter sur un service, créer une clé dédiée à une application, puis utiliser cette clé pour backup une machine, serveur ou PC, et envoyer les données sur mon serveur central. Les backups créés devraient être chiffrés, dédupliqués, et avec une gestion des droits pour ne pas permettre à un utilisateur d’écraser ou de modifier les backups des autres (tout étant chiffré, l’accès en lecture est moins critique). Si possible, le service devrait pouvoir définir des quotas par utilisateur ; malheureusement, la solution que j’ai trouvée ne le permet pas.</p>
|
<p>Les besoins sont simple : les utilisateurs ayant un compte sur mon service de SSO devraient pouvoir se connecter sur un service, créer une clé dédiée à une application, puis utiliser cette clé pour backup une machine, serveur ou PC, et envoyer les données sur mon serveur central. Les backups créés devraient être chiffrés, dédupliqués, et avec une gestion des droits pour ne pas permettre à un utilisateur d’écraser ou de modifier les backups des autres (tout étant chiffré, l’accès en lecture est moins critique). Si possible, le service devrait pouvoir définir des quotas par utilisateur ; malheureusement, la solution que j’ai trouvée ne le permet pas.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Les différentes étapes de l’articles sont :</p>
|
<p>Les différentes étapes de l’article sont :</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#faire-ses-backups-simplement">Installer restic et écrire un script pour le lancer</a></li>
|
<li><a href="#faire-ses-backups-simplement">Installer restic et écrire un script pour le lancer</a></li>
|
||||||
<li><a href="stocker-ses-backups-quelque-part">Installer MinIO, et tester que restic fonctionne avec MinIO</a></li>
|
<li><a href="#stocker-ses-backups-quelque-part">Installer MinIO, et tester que restic fonctionne avec MinIO</a></li>
|
||||||
<li><a href="et-ma-sso-dans-tout-ça-">Configurer restic pour fonctionner avec MinIO en SSO</a></li>
|
<li><a href="#et-ma-sso-dans-tout-ça-">Configurer restic pour fonctionner avec MinIO en SSO</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
326
2024/08/28/xmpp-server.html
Normal file
326
2024/08/28/xmpp-server.html
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="html" data-theme="light"><head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<title>
|
||||||
|
|
||||||
|
Remplacer la conversation Whatsapp familiale par un serveur XMPP
|
||||||
|
|
||||||
|
</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.addEventListener('load', themeChange);
|
||||||
|
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
|
||||||
|
if (currentTheme)
|
||||||
|
document.documentElement.setAttribute('data-theme', currentTheme);
|
||||||
|
|
||||||
|
function themeChange() {
|
||||||
|
let button = document.querySelector('.theme-toggle');
|
||||||
|
|
||||||
|
button.addEventListener('click', function (e) {
|
||||||
|
let currentTheme = document.documentElement.getAttribute('data-theme');
|
||||||
|
if (currentTheme === 'dark') {
|
||||||
|
transition();
|
||||||
|
document.documentElement.setAttribute('data-theme', 'light');
|
||||||
|
localStorage.setItem('theme', 'light');
|
||||||
|
} else {
|
||||||
|
transition();
|
||||||
|
document.documentElement.setAttribute('data-theme', 'dark');
|
||||||
|
localStorage.setItem('theme', 'dark');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let transition = () => {
|
||||||
|
document.documentElement.classList.add('transition');
|
||||||
|
window.setTimeout(() => {
|
||||||
|
document.documentElement.classList.remove('transition');
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="w">
|
||||||
|
<header>
|
||||||
|
<ul class="horizontal-list">
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/">
|
||||||
|
accueil
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/blog.html">
|
||||||
|
blog
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/about.html">
|
||||||
|
à propos
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="https://cv.caroline.canebier.fr">
|
||||||
|
cv
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="https://git.chapoline.me/chapeau/blog">
|
||||||
|
git
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="dashed"></div>
|
||||||
|
|
||||||
|
<h1>Remplacer la conversation Whatsapp familiale par un serveur XMPP</h1>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<p>Tout le monde aujourd’hui a, dans sa famille, une conversation Whatsapp/Telegram/Messenger/autre, en remplacement des SMS de la décennie précédente. Mais avec l’enshitification ambiante d’Internet, il devient de plus en plus essentiel d’avoir des options pour rester en contact avec ses proches sans passer par des applications propriétaires peu respectueuses de la vie privée. XMPP est une excellente solution à ça, et en installer un serveur est un projet sympathique et assez facile.</p>
|
||||||
|
|
||||||
|
<p>XMPP est un protocol décentralisé d’échange de données en temps réel. Plus simplement, c’est un très bon protocol pour construire des systèmes fédérés de discussion instantannée, ce qui est exactement ce que l’on va faire. Le protocol est défini via quelques RFC, et définit également des extensions à travers des <a href="https://xmpp.org/extensions/">XEP</a>. Plusieurs de ces XEP sont aujourd’hui très standard et sont installées et activées par défaut (comme la <a href="https://xmpp.org/extensions/xep-0012.html">XEP-0012</a>). Enfin, XMPP propose aujourd’hui du chiffrement bout-en-bout mature et automatique (<a href="https://xmpp.org/extensions/xep-0384.html">XEP-0384</a>).</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Les différentes étapes de cet article sont :</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#environnement">Une description de l’environnement dans lequel le serveur XMPP va être déployé</a></li>
|
||||||
|
<li><a href="#installation-et-configuration-initiale">L’installation et la configuration du serveur XMPP en lui-même</a></li>
|
||||||
|
<li><a href="#file-sharing-et-muc">La configuration de quelques fonctionnalités supplémentaires (partage de fichier et rooms)</a></li>
|
||||||
|
<li><a href="#fichier-de-configuration-final">La configuration finale du serveur</a></li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<h2 id="environnement">Environnement</h2>
|
||||||
|
|
||||||
|
<p>Pour monter un serveur XMPP, il est nécessaire d’avoir au moins un nom de domaine public, et si possible plusieurs sous-domaines dédiés au projet. Il est également nécessaire d’avoir une ip publique, avec a minima les ports tcp 5222 et 5269 accessibles.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Dans cet article, je prends comme noms de domaines <code class="language-plaintext highlighter-rouge">example.org</code> et ses sous-domaines, et comme ip publique <code class="language-plaintext highlighter-rouge">198.51.100.5</code>. Le serveur lui-même est sur l’ip <code class="language-plaintext highlighter-rouge">192.168.1.200/24</code>, derrière un NAT. J’utilise également un reverse-proxy dédié (puisque je n’ai qu’une ip publique), dont l’ip privée est <code class="language-plaintext highlighter-rouge">192.168.1.100</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p><a href="https://prosody.im">Prosody</a> et <a href="https://www.ejabberd.im">edjabberd</a> sont deux implémentations modernes de serveur XMPP, et les deux sont des choix très pertinents. Pour ma part, j’ai choisi Prosody.</p>
|
||||||
|
|
||||||
|
<p>Pour installer Prosody, j’utilise un serveur Debian 11, avec 2 vCPU, 2Go de ram et 32Go de disque (à titre purement indicatif, je n’ai pas fait de benchmark pour vérifier la pertinence de ces ressources).</p>
|
||||||
|
|
||||||
|
<h2 id="installation-et-configuration-initiale">Installation et configuration initiale</h2>
|
||||||
|
|
||||||
|
<p>L’installation sous debian se fait via le repo officiel de Prosody :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo </span>deb http://packages.prosody.im/debian <span class="si">$(</span>lsb_release <span class="nt">-sc</span><span class="si">)</span> main | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/prosody.list
|
||||||
|
<span class="nb">sudo </span>wget https://prosody.im/files/prosody-debian-packages.key <span class="nt">-O</span> /etc/apt/trusted.gpg.d/prosody.gpg
|
||||||
|
<span class="nb">sudo </span>apt update
|
||||||
|
<span class="nb">sudo </span>apt <span class="nb">install </span>prosody
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Toute la configuration se fait ensuite dans <code class="language-plaintext highlighter-rouge">/etc/prosody/prosody.cfg.lua</code>.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Le fichier de configuration complet est disponible à la fin du guide. J’ai enlevé les commentaires du fichier par défaut par soucis de clareté, mais je vous conseille de les laisser !</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>La configuration commence par charger une liste de modules. La liste par défaut est un bon point de départ ; j’ai simplement décommenté le module <code class="language-plaintext highlighter-rouge">mam</code>, qui permet de conserver un historique des messages sur le serveur.</p>
|
||||||
|
|
||||||
|
<p>On peut ensuite indiquer à Prosody quelle ip publique est utilisée pour accéder au service, ce qui lui permet de vérifier lui même si la configuration DNS est correcte :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">external_addresses</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"198.51.100.5"</span> <span class="p">}</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Enfin, il faut créer un VirtualHost, ce qui correspond à un domaine sur lequel Prosody va écouter (en gros, un serveur XMPP séparé). Attention, toutes les options de configuration définies après ne s’appliqueront qu’au VirtualHost !</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">VirtualHost</span> <span class="s2">"chat.example.org"</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Et voilà, juste avec ça, on a un serveur XMPP fonctionnel ! Mais avant de l’utiliser, nous allons au moins mettre en place un certificat TLS pour sécuriser les connexions entre les clients et le serveur, et entre notre serveur et les autres. Pour cela, un peu de DNS et de reverse proxy s’impose. Faisons donc pointer <code class="language-plaintext highlighter-rouge">chat.example.org</code> sur notre ip publique, puis ajoutons juste ce qu’il faut de reverse proxy :</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>J’utilise NixOS pour gérer mon reverse proxy. Je vous laisse adapter cette configuration pour nginx si ce n’est pas votre cas.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">services</span><span class="o">.</span><span class="nv">nginx</span><span class="o">.</span><span class="s2">"chat.example.org"</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="nv">locations</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"/"</span><span class="o">.</span><span class="nv">proxyPass</span> <span class="o">=</span> <span class="s2">"http://192.168.1.200:80"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Cette configuration de nginx n’écoute que sur le port 80, et reverse-proxyfie les requêtes sur le port 80 de la VM Prosody. Elle ne sert qu’à faire fonctionner le challenge Let’s Encrypt qui va venir :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>certbot certonly <span class="nt">--standalone</span> <span class="nt">-d</span> chat.example.org
|
||||||
|
<span class="nv">$ </span>prosodyctl <span class="nt">--root</span> cert import /etc/letsencrypt/live
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Pour vérifier que tout fonctionne, on peut utiliser <code class="language-plaintext highlighter-rouge">prosodyctl</code> :</p>
|
||||||
|
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ prosodyctl check certs
|
||||||
|
Checking certificates...
|
||||||
|
Checking certificate for chat.example.org
|
||||||
|
Certificate: /etc/prosody/certs/chat.example.org.crt
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Et voilà ! N’oubliez pas de forward les ports tcp 5222 et 5269 sur votre firewall, et votre serveur XMPP devrait être fonctionnel. Pour ajouter des utilisateurs, utilisez la cli :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>prosodyctl adduser user@chat.example.org
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<h2 id="file-sharing-et-muc">File sharing et MUC</h2>
|
||||||
|
|
||||||
|
<p>Afin de rajouter quelques fonctionnalités à notre serveur, nous allons rajouter un vrai service de partage de fichier (actuellement, le partage de fichiers fonctionne, mais uniquement en peer-to-peer), ainsi que la possibilité de créer des rooms de discussion.</p>
|
||||||
|
|
||||||
|
<p>Ces deux fonctionnalités s’ajoutent via des <em>Components</em>, qui se configurent à la suite du VirtualHost :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">disco_items</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="p">{</span> <span class="s2">"file.example.org"</span><span class="p">,</span> <span class="s2">"file sharing service"</span> <span class="p">},</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">http_paths</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">file_share</span> <span class="o">=</span> <span class="s2">"/"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"file.example.org"</span> <span class="s2">"http_file_share"</span>
|
||||||
|
<span class="n">http_file_share_global_quota</span> <span class="o">=</span> <span class="mi">16</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span> <span class="c1">-- 16 Go</span>
|
||||||
|
<span class="n">http_external_url</span> <span class="o">=</span> <span class="s2">"https://file.example.org/"</span>
|
||||||
|
<span class="n">trusted_proxies</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"192.168.1.100"</span><span class="p">,</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"rooms.chat.example.org"</span> <span class="s2">"muc"</span>
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"muc_mam"</span> <span class="p">}</span>
|
||||||
|
<span class="n">name</span> <span class="o">=</span> <span class="s2">"Chatrooms"</span>
|
||||||
|
<span class="n">restrict_room_creation</span> <span class="o">=</span> <span class="s2">"local"</span>
|
||||||
|
<span class="n">muc_room_default_public</span> <span class="o">=</span> <span class="kc">false</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Le service de partage de fichier, qui va être configuré derrière le reverse proxy, a besoin de connaitre son url d’accès pour générer correctement les liens. On lui configure également son quota global, et l’adresse ip du serveur proxy afin de l’autoriser.</p>
|
||||||
|
|
||||||
|
<p>Pour éviter que les liens générés soient préfixés par <code class="language-plaintext highlighter-rouge">file_share/</code>, on redéfinit son <code class="language-plaintext highlighter-rouge">http_path</code>. Enfin, pour que les clients puisse découvrir le service et parce qu’il n’est pas sur un sous-domaine de <code class="language-plaintext highlighter-rouge">chat.example.org</code>, on le définit dans la liste des services à découvrir.</p>
|
||||||
|
|
||||||
|
<p>Côté MUC, on active également le stockage des messages récents sur le serveur, on autorise uniquement les comptes locaux à créer de nouvelles rooms (même si n’importe qui peut ensuite les rejoindre), et on crée les rooms comme étant privées par défaut.</p>
|
||||||
|
|
||||||
|
<p>Afin que le reverse proxy fonctionne, il faut également faire écouter le port HTTP de Prosody sur <code class="language-plaintext highlighter-rouge">0.0.0.0</code> au lieu de <code class="language-plaintext highlighter-rouge">localhost</code> par défaut :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">http_interfaces</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"*"</span><span class="p">,</span> <span class="s2">"::"</span> <span class="p">}</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>On peut à présent configurer notre reverse proxy, cette fois avec HTTPS :</p>
|
||||||
|
|
||||||
|
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">services</span><span class="o">.</span><span class="nv">nginx</span><span class="o">.</span><span class="s2">"file.example.org"</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="nv">enableACME</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
||||||
|
<span class="nv">forceSSL</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
||||||
|
<span class="nv">locations</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"/"</span><span class="o">.</span><span class="nv">proxyPass</span> <span class="o">=</span> <span class="s2">"http://192.168.1.200:5280"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<h2 id="fichier-de-configuration-final">Fichier de configuration final</h2>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">external_addresses</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"198.51.100.5"</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"disco"</span><span class="p">;</span> <span class="c1">-- Service discovery</span>
|
||||||
|
<span class="s2">"roster"</span><span class="p">;</span> <span class="c1">-- Allow users to have a roster. Recommended ;)</span>
|
||||||
|
<span class="s2">"saslauth"</span><span class="p">;</span> <span class="c1">-- Authentication for clients and servers. Recommended if you want to log in.</span>
|
||||||
|
<span class="s2">"tls"</span><span class="p">;</span> <span class="c1">-- Add support for secure TLS on c2s/s2s connections</span>
|
||||||
|
|
||||||
|
<span class="s2">"blocklist"</span><span class="p">;</span> <span class="c1">-- Allow users to block communications with other users</span>
|
||||||
|
<span class="s2">"bookmarks"</span><span class="p">;</span> <span class="c1">-- Synchronise the list of open rooms between clients</span>
|
||||||
|
<span class="s2">"carbons"</span><span class="p">;</span> <span class="c1">-- Keep multiple online clients in sync</span>
|
||||||
|
<span class="s2">"dialback"</span><span class="p">;</span> <span class="c1">-- Support for verifying remote servers using DNS</span>
|
||||||
|
<span class="s2">"limits"</span><span class="p">;</span> <span class="c1">-- Enable bandwidth limiting for XMPP connections</span>
|
||||||
|
<span class="s2">"pep"</span><span class="p">;</span> <span class="c1">-- Allow users to store public and private data in their account</span>
|
||||||
|
<span class="s2">"private"</span><span class="p">;</span> <span class="c1">-- Legacy account storage mechanism (XEP-0049)</span>
|
||||||
|
<span class="s2">"smacks"</span><span class="p">;</span> <span class="c1">-- Stream management and resumption (XEP-0198)</span>
|
||||||
|
<span class="s2">"vcard4"</span><span class="p">;</span> <span class="c1">-- User profiles (stored in PEP)</span>
|
||||||
|
<span class="s2">"vcard_legacy"</span><span class="p">;</span> <span class="c1">-- Conversion between legacy vCard and PEP Avatar, vcard</span>
|
||||||
|
|
||||||
|
<span class="s2">"csi_simple"</span><span class="p">;</span> <span class="c1">-- Simple but effective traffic optimizations for mobile devices</span>
|
||||||
|
<span class="s2">"invites"</span><span class="p">;</span> <span class="c1">-- Create and manage invites</span>
|
||||||
|
<span class="s2">"invites_adhoc"</span><span class="p">;</span> <span class="c1">-- Allow admins/users to create invitations via their client</span>
|
||||||
|
<span class="s2">"invites_register"</span><span class="p">;</span> <span class="c1">-- Allows invited users to create accounts</span>
|
||||||
|
<span class="s2">"ping"</span><span class="p">;</span> <span class="c1">-- Replies to XMPP pings with pongs</span>
|
||||||
|
<span class="s2">"register"</span><span class="p">;</span> <span class="c1">-- Allow users to register on this server using a client and change passwords</span>
|
||||||
|
<span class="s2">"time"</span><span class="p">;</span> <span class="c1">-- Let others know the time here on this server</span>
|
||||||
|
<span class="s2">"uptime"</span><span class="p">;</span> <span class="c1">-- Report how long server has been running</span>
|
||||||
|
<span class="s2">"version"</span><span class="p">;</span> <span class="c1">-- Replies to server version requests</span>
|
||||||
|
<span class="s2">"mam"</span><span class="p">;</span> <span class="c1">-- Store recent messages to allow multi-device synchronization</span>
|
||||||
|
|
||||||
|
<span class="s2">"admin_adhoc"</span><span class="p">;</span> <span class="c1">-- Allows administration via an XMPP client that supports ad-hoc commands</span>
|
||||||
|
<span class="s2">"admin_shell"</span><span class="p">;</span> <span class="c1">-- Allow secure administration via 'prosodyctl shell'</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">s2s_secure_auth</span> <span class="o">=</span> <span class="kc">true</span>
|
||||||
|
<span class="n">limits</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">c2s</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">rate</span> <span class="o">=</span> <span class="s2">"10kb/s"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="n">s2sin</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">rate</span> <span class="o">=</span> <span class="s2">"30kb/s"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
<span class="n">pidfile</span> <span class="o">=</span> <span class="s2">"/var/run/prosody/prosody.pid"</span>
|
||||||
|
<span class="n">authentication</span> <span class="o">=</span> <span class="s2">"internal_hashed"</span>
|
||||||
|
<span class="n">archive_expires_after</span> <span class="o">=</span> <span class="s2">"1w"</span>
|
||||||
|
|
||||||
|
<span class="n">log</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">info</span> <span class="o">=</span> <span class="s2">"/var/log/prosody/prosody.log"</span><span class="p">;</span>
|
||||||
|
<span class="nb">error</span> <span class="o">=</span> <span class="s2">"/var/log/prosody/prosody.err"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">certificates</span> <span class="o">=</span> <span class="s2">"certs"</span>
|
||||||
|
|
||||||
|
<span class="n">http_interfaces</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"*"</span><span class="p">,</span> <span class="s2">"::"</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">VirtualHost</span> <span class="s2">"chat.example.org"</span>
|
||||||
|
|
||||||
|
<span class="n">disco_items</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="p">{</span> <span class="s2">"file.example.org"</span><span class="p">,</span> <span class="s2">"file sharing service"</span> <span class="p">},</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">http_paths</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">file_share</span> <span class="o">=</span> <span class="s2">"/"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"file.example.org"</span> <span class="s2">"http_file_share"</span>
|
||||||
|
<span class="n">http_file_share_global_quota</span> <span class="o">=</span> <span class="mi">16</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span> <span class="c1">-- 16 Go</span>
|
||||||
|
<span class="n">http_external_url</span> <span class="o">=</span> <span class="s2">"https://file.example.org/"</span>
|
||||||
|
<span class="n">trusted_proxies</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"192.168.1.100"</span><span class="p">,</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"rooms.chat.example.org"</span> <span class="s2">"muc"</span>
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"muc_mam"</span> <span class="p">}</span>
|
||||||
|
<span class="n">name</span> <span class="o">=</span> <span class="s2">"Chatrooms"</span>
|
||||||
|
<span class="n">restrict_room_creation</span> <span class="o">=</span> <span class="s2">"local"</span>
|
||||||
|
<span class="n">muc_room_default_public</span> <span class="o">=</span> <span class="kc">false</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<button title="Toggle Theme" class="theme-toggle">
|
||||||
|
<svg viewBox="0 0 32 32" width="24" height="24" fill="currentcolor">
|
||||||
|
<circle cx="16" cy="16" r="14" fill="none" stroke="currentcolor" stroke-width="4"></circle>
|
||||||
|
<path d="
|
||||||
|
M 16 0
|
||||||
|
A 16 16 0 0 0 16 32
|
||||||
|
z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="credits">
|
||||||
|
Theme forked from <a href="https://github.com/abhinavs/moonwalk" target="_blank" rel="noreferrer">Moonwalk</a>, mixed with <a href="https://github.com/catppuccin/catppuccin" target="_blank" rel="noreferrer">Catppuccin</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -94,6 +94,13 @@
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
|
<li class="post-list-item">
|
||||||
|
<span class="home-date">
|
||||||
|
28-08-2024»
|
||||||
|
</span>
|
||||||
|
<a href="/2024/08/28/xmpp-server.html">Remplacer la conversation Whatsapp familiale par un serveur XMPP</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="post-list-item">
|
<li class="post-list-item">
|
||||||
<span class="home-date">
|
<span class="home-date">
|
||||||
27-07-2024»
|
27-07-2024»
|
||||||
|
|
224
feed.xml
224
feed.xml
|
@ -1,5 +1,217 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://chapoline.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://chapoline.me/" rel="alternate" type="text/html" /><updated>2024-07-27T20:39:38+00:00</updated><id>https://chapoline.me/feed.xml</id><title type="html">Blog de Chapoline</title><subtitle>Blog, articles, et pensées non ordonnées
|
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://chapoline.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://chapoline.me/" rel="alternate" type="text/html" /><updated>2024-08-30T17:48:19+02:00</updated><id>https://chapoline.me/feed.xml</id><title type="html">Blog de Chapoline</title><subtitle>Blog, articles, et pensées non ordonnées
|
||||||
</subtitle><author><name>Caroline Canebier</name></author><entry><title type="html">Utiliser Firefox comme lecteur minimaliste</title><link href="https://chapoline.me/2024/07/27/firefox-minimal.html" rel="alternate" type="text/html" title="Utiliser Firefox comme lecteur minimaliste" /><published>2024-07-27T00:00:00+00:00</published><updated>2024-07-27T00:00:00+00:00</updated><id>https://chapoline.me/2024/07/27/firefox-minimal</id><content type="html" xml:base="https://chapoline.me/2024/07/27/firefox-minimal.html"><p>Je cherchais un moyen minimaliste pour pouvoir lire un pdf ou un manga dans Firefox, en épurant au maximum ma fenêtre. Deux options sont courantes : mettre la fenêtre en plein écran, ou utiliser une extension de navigateur dédiée. Mais ça ne doit pas être si difficile à faire à la main ? Voyons comment faire cela.</p>
|
</subtitle><author><name>Caroline Canebier</name></author><entry><title type="html">Remplacer la conversation Whatsapp familiale par un serveur XMPP</title><link href="https://chapoline.me/2024/08/28/xmpp-server.html" rel="alternate" type="text/html" title="Remplacer la conversation Whatsapp familiale par un serveur XMPP" /><published>2024-08-28T00:00:00+02:00</published><updated>2024-08-28T00:00:00+02:00</updated><id>https://chapoline.me/2024/08/28/xmpp-server</id><content type="html" xml:base="https://chapoline.me/2024/08/28/xmpp-server.html"><p>Tout le monde aujourd’hui a, dans sa famille, une conversation Whatsapp/Telegram/Messenger/autre, en remplacement des SMS de la décennie précédente. Mais avec l’enshitification ambiante d’Internet, il devient de plus en plus essentiel d’avoir des options pour rester en contact avec ses proches sans passer par des applications propriétaires peu respectueuses de la vie privée. XMPP est une excellente solution à ça, et en installer un serveur est un projet sympathique et assez facile.</p>
|
||||||
|
|
||||||
|
<p>XMPP est un protocol décentralisé d’échange de données en temps réel. Plus simplement, c’est un très bon protocol pour construire des systèmes fédérés de discussion instantannée, ce qui est exactement ce que l’on va faire. Le protocol est défini via quelques RFC, et définit également des extensions à travers des <a href="https://xmpp.org/extensions/">XEP</a>. Plusieurs de ces XEP sont aujourd’hui très standard et sont installées et activées par défaut (comme la <a href="https://xmpp.org/extensions/xep-0012.html">XEP-0012</a>). Enfin, XMPP propose aujourd’hui du chiffrement bout-en-bout mature et automatique (<a href="https://xmpp.org/extensions/xep-0384.html">XEP-0384</a>).</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Les différentes étapes de cet article sont :</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#environnement">Une description de l’environnement dans lequel le serveur XMPP va être déployé</a></li>
|
||||||
|
<li><a href="#installation-et-configuration-initiale">L’installation et la configuration du serveur XMPP en lui-même</a></li>
|
||||||
|
<li><a href="#file-sharing-et-muc">La configuration de quelques fonctionnalités supplémentaires (partage de fichier et rooms)</a></li>
|
||||||
|
<li><a href="#fichier-de-configuration-final">La configuration finale du serveur</a></li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<h2 id="environnement">Environnement</h2>
|
||||||
|
|
||||||
|
<p>Pour monter un serveur XMPP, il est nécessaire d’avoir au moins un nom de domaine public, et si possible plusieurs sous-domaines dédiés au projet. Il est également nécessaire d’avoir une ip publique, avec a minima les ports tcp 5222 et 5269 accessibles.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Dans cet article, je prends comme noms de domaines <code class="language-plaintext highlighter-rouge">example.org</code> et ses sous-domaines, et comme ip publique <code class="language-plaintext highlighter-rouge">198.51.100.5</code>. Le serveur lui-même est sur l’ip <code class="language-plaintext highlighter-rouge">192.168.1.200/24</code>, derrière un NAT. J’utilise également un reverse-proxy dédié (puisque je n’ai qu’une ip publique), dont l’ip privée est <code class="language-plaintext highlighter-rouge">192.168.1.100</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p><a href="https://prosody.im">Prosody</a> et <a href="https://www.ejabberd.im">edjabberd</a> sont deux implémentations modernes de serveur XMPP, et les deux sont des choix très pertinents. Pour ma part, j’ai choisi Prosody.</p>
|
||||||
|
|
||||||
|
<p>Pour installer Prosody, j’utilise un serveur Debian 11, avec 2 vCPU, 2Go de ram et 32Go de disque (à titre purement indicatif, je n’ai pas fait de benchmark pour vérifier la pertinence de ces ressources).</p>
|
||||||
|
|
||||||
|
<h2 id="installation-et-configuration-initiale">Installation et configuration initiale</h2>
|
||||||
|
|
||||||
|
<p>L’installation sous debian se fait via le repo officiel de Prosody :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo </span>deb http://packages.prosody.im/debian <span class="si">$(</span>lsb_release <span class="nt">-sc</span><span class="si">)</span> main | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/prosody.list
|
||||||
|
<span class="nb">sudo </span>wget https://prosody.im/files/prosody-debian-packages.key <span class="nt">-O</span> /etc/apt/trusted.gpg.d/prosody.gpg
|
||||||
|
<span class="nb">sudo </span>apt update
|
||||||
|
<span class="nb">sudo </span>apt <span class="nb">install </span>prosody
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Toute la configuration se fait ensuite dans <code class="language-plaintext highlighter-rouge">/etc/prosody/prosody.cfg.lua</code>.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Le fichier de configuration complet est disponible à la fin du guide. J’ai enlevé les commentaires du fichier par défaut par soucis de clareté, mais je vous conseille de les laisser !</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>La configuration commence par charger une liste de modules. La liste par défaut est un bon point de départ ; j’ai simplement décommenté le module <code class="language-plaintext highlighter-rouge">mam</code>, qui permet de conserver un historique des messages sur le serveur.</p>
|
||||||
|
|
||||||
|
<p>On peut ensuite indiquer à Prosody quelle ip publique est utilisée pour accéder au service, ce qui lui permet de vérifier lui même si la configuration DNS est correcte :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">external_addresses</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"198.51.100.5"</span> <span class="p">}</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Enfin, il faut créer un VirtualHost, ce qui correspond à un domaine sur lequel Prosody va écouter (en gros, un serveur XMPP séparé). Attention, toutes les options de configuration définies après ne s’appliqueront qu’au VirtualHost !</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">VirtualHost</span> <span class="s2">"chat.example.org"</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Et voilà, juste avec ça, on a un serveur XMPP fonctionnel ! Mais avant de l’utiliser, nous allons au moins mettre en place un certificat TLS pour sécuriser les connexions entre les clients et le serveur, et entre notre serveur et les autres. Pour cela, un peu de DNS et de reverse proxy s’impose. Faisons donc pointer <code class="language-plaintext highlighter-rouge">chat.example.org</code> sur notre ip publique, puis ajoutons juste ce qu’il faut de reverse proxy :</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>J’utilise NixOS pour gérer mon reverse proxy. Je vous laisse adapter cette configuration pour nginx si ce n’est pas votre cas.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">services</span><span class="o">.</span><span class="nv">nginx</span><span class="o">.</span><span class="s2">"chat.example.org"</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="nv">locations</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"/"</span><span class="o">.</span><span class="nv">proxyPass</span> <span class="o">=</span> <span class="s2">"http://192.168.1.200:80"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Cette configuration de nginx n’écoute que sur le port 80, et reverse-proxyfie les requêtes sur le port 80 de la VM Prosody. Elle ne sert qu’à faire fonctionner le challenge Let’s Encrypt qui va venir :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>certbot certonly <span class="nt">--standalone</span> <span class="nt">-d</span> chat.example.org
|
||||||
|
<span class="nv">$ </span>prosodyctl <span class="nt">--root</span> cert import /etc/letsencrypt/live
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Pour vérifier que tout fonctionne, on peut utiliser <code class="language-plaintext highlighter-rouge">prosodyctl</code> :</p>
|
||||||
|
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ prosodyctl check certs
|
||||||
|
Checking certificates...
|
||||||
|
Checking certificate for chat.example.org
|
||||||
|
Certificate: /etc/prosody/certs/chat.example.org.crt
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Et voilà ! N’oubliez pas de forward les ports tcp 5222 et 5269 sur votre firewall, et votre serveur XMPP devrait être fonctionnel. Pour ajouter des utilisateurs, utilisez la cli :</p>
|
||||||
|
|
||||||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>prosodyctl adduser user@chat.example.org
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<h2 id="file-sharing-et-muc">File sharing et MUC</h2>
|
||||||
|
|
||||||
|
<p>Afin de rajouter quelques fonctionnalités à notre serveur, nous allons rajouter un vrai service de partage de fichier (actuellement, le partage de fichiers fonctionne, mais uniquement en peer-to-peer), ainsi que la possibilité de créer des rooms de discussion.</p>
|
||||||
|
|
||||||
|
<p>Ces deux fonctionnalités s’ajoutent via des <em>Components</em>, qui se configurent à la suite du VirtualHost :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">disco_items</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="p">{</span> <span class="s2">"file.example.org"</span><span class="p">,</span> <span class="s2">"file sharing service"</span> <span class="p">},</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">http_paths</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">file_share</span> <span class="o">=</span> <span class="s2">"/"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"file.example.org"</span> <span class="s2">"http_file_share"</span>
|
||||||
|
<span class="n">http_file_share_global_quota</span> <span class="o">=</span> <span class="mi">16</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span> <span class="c1">-- 16 Go</span>
|
||||||
|
<span class="n">http_external_url</span> <span class="o">=</span> <span class="s2">"https://file.example.org/"</span>
|
||||||
|
<span class="n">trusted_proxies</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"192.168.1.100"</span><span class="p">,</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"rooms.chat.example.org"</span> <span class="s2">"muc"</span>
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"muc_mam"</span> <span class="p">}</span>
|
||||||
|
<span class="n">name</span> <span class="o">=</span> <span class="s2">"Chatrooms"</span>
|
||||||
|
<span class="n">restrict_room_creation</span> <span class="o">=</span> <span class="s2">"local"</span>
|
||||||
|
<span class="n">muc_room_default_public</span> <span class="o">=</span> <span class="kc">false</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Le service de partage de fichier, qui va être configuré derrière le reverse proxy, a besoin de connaitre son url d’accès pour générer correctement les liens. On lui configure également son quota global, et l’adresse ip du serveur proxy afin de l’autoriser.</p>
|
||||||
|
|
||||||
|
<p>Pour éviter que les liens générés soient préfixés par <code class="language-plaintext highlighter-rouge">file_share/</code>, on redéfinit son <code class="language-plaintext highlighter-rouge">http_path</code>. Enfin, pour que les clients puisse découvrir le service et parce qu’il n’est pas sur un sous-domaine de <code class="language-plaintext highlighter-rouge">chat.example.org</code>, on le définit dans la liste des services à découvrir.</p>
|
||||||
|
|
||||||
|
<p>Côté MUC, on active également le stockage des messages récents sur le serveur, on autorise uniquement les comptes locaux à créer de nouvelles rooms (même si n’importe qui peut ensuite les rejoindre), et on crée les rooms comme étant privées par défaut.</p>
|
||||||
|
|
||||||
|
<p>Afin que le reverse proxy fonctionne, il faut également faire écouter le port HTTP de Prosody sur <code class="language-plaintext highlighter-rouge">0.0.0.0</code> au lieu de <code class="language-plaintext highlighter-rouge">localhost</code> par défaut :</p>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">http_interfaces</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"*"</span><span class="p">,</span> <span class="s2">"::"</span> <span class="p">}</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>On peut à présent configurer notre reverse proxy, cette fois avec HTTPS :</p>
|
||||||
|
|
||||||
|
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">services</span><span class="o">.</span><span class="nv">nginx</span><span class="o">.</span><span class="s2">"file.example.org"</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="nv">enableACME</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
||||||
|
<span class="nv">forceSSL</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
||||||
|
<span class="nv">locations</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"/"</span><span class="o">.</span><span class="nv">proxyPass</span> <span class="o">=</span> <span class="s2">"http://192.168.1.200:5280"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<h2 id="fichier-de-configuration-final">Fichier de configuration final</h2>
|
||||||
|
|
||||||
|
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">external_addresses</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"198.51.100.5"</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="s2">"disco"</span><span class="p">;</span> <span class="c1">-- Service discovery</span>
|
||||||
|
<span class="s2">"roster"</span><span class="p">;</span> <span class="c1">-- Allow users to have a roster. Recommended ;)</span>
|
||||||
|
<span class="s2">"saslauth"</span><span class="p">;</span> <span class="c1">-- Authentication for clients and servers. Recommended if you want to log in.</span>
|
||||||
|
<span class="s2">"tls"</span><span class="p">;</span> <span class="c1">-- Add support for secure TLS on c2s/s2s connections</span>
|
||||||
|
|
||||||
|
<span class="s2">"blocklist"</span><span class="p">;</span> <span class="c1">-- Allow users to block communications with other users</span>
|
||||||
|
<span class="s2">"bookmarks"</span><span class="p">;</span> <span class="c1">-- Synchronise the list of open rooms between clients</span>
|
||||||
|
<span class="s2">"carbons"</span><span class="p">;</span> <span class="c1">-- Keep multiple online clients in sync</span>
|
||||||
|
<span class="s2">"dialback"</span><span class="p">;</span> <span class="c1">-- Support for verifying remote servers using DNS</span>
|
||||||
|
<span class="s2">"limits"</span><span class="p">;</span> <span class="c1">-- Enable bandwidth limiting for XMPP connections</span>
|
||||||
|
<span class="s2">"pep"</span><span class="p">;</span> <span class="c1">-- Allow users to store public and private data in their account</span>
|
||||||
|
<span class="s2">"private"</span><span class="p">;</span> <span class="c1">-- Legacy account storage mechanism (XEP-0049)</span>
|
||||||
|
<span class="s2">"smacks"</span><span class="p">;</span> <span class="c1">-- Stream management and resumption (XEP-0198)</span>
|
||||||
|
<span class="s2">"vcard4"</span><span class="p">;</span> <span class="c1">-- User profiles (stored in PEP)</span>
|
||||||
|
<span class="s2">"vcard_legacy"</span><span class="p">;</span> <span class="c1">-- Conversion between legacy vCard and PEP Avatar, vcard</span>
|
||||||
|
|
||||||
|
<span class="s2">"csi_simple"</span><span class="p">;</span> <span class="c1">-- Simple but effective traffic optimizations for mobile devices</span>
|
||||||
|
<span class="s2">"invites"</span><span class="p">;</span> <span class="c1">-- Create and manage invites</span>
|
||||||
|
<span class="s2">"invites_adhoc"</span><span class="p">;</span> <span class="c1">-- Allow admins/users to create invitations via their client</span>
|
||||||
|
<span class="s2">"invites_register"</span><span class="p">;</span> <span class="c1">-- Allows invited users to create accounts</span>
|
||||||
|
<span class="s2">"ping"</span><span class="p">;</span> <span class="c1">-- Replies to XMPP pings with pongs</span>
|
||||||
|
<span class="s2">"register"</span><span class="p">;</span> <span class="c1">-- Allow users to register on this server using a client and change passwords</span>
|
||||||
|
<span class="s2">"time"</span><span class="p">;</span> <span class="c1">-- Let others know the time here on this server</span>
|
||||||
|
<span class="s2">"uptime"</span><span class="p">;</span> <span class="c1">-- Report how long server has been running</span>
|
||||||
|
<span class="s2">"version"</span><span class="p">;</span> <span class="c1">-- Replies to server version requests</span>
|
||||||
|
<span class="s2">"mam"</span><span class="p">;</span> <span class="c1">-- Store recent messages to allow multi-device synchronization</span>
|
||||||
|
|
||||||
|
<span class="s2">"admin_adhoc"</span><span class="p">;</span> <span class="c1">-- Allows administration via an XMPP client that supports ad-hoc commands</span>
|
||||||
|
<span class="s2">"admin_shell"</span><span class="p">;</span> <span class="c1">-- Allow secure administration via 'prosodyctl shell'</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">s2s_secure_auth</span> <span class="o">=</span> <span class="kc">true</span>
|
||||||
|
<span class="n">limits</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">c2s</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">rate</span> <span class="o">=</span> <span class="s2">"10kb/s"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="n">s2sin</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">rate</span> <span class="o">=</span> <span class="s2">"30kb/s"</span><span class="p">;</span>
|
||||||
|
<span class="p">};</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
<span class="n">pidfile</span> <span class="o">=</span> <span class="s2">"/var/run/prosody/prosody.pid"</span>
|
||||||
|
<span class="n">authentication</span> <span class="o">=</span> <span class="s2">"internal_hashed"</span>
|
||||||
|
<span class="n">archive_expires_after</span> <span class="o">=</span> <span class="s2">"1w"</span>
|
||||||
|
|
||||||
|
<span class="n">log</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">info</span> <span class="o">=</span> <span class="s2">"/var/log/prosody/prosody.log"</span><span class="p">;</span>
|
||||||
|
<span class="nb">error</span> <span class="o">=</span> <span class="s2">"/var/log/prosody/prosody.err"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">certificates</span> <span class="o">=</span> <span class="s2">"certs"</span>
|
||||||
|
|
||||||
|
<span class="n">http_interfaces</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"*"</span><span class="p">,</span> <span class="s2">"::"</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">VirtualHost</span> <span class="s2">"chat.example.org"</span>
|
||||||
|
|
||||||
|
<span class="n">disco_items</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="p">{</span> <span class="s2">"file.example.org"</span><span class="p">,</span> <span class="s2">"file sharing service"</span> <span class="p">},</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">http_paths</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="n">file_share</span> <span class="o">=</span> <span class="s2">"/"</span><span class="p">;</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"file.example.org"</span> <span class="s2">"http_file_share"</span>
|
||||||
|
<span class="n">http_file_share_global_quota</span> <span class="o">=</span> <span class="mi">16</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span> <span class="c1">-- 16 Go</span>
|
||||||
|
<span class="n">http_external_url</span> <span class="o">=</span> <span class="s2">"https://file.example.org/"</span>
|
||||||
|
<span class="n">trusted_proxies</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"192.168.1.100"</span><span class="p">,</span> <span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">Component</span> <span class="s2">"rooms.chat.example.org"</span> <span class="s2">"muc"</span>
|
||||||
|
<span class="n">modules_enabled</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"muc_mam"</span> <span class="p">}</span>
|
||||||
|
<span class="n">name</span> <span class="o">=</span> <span class="s2">"Chatrooms"</span>
|
||||||
|
<span class="n">restrict_room_creation</span> <span class="o">=</span> <span class="s2">"local"</span>
|
||||||
|
<span class="n">muc_room_default_public</span> <span class="o">=</span> <span class="kc">false</span>
|
||||||
|
</code></pre></div></div></content><author><name>Caroline Canebier</name></author><category term="sysadmin" /><category term="mainpage" /><summary type="html">Tout le monde aujourd’hui a, dans sa famille, une conversation Whatsapp/Telegram/Messenger/autre, en remplacement des SMS de la décennie précédente. Mais avec l’enshitification ambiante d’Internet, il devient de plus en plus essentiel d’avoir des options pour rester en contact avec ses proches sans passer par des applications propriétaires peu respectueuses de la vie privée. XMPP est une excellente solution à ça, et en installer un serveur est un projet sympathique et assez facile.</summary></entry><entry><title type="html">Utiliser Firefox comme lecteur minimaliste</title><link href="https://chapoline.me/2024/07/27/firefox-minimal.html" rel="alternate" type="text/html" title="Utiliser Firefox comme lecteur minimaliste" /><published>2024-07-27T00:00:00+02:00</published><updated>2024-07-27T00:00:00+02:00</updated><id>https://chapoline.me/2024/07/27/firefox-minimal</id><content type="html" xml:base="https://chapoline.me/2024/07/27/firefox-minimal.html"><p>Je cherchais un moyen minimaliste pour pouvoir lire un pdf ou un manga dans Firefox, en épurant au maximum ma fenêtre. Deux options sont courantes : mettre la fenêtre en plein écran, ou utiliser une extension de navigateur dédiée. Mais ça ne doit pas être si difficile à faire à la main ? Voyons comment faire cela.</p>
|
||||||
|
|
||||||
<h2 id="création-dun-profil-dédié">Création d’un profil dédié</h2>
|
<h2 id="création-dun-profil-dédié">Création d’un profil dédié</h2>
|
||||||
|
|
||||||
|
@ -32,16 +244,16 @@
|
||||||
<li>Pour lancer Firefox directement sur le profil <code class="language-plaintext highlighter-rouge">pdf</code>, lancez le avec <code class="language-plaintext highlighter-rouge">firefox -P pdf [file.pdf]</code>.</li>
|
<li>Pour lancer Firefox directement sur le profil <code class="language-plaintext highlighter-rouge">pdf</code>, lancez le avec <code class="language-plaintext highlighter-rouge">firefox -P pdf [file.pdf]</code>.</li>
|
||||||
<li>Sans interface, la navigation au clavier est très utile : <code class="language-plaintext highlighter-rouge">ctrl+tab</code> pour cycler les onglets ouverts, <code class="language-plaintext highlighter-rouge">ctrl+t</code> pour ouvrir un nouvel onglet, <code class="language-plaintext highlighter-rouge">ctrl+o</code> pour ouvrir un fichier, ou <code class="language-plaintext highlighter-rouge">alt+left</code> pour revenir à la page précédente par exemple.</li>
|
<li>Sans interface, la navigation au clavier est très utile : <code class="language-plaintext highlighter-rouge">ctrl+tab</code> pour cycler les onglets ouverts, <code class="language-plaintext highlighter-rouge">ctrl+t</code> pour ouvrir un nouvel onglet, <code class="language-plaintext highlighter-rouge">ctrl+o</code> pour ouvrir un fichier, ou <code class="language-plaintext highlighter-rouge">alt+left</code> pour revenir à la page précédente par exemple.</li>
|
||||||
<li>Attention, la barre d’URL est totalement inaccessible dans ce mode, y compris avec <code class="language-plaintext highlighter-rouge">F6</code>. Pensez à utiliser des marques-page (<code class="language-plaintext highlighter-rouge">ctrl+shift+o</code> pour ouvrir le menu), ou à épingler des pages sur la page de nouvel onglet.</li>
|
<li>Attention, la barre d’URL est totalement inaccessible dans ce mode, y compris avec <code class="language-plaintext highlighter-rouge">F6</code>. Pensez à utiliser des marques-page (<code class="language-plaintext highlighter-rouge">ctrl+shift+o</code> pour ouvrir le menu), ou à épingler des pages sur la page de nouvel onglet.</li>
|
||||||
</ul></content><author><name>Caroline Canebier</name></author><category term="linux" /><category term="mainpage" /><summary type="html">Je cherchais un moyen minimaliste pour pouvoir lire un pdf ou un manga dans Firefox, en épurant au maximum ma fenêtre. Deux options sont courantes : mettre la fenêtre en plein écran, ou utiliser une extension de navigateur dédiée. Mais ça ne doit pas être si difficile à faire à la main ? Voyons comment faire cela.</summary></entry><entry><title type="html">Faire du Backup-as-a-Service avec Restic et Minio</title><link href="https://chapoline.me/2024/06/11/backup-minio.html" rel="alternate" type="text/html" title="Faire du Backup-as-a-Service avec Restic et Minio" /><published>2024-06-11T00:00:00+00:00</published><updated>2024-06-11T00:00:00+00:00</updated><id>https://chapoline.me/2024/06/11/backup-minio</id><content type="html" xml:base="https://chapoline.me/2024/06/11/backup-minio.html"><p>Pour mon infrastructure de backups, j’utilise depuis plusieurs années <a href="https://www.borgbackup.org/">BorgBackup</a>, un excellent outil pour chiffrer et dédupliquer ses sauvegardes, puis les stocker via SSH. Pour les sauvegardes de mes serveurs, il m’offre une complète satisfaction. Mais je voulais explorer un nouvel outil dont on m’avait dit beaucoup de bien, et je voulais essayer de faire du Backup-as-a-Service.</p>
|
</ul></content><author><name>Caroline Canebier</name></author><category term="linux" /><category term="mainpage" /><summary type="html">Je cherchais un moyen minimaliste pour pouvoir lire un pdf ou un manga dans Firefox, en épurant au maximum ma fenêtre. Deux options sont courantes : mettre la fenêtre en plein écran, ou utiliser une extension de navigateur dédiée. Mais ça ne doit pas être si difficile à faire à la main ? Voyons comment faire cela.</summary></entry><entry><title type="html">Faire du Backup-as-a-Service avec Restic et Minio</title><link href="https://chapoline.me/2024/06/11/backup-minio.html" rel="alternate" type="text/html" title="Faire du Backup-as-a-Service avec Restic et Minio" /><published>2024-06-11T00:00:00+02:00</published><updated>2024-06-11T00:00:00+02:00</updated><id>https://chapoline.me/2024/06/11/backup-minio</id><content type="html" xml:base="https://chapoline.me/2024/06/11/backup-minio.html"><p>Pour mon infrastructure de backups, j’utilise depuis plusieurs années <a href="https://www.borgbackup.org/">BorgBackup</a>, un excellent outil pour chiffrer et dédupliquer ses sauvegardes, puis les stocker via SSH. Pour les sauvegardes de mes serveurs, il m’offre une complète satisfaction. Mais je voulais explorer un nouvel outil dont on m’avait dit beaucoup de bien, et je voulais essayer de faire du Backup-as-a-Service.</p>
|
||||||
|
|
||||||
<p>Les besoins sont simple : les utilisateurs ayant un compte sur mon service de SSO devraient pouvoir se connecter sur un service, créer une clé dédiée à une application, puis utiliser cette clé pour backup une machine, serveur ou PC, et envoyer les données sur mon serveur central. Les backups créés devraient être chiffrés, dédupliqués, et avec une gestion des droits pour ne pas permettre à un utilisateur d’écraser ou de modifier les backups des autres (tout étant chiffré, l’accès en lecture est moins critique). Si possible, le service devrait pouvoir définir des quotas par utilisateur ; malheureusement, la solution que j’ai trouvée ne le permet pas.</p>
|
<p>Les besoins sont simple : les utilisateurs ayant un compte sur mon service de SSO devraient pouvoir se connecter sur un service, créer une clé dédiée à une application, puis utiliser cette clé pour backup une machine, serveur ou PC, et envoyer les données sur mon serveur central. Les backups créés devraient être chiffrés, dédupliqués, et avec une gestion des droits pour ne pas permettre à un utilisateur d’écraser ou de modifier les backups des autres (tout étant chiffré, l’accès en lecture est moins critique). Si possible, le service devrait pouvoir définir des quotas par utilisateur ; malheureusement, la solution que j’ai trouvée ne le permet pas.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Les différentes étapes de l’articles sont :</p>
|
<p>Les différentes étapes de l’article sont :</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#faire-ses-backups-simplement">Installer restic et écrire un script pour le lancer</a></li>
|
<li><a href="#faire-ses-backups-simplement">Installer restic et écrire un script pour le lancer</a></li>
|
||||||
<li><a href="stocker-ses-backups-quelque-part">Installer MinIO, et tester que restic fonctionne avec MinIO</a></li>
|
<li><a href="#stocker-ses-backups-quelque-part">Installer MinIO, et tester que restic fonctionne avec MinIO</a></li>
|
||||||
<li><a href="et-ma-sso-dans-tout-ça-">Configurer restic pour fonctionner avec MinIO en SSO</a></li>
|
<li><a href="#et-ma-sso-dans-tout-ça-">Configurer restic pour fonctionner avec MinIO en SSO</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,13 @@
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li class="post-list-item">
|
||||||
|
<span class="home-date">
|
||||||
|
28-08-2024»
|
||||||
|
</span>
|
||||||
|
<a href="/2024/08/28/xmpp-server.html">Remplacer la conversation Whatsapp familiale par un serveur XMPP</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="post-list-item">
|
<li class="post-list-item">
|
||||||
<span class="home-date">
|
<span class="home-date">
|
||||||
27-07-2024»
|
27-07-2024»
|
||||||
|
|
Loading…
Add table
Reference in a new issue