<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Nicolas Guilloux</title><link>https://nicolasguilloux.eu/post/</link><description>Recent content in Posts on Nicolas Guilloux</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><lastBuildDate>Tue, 17 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://nicolasguilloux.eu/post/index.xml" rel="self" type="application/rss+xml"/><item><title>Ma stack Network</title><link>https://nicolasguilloux.eu/articles/network-stack/</link><pubDate>Tue, 17 Feb 2026 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/network-stack/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Ma stack Network" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Je pense que le réseau est la pierre angulaire de tout Homelab qui se respecte. Pas besoin de choses overkill juste pour héberger quelques services, mais dès lors que l’IOT s’invite à la fête, il vaut mieux avoir quelque chose de solide.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je suis parti sur Unifi, car je ne suis pas un pro du réseau et je voulais quelque chose qui fonctionne bien, qui permette un contrôle fin de mon réseau tout en me prenant par la main pour sa configuration. En plus, la partie Camera me tentait bien !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_hardware"&gt;Hardware&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_unifi_dream_machine_se"&gt;&lt;a href="https://eu.store.ui.com/eu/en/category/cloud-gateways-large-scale/products/udm-se" target="_blank" rel="noopener"&gt;Unifi Dream Machine SE&lt;/a&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="udm.png" alt="Unifi Dream Machine SE"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ou UDM pour les intimes. C’est le centre névralgique du réseau. C’est une passerelle tout-en-un au format rack 1U qui fait office de routeur, de pare-feu, de switch PoE et même de NVR (enregistreur vidéo réseau) pour les caméras Unifi Protect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Côté performances, on parle d’un routage avec la stack de sécurité qui supporte un débit de ~5 Gbps pour ma configuration. Autant dire que même en activant toutes les protections réseau, ça ne bronche pas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ce qui m’a particulièrement séduit, c’est la connectique :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;8 ports LAN 1 GbE RJ45&lt;/strong&gt; dont 6 ports PoE 15W et 2 ports PoE+ 30W (130W au total) — parfait pour alimenter des access points et caméras sans câbles d’alimentation supplémentaires&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2 ports LAN 10G SFP+&lt;/strong&gt; — pour les liaisons rapides avec ma Freebox pro et un switch principal&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le tout est géré via l’interface UniFi OS qui centralise la gestion du réseau, des caméras, du contrôle d’accès…​ C’est propre, c’est intuitif, et ça donne accès à l’ensemble de la suite applicative Unifi (Network, Protect et Connect).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Au départ, j’ai choisi ce matos car il permettait effectivement d’avoir suffisamment de ports en PoE+ pour mettre deux points d’accès et assez d’autres ports pour mes besoins. Je prévoyais aussi l’arrivée de la fibre, ainsi qu’éventuellement rajouter du matos sur le port SFP. Ce qui n’a pas manqué…​&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_usw_pro_max_16_poe"&gt;&lt;a href="https://eu.store.ui.com/eu/en/category/all-switching/products/usw-pro-max-16-poe" target="_blank" rel="noopener"&gt;USW Pro Max 16 PoE&lt;/a&gt;&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="usw-pro-max.png" alt="USW Pro Max 16 PoE"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Quand on commence à brancher des équipements un peu partout, les 8 ports du UDM SE ne suffisent plus. C’est là que ce switch entre en jeu. Le USW Pro Max 16 PoE est un switch managé au format rack 1U qui vient compléter l’infrastructure avec 16 ports supplémentaires et surtout du PoE++ pour les équipements les plus gourmands. Là, je devrais être bulletproof pour le futur.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Côté connectique, c’est bien fourni :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;12 ports 1 GbE RJ45&lt;/strong&gt; avec PoE+ (30W par port) — pour les access points, caméras et autres équipements classiques&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;4 ports 2.5 GbE RJ45&lt;/strong&gt; avec PoE++ (60W par port) — pour les équipements nécessitant plus de bande passante ou de puissance, comme des access points WiFi 7&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2 ports 10G SFP+&lt;/strong&gt; — pour les uplinks vers le UDM SE ou d’autres switches&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le petit plus sympa, c’est l’Etherlighting : chaque port s’illumine pour indiquer son état (vitesse de liaison, VLAN natif…​). C’est gadget, mais en pratique c’est super utile pour diagnostiquer un problème de câblage d’un coup d’œil dans le rack. Je suis pas très RGB d’habitude, mais je dois avouer que ça fait son petit effet !&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_autres"&gt;Autres&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour la partie réseau filaire, j’ai quelques petits &lt;a href="https://eu.store.ui.com/eu/en/category/switching-utility/products/usw-flex-mini" target="_blank" rel="noopener"&gt;USW Flex Mini&lt;/a&gt; ça et là pour de l’appoint. Par exemple, mon meuble télévision n’a pas besoin de hautes vitesses, donc pour connecter l’Apple TV, la Switch et d’autres appareils, c’est suffisant.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour la partie réseau sans fil, j’ai plusieurs points d’accès. Je suis obligé d’en avoir au moins 3 ou 4 pour avoir une couverture acceptable dans ma maison à cause de ses énormes murs en terre de 60cm d’épaisseur. Aucun WiFi ne saurait traverser ça sereinement ! Comme la maison a été bâtie autour de ces murs en terre, j’ai donc 3 zones à couvrir en intérieur, une large zone en extérieur.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_la_configuration_générale"&gt;La Configuration Générale&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ça, c’est le nerf de la guerre. C’est là qu’on peaufine tout et que mon attrait pour la bidouille prend tout son sens. C’est sympa de monter un rack, mais c’est encore plus satisfaisant de le paramétrer !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_internet"&gt;Internet&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai une fibre Free Pro de 8 Gbps symétrique. Toutefois, je n’utiliserai jamais plus de 5 Gbps car les couches de sécurité de mon UDM limitent le débit en analysant les paquets. C’est un bottleneck que je trouve acceptable pour mon utilisation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je suis obligé d’utiliser la Freebox Pro car brancher la fibre directement dans le port fibre de la UDM ne fonctionne pas. Probablement une authentification propriétaire, dans tous les cas le support ne m’a pas aidé à me passer de leur box. Un câble SFP+ relie donc mon UDM à ma Freebox Pro.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai en plus un modem 4G de backup si jamais la connexion principale est down.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Enfin, j’ai un client &lt;a href="https://protonvpn.com" target="_blank" rel="noopener"&gt;ProtonVPN&lt;/a&gt; pour router une partie du trafic dans un tunnel chiffré. Je l’utilise principalement pour anonymiser certaines connexions.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_vlan"&gt;VLAN&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Tout s’axe autour des VLAN qui sont des réseaux virtuels sur lesquels les appareils se connectent.&lt;br/&gt;
Généralement, on utilise les VLAN pour cloisonner le réseau en fonction des appareils. Voici les miens :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Main&lt;/strong&gt; : Correspond au par défaut, sans restriction. Je ne suis pas sûr que ce soit une très bonne pratique de le garder comme tel. Il sert aux appareils réseaux de Unifi.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Devices&lt;/strong&gt; : Tous les appareils comme les téléphones, ordinateurs et les invités. Par défaut, le réseau est cloisonné et les appareils ne peuvent parler à aucun autre appareil sur le réseau.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Servers&lt;/strong&gt; : Le nom est plutôt explicite. Généralement ce sont des appareils qui sont statiques et ne sont pas voués à être offline.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Virtual Machines&lt;/strong&gt; : Les machines virtuelles utilisent ce réseau qui par défaut est isolé.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IoT&lt;/strong&gt; : Tous les appareils IoT. Par défaut, les appareils ne devraient pas avoir accès à internet, et ont tous accès à ma centrale domotique.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;div class="title"&gt;Note&lt;/div&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Un dernier VLAN nommé NoT est présent actuellement mais voué à disparaître. Les appareils IoT ont actuellement accès à internet, et les NoT non. À terme, je vais refuser l’accès à tous par défaut, puis autoriser certains domaines au cas par cas. Le VLAN IoT actuel est donc trop laxiste.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_wifi"&gt;WiFi&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;En vrai c’est plutôt anecdotique. Il y a deux réseaux à savoir un commun qui envoie dans le VLAN &lt;code&gt;Devices&lt;/code&gt;, et un autre, caché, dédié aux appareils IoT, qui envoie dans le VLAN &lt;code&gt;IoT&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je réserve le 2.4GHz pour les appareils legacy, et le 5GHz pour les appareils qui le supportent.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_firewall"&gt;Firewall&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Disons-le, c’est la partie sécurité la plus importante. C’est ici qu’on autorise ou non un paquet à faire son petit bonhomme de chemin sur notre réseau, à un appareil de contacter un autre.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_les_objets"&gt;Les Objets&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Les règles &amp;#34;objets&amp;#34; servent à viser un réseau ou un appareil spécifique et lui donner des règles simples, prioritaires par rapport aux autres règles. Le contrôle que l’on peut avoir sur la configuration est assez limité ici, donc je ne l’utilise que pour des règles simples.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Une règle visant le réseau &lt;code&gt;Devices&lt;/code&gt; qui route certains domaines sur la partie VPN.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L’objet réseau HomeAssistant qui a le droit de contacter tout le VLAN IoT.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Certains appareils ont 100% de leur trafic routé vers le VPN.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_les_zones"&gt;Les Zones&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Un bon schéma vaut mieux qu’un long discours, voici un screenshot du mapping des VLAN sur mon réseau :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="firewall-zones.png" alt="A screenshot of the Zones configuration"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je vais maintenant trier les règles par zone source. Concrètement, c’est surtout trois zones qui sont importantes : IoT, Devices et Servers. La partie Virtual Machines est au cas par cas et souvent éphémère.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour le tableau suivant, on parle des privilèges qu’ont les appareils IoT sur le réseau. Comme ces appareils sont très variés et sont sur une zone volontairement restrictive, il y a beaucoup de règles précises.&lt;/p&gt;
&lt;/div&gt;
&lt;table class="tableblock frame-all grid-all stretch"&gt;
&lt;colgroup&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.667%;"/&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Nom&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Zone Src&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Src&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Zone Dest&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Dest&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;AirPlay → AirPlay&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;AirPlay Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;AirPlay Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet aux appareils supportant AirPlay à échanger&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HomeKit Bridge → Camera&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Apple TV&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Camera&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à l’Apple TV de se connecter directement aux caméras&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT → HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Servers&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils IoT de dialoguer librement avec HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT → NTP&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;External&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Domaines spécifiques&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils de contacter des serveurs NTP pour l’heure&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;TV → Multimedia Server&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Télévisions&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Servers&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;NAS&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à mes télévisions d’accéder aux services du NAS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Les appareils de la zone &lt;code&gt;Devices&lt;/code&gt; doivent supporter le moins de friction possible malgré une zone très restrictive. En effet, on ne souhaiterait pas que quelqu’un râle car il n’arrive pas à utiliser le AirPlay alors que c’est censé marcher, et accuser à raison mes &amp;#34;bidouilles&amp;#34; qui sont inutiles selon eux. Aussi, de la même manière, on expose petit à petit des droits sélectionnés avec soin.&lt;/p&gt;
&lt;/div&gt;
&lt;table class="tableblock frame-all grid-all stretch"&gt;
&lt;colgroup&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.6666%;"/&gt;
&lt;col style="width: 16.667%;"/&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Nom&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Zone Src&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Src&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Zone Dest&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Dest&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices → HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Servers&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils de contacter les services de HomeAssistant&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices → Printer&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Imprimantes&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils d’imprimer/scanner&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices → HomeLab HTTP(S)&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Servers&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HomeLab&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils d’accéder aux services Web de mon HomeLab&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices → AirPlay&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;AirPlay&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Permet à tous les appareils d’accéder aux services AirPlay&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices → IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IoT&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Activé à l’occasion de maintenance&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices → Server&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Servers&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Activé à l’occasion de maintenance&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices → VM&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Nover Devices&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Virtual Machines&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;*&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Activé à l’occasion de maintenance&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ce réseau comprend quelques subtilités que j’ai passées sous silence pour ne pas rendre plus verbeux un article déjà long. De plus, souvent ces &amp;#34;subtilités&amp;#34; sont dues à une mauvaise abstraction et pourraient être résolues par un meilleur regroupement des appareils ou des règles plus générales.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je trouve ma configuration plutôt robuste, même si j’y retourne occasionnellement pour peaufiner certaines choses. Par exemple, j’ai eu à utiliser le logiciel AudioRelay entre une VM et mon ordinateur, qui se trouvent sur 2 VLAN différents. Cela a donné lieu à des configurations spécifiques, mais qui n’ont pas grand intérêt à détailler ici.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Certification locale</title><link>https://nicolasguilloux.eu/articles/local-certification/</link><pubDate>Thu, 21 Jul 2022 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/local-certification/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Certification locale" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;La certification locale est très utile majoritairement pour du développement local.
Il s’agit de fournir un certificat pour chaque domaine hébergé sur la machine, et que la fameuse page vous disant que le site est dangereux disparaisse.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_comment_fonctionne_un_certificat"&gt;Comment fonctionne un certificat&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Tout d’abord, un certificat sert à garantir l’authenticité d’un site par l’intermédiaire d’une autorité de confiance abrégée CA pour Certification Authority.
Je vais faire un exemple.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="certification_workflow.png" alt="certification workflow"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je souhaite certifier que le site &lt;code&gt;blog.nicolasguilloux.eu&lt;/code&gt; est à moi auprès d’un CA (par exemple &lt;a href="https://letsencrypt.org/fr/" target="_blank" rel="noopener"&gt;Let’s Encrypt&lt;/a&gt;). Il va alors se passer plusieurs choses successivement :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Je crée un couple de clé privée et clé publique.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Je demande au CA de me donner un challenge pour qu’il vérifie que je contrôle bien l’adresse en question&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Généralement, c’est un texte que l’on doit fournir à une URL précise (par exemple mettre le texte &lt;code&gt;ed98&lt;/code&gt; dans l’URL &lt;a href="https://blog.nicolasguilloux.eu/8303" class="bare"&gt;https://blog.nicolasguilloux.eu/8303&lt;/a&gt;) et de le signer avec ma clé privée.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Le CA vérifie alors que le challenge est OK en déchiffrant le contenu de ladite page avec la clé publique qu’on lui fournit.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Le CA enregistre alors cette clé publique et la fournit à qui veut vérifier la certification du site &lt;code&gt;blog.nicolasguilloux.eu&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ainsi, une personne lambda qui accède au site demande la clé publique au CA et vérifie le certificat fourni par le site avec chaque requête HTTPS avec celle-ci pour vérifier que je suis bien le propriétaire du site.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour plus d’information, vous pouvez consulter la &lt;a href="https://letsencrypt.org/fr/how-it-works/" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt; de Let’s Encrypt. L’image précédente est d’ailleurs tirée de cette page.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_notre_certification_custom"&gt;Notre certification custom&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Quand on demande une page https sans fournir de certificat, notre navigateur nous met en garde que ce n’est pas sécurisé, car il ne peut pas vérifier la source des informations données.
On va donc y remédier en créant un certificat par nous même, et en disant au système que l’autorité de confiance que nous avons créée est justement de confiance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On remarque qu’on ne s’occupera pas de la partie challenge, qui est uniquement là pour que le CA nous croit notre légitimité. Ici, on est légitime, on détient le système. Et le CA, c’est nous, on fait ce qu’on veut !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va créer une dérivation qui va générer les certificats grâce à la liste des domaines qu’on lui aura fournis ainsi que l’éventuelle autorité de certification qu’on lui aura donné.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;{ stdenv
, mkcert
, domains ? [ &amp;#34;local&amp;#34; &amp;#34;*.local&amp;#34; ]
, authority ? null
}:

let
 domainsToString = builtins.concatStringsSep &amp;#34; &amp;#34; (
 builtins.map (domain: &amp;#34;\&amp;#34;${domain}\&amp;#34;&amp;#34;) domains
 );
in
stdenv.mkDerivation rec {
 name = &amp;#34;local-certificates&amp;#34;;
 dontUnpack = true;

 installPhase = &amp;#39;&amp;#39;
 # Create the directories
 mkdir -p $out/ssl/authority;
 &amp;#39;&amp;#39; +
 if authority != null then
 &amp;#34;cp ${authority} $out/ssl/authority/rootCA.pem&amp;#34;
 else
 &amp;#34;&amp;#34;
 + &amp;#39;&amp;#39;
 # Generate the certificates
 CAROOT=&amp;#34;$out/ssl/authority&amp;#34; \
 ${mkcert}/bin/mkcert \
 -cert-file $out/ssl/local-cert.pem \
 -key-file $out/ssl/local-key.pem \
 ${domainsToString}
 &amp;#39;&amp;#39;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_lintégration_dans_le_système"&gt;L’intégration dans le système&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Regardons maintenant son intégration dans la configuration générale de NixOS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;{ config, lib, pkgs, ... }:

let
 localCerts = pkgs.callPackage ./local-certs.nix {
 domains = config.networking.hosts.&amp;#34;127.0.0.1&amp;#34;;
 # authority = ./rootCA.pem;
 };
in
{
 # Add certificates systemwide
 security.pki.certificateFiles = [
 (localCerts + &amp;#34;/ssl/authority/rootCA.pem&amp;#34;)
 ];

 # Add local certificates
 services.traefik.dynamicConfigOptions.tls = {
 certificates = [
 {
 certFile = &amp;#34;${localCerts}/ssl/local-cert.pem&amp;#34;;
 keyFile = &amp;#34;${localCerts}/ssl/local-key.pem&amp;#34;;
 }
 ];

 stores.default.defaultCertificate = {
 certFile = &amp;#34;${localCerts}/ssl/local-cert.pem&amp;#34;;
 keyFile = &amp;#34;${localCerts}/ssl/local-key.pem&amp;#34;;
 };
 };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On peut déjà constater que je build la dérivation précédemment mentionnée afin de pouvoir l’exploiter ensuite. Comme domaine, je donne tous ceux qui renvoient vers mon localhost. Je brasse large, mais c’est plus simple ainsi.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On remarque aussi que j’ai commenté le &lt;code&gt;authority&lt;/code&gt;. Si vous avez déjà créé l’autorité, vous pouvez l’utiliser sinon une sera créée pour vous. Cependant, cela peut poser problème si vous ne redémarrez pas entièrement votre système. En effet, si par exemple vous lancez Chrome, celui-ci récupèrera les autorités de votre système lors du démarrage. Ainsi, si les certificats locaux sont reconstruits, l’autorité aussi et Chrome n’aura pas la nouvelle autorité tout juste créée, du moins jusqu’à son prochain redémarrage.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On remarque donc qu’on ajoute le &lt;code&gt;rootCA.pem&lt;/code&gt; dans les autorités du système. Ainsi, le système croira tous les certificats émis par cette autorité, c’est-à-dire la nôtre.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;En prime, j’ai ajouté une configuration pour dire à Traefik d’associer le certificat généré par défaut. C’est un exemple et certaines personnes pourraient vouloir l’implémenter autrement.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_et_voilà"&gt;Et voilà !&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Vous avez dorénavant une certification locale qui se régénère dès que vous ajoutez un site dans vos hosts.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Reverse Proxy sur NixOS</title><link>https://nicolasguilloux.eu/articles/reverse-proxy-nixos/</link><pubDate>Fri, 01 Jul 2022 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/reverse-proxy-nixos/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Reverse Proxy sur NixOS" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai jonglé entre 3 proxies récemment afin de pouvoir facilement rediriger des requêtes vers les services appropriés, que ce soit en utilisant Docker ou en utilisant des services exposant des ports.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_lets_get_started"&gt;Let’s get started&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai expérimenté les proxies suivants dans l’ordre chronologique. Je vais passer en revue pourquoi je les ai utilisés, et pourquoi je les ai aussi abandonnés.&lt;br/&gt;
Il n’y en a pas nécessairement de meilleurs que d’autres, c’est juste que chacun trouve chaussure à son pied !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’avais aussi utilisé une configuration qui permettait de facilement jongler entre les différents services en adaptant le module sans pour autant rajouter de configuration. C’est d’ailleurs l’un des gros avantages de NixOS : pouvoir dissocier la configuration de l’implémentation. Vous pouvez voir le code &lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/tree/master/modules/reverse-proxies" target="_blank" rel="noopener"&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour des raisons de facilité, on va utiliser l’exemple d’un site web qui serait à l’adresse &lt;code&gt;blog.nicolasguilloux.eu&lt;/code&gt; et qui serait disponible en local sur le port 8080. Bien entendu, on souhaite que le site soit en &lt;code&gt;https&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_nginx"&gt;Nginx&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;C’est le premier proxy que j’ai utilisé, car c’est le serveur web que j’utilisais et qui permettait de facilement mettre en place cette fonctionnalité. C’est aussi le serveur web majoritairement utilisé.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="nginx.png" alt="nginx"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;La première chose à faire est de configurer le Acme challenge ainsi que 4 optimisations recommandées pour Nginx. Le premier servira bien entendu à générer automatiquement le certificat HTTPS pour notre site.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;# ACME Challenge
security.acme.acceptTerms = true;
security.acme.defaults.email = &amp;#34;nicolas.guilloux@proton.me&amp;#34;;

# Use recommended settings
services.nginx.recommendedGzipSettings = lib.mkDefault true;
services.nginx.recommendedOptimisation = lib.mkDefault true;
services.nginx.recommendedProxySettings = lib.mkDefault true;
services.nginx.recommendedTlsSettings = lib.mkDefault true;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ensuite, il nous faut dire à Nginx de rediriger le traffic entrant de &lt;code&gt;blog.nicolasguilloux.eu&lt;/code&gt; vers le port 8080. Pour ce faire, nous allons déclarer une virtual host, lui donner quelques configurations relatives au SSL et au proxy, mais surtout lui dire de rediriger tout le traffic vers la bonne adresse. La configuration parle d’elle-même :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;services.nginx.virtualHosts.&amp;#34;blog.nicolasguilloux.eu&amp;#34; = {
 forceSSL = true;
 enableACME = true;
 extraConfig = &amp;#34;proxy_buffering off&amp;#34;;

 locations.&amp;#34;/&amp;#34; = {
 proxyPass = &amp;#34;http://127.0.0.1:8080&amp;#34;;
 proxyWebsockets = true;
 extraConfig =
 # required when the target is also TLS server with multiple hosts
 &amp;#34;proxy_ssl_server_name on;&amp;#34; +
 # required when the server wants to use HTTP Authentication
 &amp;#34;proxy_pass_header Authorization;&amp;#34;;
 };
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Nginx était bien mais nécessitait que le service en question expose un port pour être accessible. Comme je travaille beaucoup avec des images Docker, l’utiliser était devenu de plus en plus fastidieux car je devais réfléchir à quel port j’exposais.
Si par exemple j’avais deux sites exposés sur le port 80, je devais choisir de les exposer, l’un sur le port 8080 et l’autre sur le port 8081.&lt;br/&gt;
Bref, rapidement j’ai trouvé que l’attribution arbitraire d’un port pour éviter les conflits n’était pas pérenne dans le temps.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_caddy_proxy"&gt;Caddy Proxy&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Celui-ci est légèrement différent. À la base, &lt;a href="" target="_blank" rel="noopener"&gt;Caddy&lt;/a&gt; est un serveur Web qui fournit beaucoup de fonctionnalité et se veut facile d’accès. Pour notre utilisation, c’est une &lt;a href="https://github.com/lucaslorentz/caddy-docker-proxy" target="_blank" rel="noopener"&gt;image docker&lt;/a&gt; qui a pour principe de se servir des labels associés à un container Docker pour le router.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="caddy.png" alt="caddy"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Regardons comment &amp;#34;installer&amp;#34; le service the nix way :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On va devoir déclarer un container qui utilisera le port 80 et 443 pour respectivement le http et https.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On doit donner un petit nom au network Docker. Tout container appartenant à ce network sera analysé par caddy-proxy pour trouver éventuellement des labels le concernant.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On l’ajoute bien entendu à ce dit network.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On lui donne accès à notre socket Docker, pour qu’il puisse analyser les différents containers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On lui donne un espace pour stocker ses données.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une dernière configuration doit être ajoutée pour créer le network Docker avant de lancer le container pour éviter une erreur.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Voici donc la configuration correspondante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;let
 dockerNetwork = &amp;#34;caddy-proxy&amp;#34;;
in
{
 virtualisation.oci-containers.containers.caddy-proxy = {
 autoStart = true;
 image = &amp;#34;lucaslorentz/caddy-docker-proxy:ci-alpine&amp;#34;;
 ports = [ &amp;#34;80:80&amp;#34; &amp;#34;443:443&amp;#34; ];
 environment = { CADDY_INGRESS_NETWORKS = &amp;#34;${dockerNetwork} };
 extraOptions = [ &amp;#34;--network=${dockerNetwork} ];
 volumes = [
 &amp;#34;/var/run/docker.sock:/var/run/docker.sock&amp;#34;
 &amp;#34;/var/lib/caddy-proxy:/data&amp;#34;
 ];
 };

 systemd.services.docker-caddy-proxy.preStart = lib.mkAfter &amp;#39;&amp;#39;
 ${pkgs.docker}/bin/docker network create -d bridge ${dockerNetwork} || true
 &amp;#39;&amp;#39;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Et voilà, ça fonctionne. On pourra noter une amélioration à apporter : le support de Podman. Pour l’instant, c’est hardcodé pour Docker à cause de preStart ainsi que du socket.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Si on regarde maintenant pour instancier un service qui passerait par ce proxy, on se retrouverait avec une configuration de ce genre :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;let
 dockerNetwork = &amp;#34;caddy-proxy&amp;#34;;
in
{
 virtualisation.oci-containers.containers.whoami = {
 autoStart = true;
 image = &amp;#34;jwilder/whoami&amp;#34;;
 extraOptions = [
 &amp;#34;--network=${dockerNetwork}&amp;#34;
 &amp;#34;--label=caddy=whoami.example.com&amp;#34;
 &amp;#34;--label=caddy.reverse_proxy={{upstreams 8000}}&amp;#34;
 ];
 };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai abandonné cette implémentation particulière d’un proxy car étant très pratique pour du développement local avec Docker, elle ne permet pas de facilement placer un service natif derrière celui-ci. De plus, je n’ai pas exploré la possibilité du SSL car je n’envisageais pas cette solution sur mon serveur.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_traefik"&gt;Traefik&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ce qu’il me fallait, c’est le meilleur des deux mondes : placer des services natifs et des services dockerisés derrière un proxy. Si en plus je pouvais avoir une interface graphique pour debugger, ça serait parfait.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Traefik m’a alors été conseillé par un ami, et rempli totalement son rôle. On peut lui dire manuellement de forward tel host sur tel adresse et port, tout comme on peut bénéficier d’une configuration avec des labels via le Docker provider.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="traefik.png" alt="traefik"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Voyons quelques prérequis qui expliquent la configuration :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Traefik doit avoir accès à Docker&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On veut son Dashboard pour pouvoir facilement débugger&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On doit configurer au moins deux points d’entrées : un pour le http et l’autre pour le https. Le http dans cet exemple redirigera vers le https.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On doit configurer la génération des certificats&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On souhaite par défaut que le dashboard soit accessible via &lt;code&gt;&lt;a href="https://traefik.local" class="bare"&gt;https://traefik.local&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Avec tout ça en tête, on obtient alors la configuration par défaut suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;{ config, lib, pkgs, ... }:

let
 localCertificationDirectory = config.security.localCertification.directory;
in
{
 # Enable Traefik
 services.traefik.enable = true;

 # Let Traefik interact with Docker
 services.traefik.group = &amp;#34;docker&amp;#34;;

 services.traefik.staticConfigOptions = {
 api.dashboard = true;
 api.insecure = false;

 # Enable logs
 log.filePath = &amp;#34;/var/log/traefik/traefik.log&amp;#34;;
 accessLog.filePath = &amp;#34;/var/log/traefik/accessLog.log&amp;#34;;

 # Enable Docker provider
 providers.docker = {
 endpoint = &amp;#34;unix:///run/docker.sock&amp;#34;;
 watch = true;
 exposedByDefault = false;
 };

 # Configure entrypoints, i.e the ports
 entryPoints = {
 websecure.address = &amp;#34;:443&amp;#34;;
 web = {
 address = &amp;#34;:80&amp;#34;;
 http.redirections.entryPoint = {
 to = &amp;#34;websecure&amp;#34;;
 scheme = &amp;#34;https&amp;#34;;
 };
 };
 };

 # Configure certification
 certificatesResolvers.acme-challenge.acme = {
 email = &amp;#34;nicolas.guilloux@proton.me&amp;#34;;
 storage = &amp;#34;/var/lib/traefik/acme.json&amp;#34;;
 httpChallenge.entryPoint = &amp;#34;web&amp;#34;;
 };
 };

 # Dashboard
 services.traefik.dynamicConfigOptions.http.routers.dashboard = {
 rule = lib.mkDefault &amp;#34;Host(`traefik.local`)&amp;#34;;
 service = &amp;#34;api@internal&amp;#34;;
 entryPoints = [ &amp;#34;websecure&amp;#34; ];
 tls = lib.mkDefault true;
 # Add certification
 # tls.certResolver = &amp;#34;acme-challenge&amp;#34;;
 };

 # Add Dashboard to hosts
 networking.hosts.&amp;#34;127.0.0.1&amp;#34; =
 if config.services.traefik.dynamicConfigOptions.http.routers.dashboard.rule == &amp;#34;Host(`traefik.local`)&amp;#34; then
 [ &amp;#34;traefik.local&amp;#34; ]
 else
 [ ];
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;À partir de là, on a un Traefik qui dispose d’un dashboard et qui surveille Docker, quel que soit le network.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;div class="title"&gt;Note&lt;/div&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Si jamais vous voulez manipuler des headers, il faut passer par des middlewares.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Regardons déjà la déclaration d’un container pour qu’il soit câblé sur Traefik. L’attribution des labels est plutôt évidentes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;virtualisation.oci-containers.containers.whoami = {
 autoStart = true;
 image = &amp;#34;jwilder/whoami&amp;#34;;
 extraOptions = [
 &amp;#34;--label=traefik.enable=true&amp;#34;
 &amp;#34;--label=traefik.http.routers.whoami.entrypoints=websecure&amp;#34;
 &amp;#34;--label=traefik.http.routers.whoami.rule=Host(`whoami.example.com`)&amp;#34;
 &amp;#34;--label=traefik.http.routers.whoami.tls=true&amp;#34;
 &amp;#34;--label=traefik.http.services.whoami.loadbalancer.server.port=8000&amp;#34;
 # Add certification
 # &amp;#34;--label=traefik.http.routers.whoami.tls.certresolver=acme-challenge&amp;#34;
 ];
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour ajouter notre fameux blog, c’est-à-dire un service natif, on peut le faire de la manière suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nix" data-lang="nix"&gt;services.traefik.dynamicConfigOptions.http.services.&amp;#34;blog.nicolasguilloux.eu&amp;#34; = {
 loadBalancer.servers = [
 { url = &amp;#34;http://127.0.0.1:8080&amp;#34;; }
 ];
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Traefik est pour moi la solution qui me convient le mieux, car elle réunit le meilleur des deux précédents proxy, tout en proposant davantage. Le dashboard est très pratique pour surveiller le routing, et je pourrais explorer d’autres fonctionnalités à l’avenir comme le routing TCP/UDP.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_aller_plus_loin"&gt;Aller plus loin&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il y a plusieurs fonctionnalités que j’ai ou vais explorer avec Traefik :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="../local-certification/"&gt;Faire de la certification en local&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Faire du routing TCP/UDP&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implémenter du monitoring&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implémenter + de sécurité (Crowdsec ?)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Le Bridge Signal pour Matrix</title><link>https://nicolasguilloux.eu/articles/mautrix-signal/</link><pubDate>Thu, 08 Apr 2021 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/mautrix-signal/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Le Bridge Signal pour Matrix" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Matrix est un protocole de messagerie instantanée. La suite de ce ticket considère que vous connaissez les bases et notamment le glossaire. Je vous conseille fortement d’aller lire le tutoriel précédent :
&lt;a href="../matrix"&gt;Matrix sur NixOS&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_signal_messenger"&gt;Signal Messenger&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/signal.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-Mautrix%20Signal-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le bridge Signal supporte les conversations de groupe et les messages directs. Toutefois, toute conversation chiffrée ne sera pas supportée.&lt;br/&gt;
La petite particularité sur ce bridge est que Signal ne dispose pas d’une API. Ainsi, il va falloir utiliser une image Docker qui va simuler un accès Web à Signal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Voici la configuration que je préconise :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;{ config, lib, ... }:

let
 bridgeFolder = &amp;#34;/var/lib/mautrix-signal&amp;#34;;

 toListIfExists = path:
 if (lib.pathExists path) then
 [ path ]
 else
 [];
in {
 # Signal daemon
 virtualisation.oci-containers.containers.signald = {
 image = &amp;#34;docker.io/finn/signald&amp;#34;;
 volumes = [ &amp;#34;${bridgeFolder}/signald:/signald&amp;#34; ];
 extraOptions = [ &amp;#34;--network=host&amp;#34; ];
 };

 # Signal bridge
 virtualisation.oci-containers.containers.mautrix-signal = {
 image = &amp;#34;dock.mau.dev/tulir/mautrix-signal&amp;#34;;
 extraOptions = [ &amp;#34;--network=host&amp;#34; ];
 dependsOn = [ &amp;#34;signald&amp;#34; ];
 volumes = [
 &amp;#34;${bridgeFolder}/data:/data&amp;#34;
 &amp;#34;${bridgeFolder}/signald:/signald&amp;#34;
 ];
 };

 # Add configuration to Matrix server
 services.matrix-synapse.app_service_config_files = toListIfExists &amp;#34;${bridgeFolder}/data/registration.yaml&amp;#34;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Si on résume, toutes les données sont stockées dans &lt;code&gt;/var/lib/mautrix-signal&lt;/code&gt;. On ajoute les images Docker qui permettent de lancer le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;L’image &lt;code&gt;signald&lt;/code&gt; est le daemon pour pouvoir simuler une interface Web auprès de notre application Signal. C’est nécessaire pour pouvoir récupérer les messages en toute sécurité vu que Signal ne dispose pas d’API.&lt;br/&gt;
C’est aussi pour cela qu’on doit partager le volume où sont stockées toutes les informations (comme les avatars) entre le daemon et le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va dès maintenant configurer ce dernier en éditant &lt;strong&gt;en tant que root&lt;/strong&gt; le fichier &lt;code&gt;/var/lib/mautrix-signal/data/config.yaml&lt;/code&gt;…​ Enfin faite votre &lt;code&gt;nixos-rebuild switch&lt;/code&gt; pour lancer le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va changer différentes clés dans le fichier, je vais lister ce les clés qui ont changé :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;homeserver:
 address: http://localhost:8008
 domain: server_name
 verify_ssl: false

signal:
 socket_path: /signald/signald.sock
 outgoing_attachment_dir: /signald/attachments
 avatar_dir: /signald/avatars
 data_dir: /signald/data

bridge:
 permissions:
 &amp;#34;*&amp;#34;: user
 &amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.address&lt;/code&gt; : Votre serveur Matrix, pas besoin de passer par internet, il est disponible en local&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.domain&lt;/code&gt; : C’est le &lt;code&gt;server_name&lt;/code&gt;, vous devriez maintenant savoir ce que c’est :)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.verify_ssl&lt;/code&gt; : Comme on est dans une boucle locale, pas besoin de vérifier le SSL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;signal.socket-path&lt;/code&gt; : Socket pour dialoguer avec le daemon&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;signal.outgoing_attachment_dir&lt;/code&gt; : Répertoire du daemon où sont mis les pièces jointes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;signal.avatar_dir&lt;/code&gt; : Répertoire du daemon où sont mis les avatars&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;signal.data_dir&lt;/code&gt; : Répertoire du daemon où sont mis les autres données utiles aux bridges&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bridge.permissions&lt;/code&gt; : Ce sont les permissions. Pour ma part, j’ai mis &lt;code&gt;&amp;#34;*&amp;#34;: user&lt;/code&gt; pour que tous les utilisateurs puissent utiliser le bridge, et enfin &lt;code&gt;&amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt; pour que votre utilisateur puisse l’administrer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois ça fait, pensez à redémarrer votre image docker &lt;code&gt;docker restart mautrix-signal&lt;/code&gt; et faites ensuite un petit &lt;code&gt;nixos-rebuild switch&lt;/code&gt;. Normalement, &lt;code&gt;matrix-synapse&lt;/code&gt; se redémarrera car le fichier &lt;code&gt;registration.yaml&lt;/code&gt; existera.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Vous pouvez maintenant constater que vous pouvez parler au bot dans votre client Matrix en ouvrant une conversation avec &lt;code&gt;@signalbot:server_name&lt;/code&gt;.&lt;br/&gt;
Celui-ci devrait accepter votre invitation. Vous pouvez alors lui demander de l’aide comme il le propose.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;A partir d’ici vous avez plusieurs choix, car vous pouvez :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Créer un compte de zéro en utilisant la commande &lt;code&gt;register +33xxxxxxxxx&lt;/code&gt;. Si vous n’avez pas signal sur votre téléphone, cela permettra de tout recevoir sur Matrix directement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lier votre compte déjà existant, relié à votre téléphone, et forward tous les messages à Matrix en tapant &lt;code&gt;link&lt;/code&gt; et en scannant le QR Code.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois connecté, attendez un peu et vous allez recevoir plein d’invitations :) Bien joué, tout devrait fonctionner !&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Le Bridge Telegram pour Matrix</title><link>https://nicolasguilloux.eu/articles/mautrix-telegram/</link><pubDate>Mon, 05 Apr 2021 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/mautrix-telegram/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Le Bridge Telegram pour Matrix" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Matrix est un protocole de messagerie instantanée. La suite de ce ticket considère que vous connaissez les bases et notamment le glossaire. Je vous conseille fortement d’aller lire le tutoriel précédent :
&lt;a href="../matrix"&gt;Matrix sur NixOS&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_telegram_messenger"&gt;Telegram Messenger&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/telegram.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-Mautrix%20Telegram-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le bridge de Telegram supporte quasiment toutes les fonctionnalités. La configuration est quasiment la même que pour
&lt;a href="../mautrix-facebook"&gt;Mautrix Facebook&lt;/a&gt;
hormis un léger changement au niveau de la configuration d’une API.&lt;br/&gt;
Je n’ai volontairement pas suivi la configuration proposée par NixOS car je n’ai jamais réussi à la faire fonctionner, et je souhaite avoir une installation cohérente. Comme NixOS ne propose pas de module pour Mautrix Facebook, Mautrix Telegram et Mautrix Signal, je préfère les configurer de la même manière.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Voici la configuration que je préconise :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;{ config, lib, ... }:

let
 bridgeFolder = &amp;#34;/var/lib/mautrix-telegram&amp;#34;;

 toListIfExists = path:
 if (lib.pathExists path) then
 [ path ]
 else
 [];
in {
 # Telegram bridge
 virtualisation.oci-containers.containers.mautrix-telegram = {
 image = &amp;#34;dock.mau.dev/tulir/mautrix-telegram&amp;#34;;
 extraOptions = [ &amp;#34;--network=host&amp;#34; ];
 volumes = [ &amp;#34;${bridgeFolder}/data:/data&amp;#34; ];
 };

 # Add configuration to Matrix server
 services.matrix-synapse.app_service_config_files = toListIfExists &amp;#34;${bridgeFolder}/data/registration.yaml&amp;#34;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Si on résume, toutes les données sont stockées dans &lt;code&gt;/var/lib/mautrix-telegram&lt;/code&gt;. On ajoute l’image docker qui permet de lancer le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va dès maintenant le configurer en éditant &lt;strong&gt;en tant que root&lt;/strong&gt; le fichier &lt;code&gt;/var/lib/mautrix-telegram/data/config.yaml&lt;/code&gt;…​ Enfin faite votre &lt;code&gt;nixos-rebuild switch&lt;/code&gt; pour lancer le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Dans un premier temps, il faut faire une application sur le site de Telegram pour récupérer un ID et un hash qui serviront au bridge pour interagir avec l’API. Pour ce faire, allez sur cette &lt;a href="https://core.telegram.org/api/obtaining_api_id#obtaining" target="_blank" rel="noopener"&gt;page d’aide de Telegram&lt;/a&gt; et suivez les instructions pour récupérer le &lt;code&gt;api_id&lt;/code&gt; et le &lt;code&gt;api_hash&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va changer différentes clés dans le fichier, je vais lister ce les clés qui ont changé :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;homeserver:
 address: http://localhost:8008
 domain: server_name
 verify_ssl: false

telegram:
 api_id: #ApiId#
 api_hash: #ApiHash#

bridge:
 permissions:
 &amp;#34;*&amp;#34;: user
 &amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.address&lt;/code&gt; : Votre serveur Matrix, pas besoin de passer par internet, il est disponible en local&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.domain&lt;/code&gt; : C’est le &lt;code&gt;server_name&lt;/code&gt;, vous devriez maintenant savoir ce que c’est :)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.verify_ssl&lt;/code&gt; : Comme on est dans une boucle locale, pas besoin de vérifier le SSL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;telegram.api_id&lt;/code&gt; : ID fourni par Telegram sur le site&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;telegram.api_hash&lt;/code&gt; : Hash fourni par Telegram sur le site&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bridge.permissions&lt;/code&gt; : Ce sont les permissions. Pour ma part, j’ai mis &lt;code&gt;&amp;#34;*&amp;#34;: user&lt;/code&gt; pour que tous les utilisateurs puissent utiliser le bridge, et enfin &lt;code&gt;&amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt; pour que votre utilisateur puisse l’administrer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois ça fait, pensez à redémarrer votre image docker &lt;code&gt;docker restart mautrix-telegram&lt;/code&gt; et faites ensuite un petit &lt;code&gt;nixos-rebuild switch&lt;/code&gt;. Normalement, &lt;code&gt;matrix-synapse&lt;/code&gt; se redémarrera car le fichier &lt;code&gt;registration.yaml&lt;/code&gt; existera.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Vous pouvez maintenant constater que vous pouvez parler au bot dans votre client Matrix en ouvrant une conversation avec &lt;code&gt;@telegrambot:server_name&lt;/code&gt;.&lt;br/&gt;
Celui-ci devrait accepter votre invitation. Vous pouvez alors lui demander de l’aide comme il le propose. Pour lier votre compte, faites &lt;code&gt;!tg login&lt;/code&gt; et suivez les instructions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois connecté, attendez un peu et vous allez recevoir plein d’invitations :) Bien joué, tout devrait fonctionner !&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Le Bridge Facebook pour Matrix</title><link>https://nicolasguilloux.eu/articles/mautrix-facebook/</link><pubDate>Mon, 29 Mar 2021 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/mautrix-facebook/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Le Bridge Facebook pour Matrix" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Matrix est un protocole de messagerie instantanée. La suite de ce ticket considère que vous connaissez les bases et notamment le glossaire. Je vous conseille fortement d’aller lire le tutoriel précédent :
&lt;a href="../matrix"&gt;Matrix sur NixOS&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_facebook_messenger"&gt;Facebook Messenger&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/facebook.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-Mautrix%20Facebook-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Bon, qu’on se le dise, j’aimerai bien partir de Facebook mais beaucoup de personnes ne veulent pas par simplicité. Même si ça m’embête pour des raisons évidentes, je dois rester dessus car j’ai vraiment des personnes que j’aime beaucoup qui refusent de passer sur d’autres plateformes.&lt;br/&gt;
C’est d’ailleurs un intérêt de ce bridge : je vais désinstaller toutes les applications Facebook, ma seule interaction sera via Matrix.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Dans un premier temps, on va préparer notre base de données afin d’y stocker les données utiles au bridge. Pour le moment, celui-ci ne supporte que PostgreSQL. Ca tombe bien, on a déjà une BDD disponible via le serveur Synapse. Aussi, on va pouvoir facilement créer un user et une base.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;sudo -u postgres psql
CREATE ROLE &amp;#34;mautrixfacebook&amp;#34; WITH LOGIN PASSWORD &amp;#39;VotreMotDePasseUnique&amp;#39;;
CREATE DATABASE &amp;#34;mautrixfacebook&amp;#34; WITH OWNER &amp;#34;mautrixfacebook&amp;#34; TEMPLATE template0 LC_COLLATE = &amp;#34;C&amp;#34; LC_CTYPE = &amp;#34;C&amp;#34;;
\q&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois fait, on va pouvoir préparer notre module qui va démarrer l’image docker du bridge. On va aussi câbler ce bridge à notre instance Matrix.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;{ config, lib, ... }:

let
 bridgeFolder = &amp;#34;/var/lib/mautrix-facebook&amp;#34;;

 toListIfExists = path:
 if (lib.pathExists path) then
 [ path ]
 else
 [];
in {
 # Facebook bridge
 virtualisation.oci-containers.containers.mautrix-facebook = {
 image = &amp;#34;dock.mau.dev/tulir/mautrix-facebook&amp;#34;;
 extraOptions = [ &amp;#34;--network=host&amp;#34; ];
 volumes = [ &amp;#34;${bridgeFolder}/data:/data&amp;#34; ];
 };

 # Add configuration to Matrix server
 services.matrix-synapse.app_service_config_files = toListIfExists &amp;#34;${bridgeFolder}/data/registration.yaml&amp;#34;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Si on résume, toutes les données sont stockées dans &lt;code&gt;/var/lib/mautrix-facebook&lt;/code&gt;. On ajoute l’image docker qui permet de lancer le bridge.&lt;br/&gt;
La partie où on relie notre bridge à notre serveur est commentée pour le moment car le fichier en question sera généré par le bridge, et donc n’existe pas avant d’avoir bien parametré le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va dès maintenant le configurer en éditant &lt;strong&gt;en tant que root&lt;/strong&gt; le fichier &lt;code&gt;/var/lib/mautrix-facebook/data/config.yaml&lt;/code&gt;…​ Enfin faite votre &lt;code&gt;nixos-rebuild switch&lt;/code&gt; pour lancer le bridge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va changer différentes clés dans le fichier, je vais lister les clés qui ont changé :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;homeserver:
 address: http://localhost:8008
 domain: server_name
 verify_ssl: false

appservice:
 database: postgres://mautrixfacebook:VotreMotDePasseUnique@127.0.0.1/mautrixfacebook

bridge:
 permissions:
 &amp;#34;*&amp;#34;: user
 &amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.address&lt;/code&gt; : Votre serveur Matrix, pas besoin de passer par internet, il est disponible en local&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.domain&lt;/code&gt; : C’est le &lt;code&gt;server_name&lt;/code&gt;, vous devriez maintenant savoir ce que c’est :)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;homeserver.verify_ssl&lt;/code&gt; : Comme on est dans une boucle locale, pas besoin de vérifier le SSL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;appservice.database&lt;/code&gt; : Lien vers *votre base de données. Pensez à changer le mot de passe pour celui que vous avez utilisé au dessus.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bridge.permissions&lt;/code&gt; : Ce sont les permissions. Pour ma part, j’ai mis &lt;code&gt;&amp;#34;*&amp;#34;: user&lt;/code&gt; pour que tous les utilisateurs puissent utiliser le bridge, et enfin &lt;code&gt;&amp;#34;@pseudo:server_name&amp;#34;: admin&lt;/code&gt; pour que votre utilisateur puisse l’administrer&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois ça fait, pensez à redémarrer votre image docker &lt;code&gt;docker restart mautrix-facebook&lt;/code&gt; et faites ensuite un petit &lt;code&gt;nixos-rebuild switch&lt;/code&gt;. Normalement, &lt;code&gt;matrix-synapse&lt;/code&gt; se redémarrera car le fichier &lt;code&gt;registration.yaml&lt;/code&gt; existera.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Vous pouvez maintenant constater que vous pouvez parler au bot dans votre client Matrix en ouvrant une conversation avec &lt;code&gt;@facebookbot:server_name&lt;/code&gt;.&lt;br/&gt;
Celui-ci devrait accepter votre invitation. Vous pouvez alors lui demander de l’aide comme il le propose. Pour lier votre compte, faites &lt;code&gt;login &amp;lt;email&amp;gt;&lt;/code&gt; avec l’email de votre compte Facebook bien entendu ! Suivez ce qu’il vous dit, il va vous demander votre mot de passe et potentiellement votre code de double authentification.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois connecté, attendez un peu et vous allez recevoir plein d’invitations :) Bien joué, tout devrait fonctionner !&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Matrix sur NixOS</title><link>https://nicolasguilloux.eu/articles/matrix/</link><pubDate>Fri, 26 Mar 2021 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/matrix/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Matrix sur NixOS" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Comme beaucoup de personnes, j’ai beaucoup de messageries qui ont su évoluer (ou pas) dans le temps. Et chacune de ces messageries apporte ses avantages et ses inconvénients, et la plupart des gens ne veulent pas toutes les avoir. Et j’en fais partie !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Aussi, j’ai toujours reluqué &lt;a href="https://matrix.org" target="_blank" rel="noopener"&gt;Matrix&lt;/a&gt; de loin. Les seules fois où j’avais abordé ce standard, j’ai été très déçu à cause de la lenteur de celui-ci et aussi le fait que ce soit extrêmement intimidant au niveau sécurité.&lt;/p&gt;
&lt;/div&gt;
&lt;div id="beeper" class="paragraph"&gt;
&lt;p&gt;&lt;span class="image center"&gt;&lt;img src="beeper.png" alt="beeper"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Finalement, j’ai décidé de me lancer en entendant parler de &lt;a href="https://www.beeper.com" target="_blank" rel="noopener"&gt;Beeper&lt;/a&gt; qui permettait de centraliser plein de protocoles au même endroit. J’ai été déçu de voir que c’était très payant pour une utilisation domestique. Et j’ai remarqué par mon don incroyable de lecture de la seule et unique page disponible que Beeper était une application basée sur Matrix et la notion de bridges. Donc, en théorie, on peut faire la même chose sans payer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_quest_ce_que_matrix"&gt;Qu’est-ce que Matrix&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Matrix est un standard OpenSource pour construire une messagerie sécurisée en temps réel et décentralisée. Beaucoup de buzz words, on va expliquer tout ça.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;C’est un &lt;strong&gt;standard&lt;/strong&gt;, ce qui veut dire que Matrix n’est pas un logiciel mais simplement une liste de fonctionnalités à implémenter afin de supporter le protocole. C’est un peu comme si on parlait d’un mixeur, qui est la fonctionnalité, ce qui ne l’empêche pas d’avoir un nom donné par la marque ou par les utilisateurs. Le mixeur de mes parents s’appelle Bob.&lt;br/&gt;
Une &lt;strong&gt;messagerie sécurisée en temps réel&lt;/strong&gt;, c’est assez simple à comprendre.&lt;br/&gt;
Pour le côté &lt;strong&gt;décentralisé&lt;/strong&gt;, ça veut dire que un seul et unique serveur n’est pas souverain du réseau. Ainsi, installer un serveur chez vous permettra d’avoir accès au service sur votre réseau. Matrix implémente aussi un système pour faire dialoguer les serveurs entre eux, comme ça votre serveur ne reste pas dans son coin et pourra dialoguer avec le monde extérieur.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On a parlé plus haut des bridges, et ça c’est une des fonctionnalités de Matrix. Le principe est qu’on peut ajouter un genre de plugin qui joue le rôle d’interface avec quelque chose d’autre. Ouais c’est un peu abstrait, mais concrètement un bridge peut se charger en temps réel de relayer les messages d’une autre messagerie par exemple.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_installation_du_serveur"&gt;Installation du serveur&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai rassemblé tous mes efforts pour que tout fonctionne dans un dossier de mon installation NixOS. Il peut varier dans le temps, j’actualiserais le tutoriel et les liens vers ma configuration en fonction des updates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_le_serveur_synapse"&gt;Le serveur Synapse&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/server.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-Synapse-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Tout commence d’abord par installer &lt;a href="https://matrix.org/docs/projects/server/synapse"&gt;Synapse&lt;/a&gt; qui est un serveur Matrix. Matrix étant un standard, Synapse est une implémentation de celui-ci. Si vous êtes déjà perdu, relisez le point précédent ;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, NixOS nous a bien facilité la tâche vu qu’une configuration est disponible, donc on peut aller très vite.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;services.matrix-synapse = {
 enable = true;
 server_name = &amp;#34;matrix.nicolasguilloux.eu&amp;#34;;
 registration_shared_secret = &amp;#34;UnSecretTemporaire&amp;#34;;
 # enable_registration = true;

 listeners = [
 {
 port = 8008;
 bind_address = &amp;#34;::1&amp;#34;;
 type = &amp;#34;http&amp;#34;;
 tls = false;
 x_forwarded = true;
 resources = [
 {
 names = [ &amp;#34;client&amp;#34; &amp;#34;federation&amp;#34; ];
 compress = false;
 }
 ];
 }
 ];
};

# For the registration of a user
services.matrix-synapse.registration_shared_secret = &amp;#34;UnSecretTemporaire&amp;#34;;
environment.systemPackages = [ pkgs.matrix-synapse ];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il faut s’assurer que l’option &lt;code&gt;server_name&lt;/code&gt; correspond bien à l’adresse finale du serveur. C’est important pour faire dialoguer le monde extérieur avec notre instance. Si jamais vous vous lancez dans l’installation et que cette adresse est fausse, il faudra tout recommencer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, on n’utilise qu’un seul port : le &lt;code&gt;8008&lt;/code&gt;. C’est celui conseillé dans la documentation. Vous remarquerez qu’il n’y a pas de SSL, c’est parce que mon serveur sera exposé à travers un Reverse Proxy géré par Nginx. On va voir ça après.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;L’option &lt;code&gt;registration_shared_secret&lt;/code&gt; est là uniquement pour enregistrer votre utilisateur administrateur. Il faudra bien penser à l’enlever, car elle permet de créer des utilisateurs un peu comme on veut en utilisant le dit mot de passe.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Et enfin, pas besoin d’importer le paquet de Synapse dans ceux de système hormis pour l’inscription d’un nouvel utilisateur via un terminal.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_la_base_de_données"&gt;La base de données&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/database.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-BDD-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il faudra aussi configurer une base de données PostgreSQL pour le serveur.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;# Manually configure PostgreSQL
# ref: https://www.foxypossibilities.com/2018/02/04/running-matrix-synapse-on-nixos/
services.postgresql.enable = true;
services.postgresql.initialScript = pkgs.writeText &amp;#34;synapse-init.sql&amp;#34; &amp;#39;&amp;#39;
 CREATE ROLE &amp;#34;matrix-synapse&amp;#34; WITH LOGIN PASSWORD &amp;#39;${config.secrets.matrix.database}&amp;#39;;
 CREATE DATABASE &amp;#34;matrix-synapse&amp;#34; WITH OWNER &amp;#34;matrix-synapse&amp;#34;
 TEMPLATE template0
 LC_COLLATE = &amp;#34;C&amp;#34;
 LC_CTYPE = &amp;#34;C&amp;#34;;
&amp;#39;&amp;#39;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, mon mot de passe est défini bien au chaud dans la config. Pensez à mettre votre mot de passe. Vous pouvez aussi faire cette étape à la mano en allant tater &lt;code&gt;sudo -u postgres psql&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_création_de_notre_admin"&gt;Création de notre admin&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Avant d’exposer sur Internet, on va déjà créer notre utilisateur admin puis désactiver la possibilité de s’enregistrer en utilisant les lignes de commandes. Comme ça, on ferme une porte !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, rappelez vous la &lt;code&gt;registration_shared_secret&lt;/code&gt; mis plus haut et simplement tapez la commande suivante&lt;/p&gt;
&lt;/div&gt;
&lt;div class="quoteblock"&gt;
&lt;blockquote&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;register_new_matrix_user --shared-secret &amp;#34;UnSecretTemporaire&amp;#34; &lt;a href="http://localhost:8008" class="bare"&gt;http://localhost:8008&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On suit donc tout ce qu’il nous dit comme il faut en prenant soin de mettre votre utilisateur Admin.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_le_reverse_proxy"&gt;Le Reverse Proxy&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/NicolasGuilloux/nixos-configuration/-/blob/master/server/matrix/nginx.nix" target="_blank" rel="noopener"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/Gitlab-Nginx-orange" alt="Gitlab"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va maintenant configurer notre Reverse Proxy pour qu’il puisse être accessible du monde extérieur. C’est important aussi pour pouvoir dialoguer avec les autres serveurs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;let
 listenPort = port: ssl: {
 addr = &amp;#34;0.0.0.0&amp;#34;;
 port = port;
 ssl = ssl;
 };
in
{
 # Open port
 networking.firewall.allowedTCPPorts = [ 8448 ];

 # Reverse proxy
 services.nginx.virtualHosts.&amp;#34;matrix.nicolasguilloux.eu&amp;#34; = {
 enableACME = true;
 forceSSL = true;

 listen = [
 (listenPort 80 false)
 (listenPort 443 true)
 (listenPort 8448 true)
 ];

 locations.&amp;#34;/_matrix&amp;#34; = {
 proxyPass = &amp;#34;http://[::1]:8008&amp;#34;;
 };
 };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, on voit que nous redirigeons tout vers notre serveur Synapse. On peut aussi voir qu’on utilise le port 8448. Il est important car c’est ce port qui est utilisé par la fédération des serveurs Matrix. Ainsi, un serveur lambda ira questionner notre serveur via ce port uniquement.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois tout installé, vous pouvez d’ailleurs &lt;a href="https://federationtester.matrix.org" target="_blank" rel="noopener"&gt;tester votre serveur&lt;/a&gt; pour voir s’il est bien accessible par la fédération.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Si vous avez tout bien fait, normalement vous devez pouvoir vous connecter sur &lt;a href="https://app.element.io/#/login"&gt;Element.io&lt;/a&gt;, modifier le serveur d’accueil (le fameux &lt;code&gt;server_name&lt;/code&gt;) et vous connecter.&lt;br/&gt;
Vous remarquerez alors que votre pseudo est &lt;code&gt;pseudo:server_name&lt;/code&gt;. Par exemple, pour ma part, c’est &lt;code&gt;nover:matrix.nicolasguilloux.eu&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_les_bridges"&gt;Les Bridges&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois votre serveur fonctionnel, vous pouvez jouir de toutes les fonctionnalités de Matrix de base. Vous pouvez donc rejoindre des salons et discuter avec des personnes mêmes si elles ne sont pas sur votre serveur grâce à la magie de la fédération.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va maintenant pouvoir ajouter des bridges qui vont être les interfaces entre un autre protocole et celui de Matrix. En plus simple : ça va permettre d’envoyer des messages en utilisant Matrix vers des destinataires comme Signal ou encore Messenger.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ici, je ne vais passer en revue que les bridges que j’ai implémenté sur mon serveur. On notera que la plupart ont été conçu par la même personne et donc ont le préfix &lt;code&gt;mautrix&lt;/code&gt;. On peut donc constater qu’ils se configurent quasiment de la même manière.&lt;br/&gt;
Je vais aussi essayer de trier l’ordre des bridges ci-dessous en fonction de leur difficulté à installer. Ça permettra de monter progressivement en difficulté.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="../mautrix-facebook"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/mautrix-facebook-blue" alt="mautrix facebook blue"/&gt;&lt;/span&gt;&lt;/a&gt;
&lt;a href="../mautrix-telegram"&gt;&lt;span class="image"&gt;&lt;img src="https://img.shields.io/badge/mautrix-telegram-blue" alt="mautrix telegram blue"/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Mirint V2</title><link>https://nicolasguilloux.eu/articles/mirint-v2/</link><pubDate>Wed, 10 Mar 2021 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/mirint-v2/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Mirint V2" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai décidé de revoir mon &lt;a href="https://nicolasguilloux.eu/articles/mirint-v1"&gt;miroir intelligent&lt;/a&gt; pour plusieurs raisons :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;J’ai domotisé ma maison, et avoir un affichage des différents capteurs serait vraiment un plus&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;La page web affichée était faite à la main, alors que des solutions bien plus jolies existent comme &lt;a href="https://magicmirror.builders/" target="_blank" rel="noopener"&gt;MagicMirror&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Le miroir était beaucoup trop épais, il sortait du mur d’une 10aine de centimètres&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Il était moche&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Il était beaucoup trop lourd, impossible de l’installer sur un mur sans mettre 1 ou 2 chevilles&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L’écran mettait trop de temps à s’allumer, c’est dommage pour quelque chose qui doit donner des informations de manière spontanée de prendre 10 secondes à les afficher&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Autre chose qui en découle, mais on pouvait laisser l’écran allumé, mais il consommait beaucoup trop&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour toutes ces raisons, j’ai décidé de le démonter pour en faire une nouvelle version.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_matériel"&gt;Matériel&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_ecran"&gt;Ecran&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Je ne garderais pas l’écran car c’est la principale raison pour laquelle le miroir n’était pas satisfaisant. Comme c’est une ancienne télévision, tout était prévu pour avoir de l’espace derrière l’écran et que celle-ci soit posée sur un meuble. On peut le voir notamment avec les ports HDMI qui sont à la perpendiculaire de la dalle, son épaisseur et son poids.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="screen_display.jpg" alt="Ecran"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;J’ai réussi à récupérer un écran LCD d’un ordinateur portable et j’ai commandé une carte d’acquisition pour le modèle de l’écran de ~13€ qui fera l’interface entre la sortie HDMI du Rapsberry Pi et la dalle LCD. Le principal intérêt de récupérer un écran comme celui-ci est qu’il a été prévu pour ne pas consommer car étant à l’origine dans un appareil mobile, que son poids et son épaisseur sont vraiment faibles et que cela permet de déporter la dite carte où on peut pour économiser encore une fois de l’espace et réduire l’épaisseur du miroir.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;L’autre intérêt est le temps pour s’allumer. Il est quasi immédiat, c’est ainsi que sont utilisés les écrans d’ordinateurs portables. Vous verrez rarement un ordinateur mettre 10 secondes à s’allumer lorsque vous le sortez de veille, ou alors c’est votre OS qui prend son temps et non l’écran.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Et enfin la sécurité : je suis toujours plus à l’aise quand je ne travaille pas avec des tensions mortelles. Aussi, l’écran LCD et sa carte sont alimentés en 12V, ce qui permettra de sortir l’alimentation hors du miroir. Il faudra néanmoins prévoir un abaisseur de tension pour alimenter le Raspberry Pi en 5V.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_raspberry_pi"&gt;Raspberry Pi&lt;/h3&gt;
&lt;div class="quoteblock"&gt;
&lt;blockquote&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Parlons du Raspberry Pi. Il s’avère que je pensais avoir un Raspberry Pi 2, mais en fait c’est le premier modèle. Il est donc extrêmement lent, il n’a clairement pas les reins pour produire un affichage rapide qui pourrait avoir des animations fluides. Aussi, il faudra que je change ce composant, il n’est pas approprié. Pour le moment, je n’ai rien d’autre sous la main, et donc je l’utilise comme navigateur avec MagicMirror hébergé à un autre endroit. Dans la suite, je ferais comme si MagicMirror était hébergé sur le Raspberry Pi&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le Raspberry Pi va héberger le logiciel qui va nous permettre de facilement intégrer différents modules pour avoir l’affichage le plus complet possible : &lt;a href="https://magicmirror.builders/" target="_blank" rel="noopener"&gt;MagicMirror&lt;/a&gt;. C’est un logiciel spécialement conçu ce qu’on veut faire. Vous pouvez rajouter des plugins pour avoir toute sorte d’information sur l’écran. Comme tout côté logiciel a été fait, on ne va pas beaucoup aborder la configuration de MagicMirror hormis le fait d’avoir une installation fonctionnelle.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Lola</title><link>https://nicolasguilloux.eu/articles/lola/</link><pubDate>Sun, 18 Mar 2018 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/lola/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Lola" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Lola est une extension firefox qui permet de styliser votre nouvel onglet. C’est ma première approche vers les extensions des navigateurs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Elle est fortement inspirée de l’extension &amp;#34;Momentum&amp;#34; mais ajoute des fonctionnalités qui me plaisent :
 * La météo
 * Les raccourcis en bas à gauche sous forme d’icones
 * Des notifications en bas à droite&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://github.com/NicolasGuilloux/Lola" target="_blank" rel="noopener"&gt;Extension Firefox&lt;/a&gt; - &lt;a href="https://github.com/NicolasGuilloux/Lola" target="_blank" rel="noopener"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>Mirint</title><link>https://nicolasguilloux.eu/articles/mirint-v1/</link><pubDate>Mon, 10 Jul 2017 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/mirint-v1/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Mirint" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;Le miroir intelligent est une petite interface qui devrait, le matin et le soir (ou à vrai dire, à chaque fois que vous allez dans la salle de bain), vous donner des informations pertinentes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le but est de se dispenser de vérifier son Smartphone en affichant les choses à faire dans la journée, la météo et quelques news. Et dans un soucis d’ergonomie, pas besoin d’un bouton pour l’activer : un capteur de proximité se chargera de le réveiller quand vous le regardez.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour l’instant, le projet n’en est qu’à un stade de prototype non fini. Il n’est toutefois pas abandonné.
Après l’achèvement des premières fonctionnalités, le travail suivant sera d’implémenter une reconnaissance vocale.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_matériel"&gt;Matériel&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Mirint regroupe différents appareils &amp;#34;recyclés&amp;#34; : ils ne servaient plus, donc je me suis servi.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ecran de télévision LCD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Raspberry Pi 2 et son alimentation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Câble HDMI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Un coffret&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Un film miroir sans tain&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Une plaque de plexiglas&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Du fil et de quoi souder&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;La première étape a été de dépioter le téléviseur. Afin que le miroir soit le plus fin possible, il faut enlever toute la partie protection plastique pour ne garder que la dalle et les circuits du téléviseur qui se divisent souvent en deux parties : un circuit d’alimentation où on relit l’appareil au secteur et un circuit d’entrées/sorties où vous branchez HDMI etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il est important de &lt;strong&gt;ne pas toucher le circuit d’alimentation&lt;/strong&gt; quand le système est sous tension ! Il y a risque d’électrisation voire électrocution !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="tele_dessus.jpg" alt="Vue de dessus"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le Raspberry Pi est relié donc en HDMI au téléviseur. On pourrait auto-alimenter le RPi grâce au port USB du téléviseur, mais il sera tributaire de sa puissance. De plus, si le téléviseur est éteint, il y a de grandes chances que sur la plupart des téléviseurs, le port USB soit désactivé. On opte donc pour une alimentation séparée.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le coffret a été raboté afin de pouvoir placer le téléviseur sur ses rebords et donc avoir la dalle sur le même plan horizontal que les bords du coffret. Il faudra aussi faire en sorte que ces mêmes bords ainsi que ceux du téléviseur soient noirs (peinture ou scotch noir).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="tele_dos.jpg" alt="Dos de la télé"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;La plaque de plexiglas a été découpée avec les dimensions extérieures du coffret afin qu’elle couvre toute la surface.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le film miroir a été collé sur la surface qui sera vers l’intérieur du coffret afin d’éviter toute dégradation et rentrée de lumière. Pour le mettre en place :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Bien laver le plexiglas,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mettre de l’eau savonneuse sur la surface à coller,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enlever le film protecteur du revêtement miroir,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Placer le film progressivement sur la surface en raclant avec une carte afin de chasser les bulles d’air&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Une fois placé et bien séché, couper l’excédent de film&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour ma part, j’ai percé puis fraisé le plexiglas pour le visser sur le coffret.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Par ailleurs, on veut pouvoir allumer le téléviseur sans appuyer physiquement sur le bouton &amp;#34;Allumer&amp;#34; car ça contraint à démonter le miroir à chaque fois. Ainsi, on regarde la tension appliquée aux bornes de ce bouton poussoir. Généralement, il y a 4 pattes, on peut vérifier avec deux bornes en diagonale.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="btn_power.jpg" alt="Boutons"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois trouvé (pour ma part 3,3V), on soude deux fils : un qui ira à la masse du Raspberry Pi et l’autre à un de ses nombreux GPIO, j’ai choisi le n°7. Pour voir la partie logicielle, rendez vous un peu plus bas au paragraphe &amp;#34;Contrôle du téléviseur&amp;#34;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_logiciel"&gt;Logiciel&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;strong&gt;La partie logicielle est obsolète, puisque maintenant il y a &lt;a href="https://magicmirror.builders/" target="_blank" rel="noopener"&gt;MagicMirror&lt;/a&gt; qui propose de faire tout ce que j’ai pu proposer.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Dans un premier temps, veillez à bien configurer votre téléviseur pour s’allumer lorsque qu’on le branche et de choisir la source HDMI par défaut. Vous pouvez aussi configurer la profondeur du noir : plus il sera profond plus le rendu sera de qualité.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;De plus, vous pouvez configurer le téléviseur pour ne pas s’éteindre. Une amélioration sera à prévoir pour économiser de l’énergie.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Venons au Raspberry qui sera le cerveau de notre miroir. J’ai choisi de faire l’affichage en HTML sur un serveur Web qui sera pour ma part plus facile à maintenir. Toutefois, avant de parler du coeur du projet, il faut configurer notre Raspberry. Je me suis basé sur l’OS Raspbian Jessie Lite. Je pars du principe que les périphériques branchés fonctionnent correctement (comme la carte WiFi de votre RPi).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_connexion_au_wifi"&gt;Connexion au Wifi&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Commençons par chercher le SSID de votre réseau (son petit nom en fait) en scannant ce que le RPi reçoit : &lt;code&gt;sudo iwlist wlan0 scan&lt;/code&gt;. Cherchez le SSID de votre réseau et notez le dans un coin de votre tête.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va maintenant modifier les paramètres des réseaux WiFi &lt;code&gt;sudo nano /etc/wpa_supplicant/wpa_supplicant.conf&lt;/code&gt; puis rentrez les informations comme suit à la fin du fichier (ou dans le champ correspondant s’il existe déjà la variable) :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;network={
 ssid=&amp;#34;votre SSID&amp;#34;
 psk=&amp;#34;votre mot de passe&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;ATTENTION : Votre mot de passe est stocké en clair.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ensuite, on valide nos changements en effectuant ce petit bout de code : &lt;code&gt;sudo wpa_cli reconfigure&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On aura besoin d’une interface graphique et de mettre à jour le bousin. On installe donc un serveur X et on met à jour le système (et un petit brin de ménage au cas ou) avec la ligne suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get --no-install-recommends install xserver-xorg xserver-xorg-video-fbdev xinit pciutils xinput xfonts-100dpi xfonts-75dpi xfonts-scalable x11-xserver-utils unclutter
sudo apt-get dist-upgrade
sudo apt-get autoremove&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_paramétrage_du_raspberry_pi"&gt;Paramétrage du Raspberry Pi&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On va maintenant aller dans les configurations de base du RPi : &lt;code&gt;sudo raspi-config&lt;/code&gt;. Cela vous amènera sur l’interface &amp;#34;graphique&amp;#34; suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="raspi-config.jpg" alt="Raspi config"/&gt;&lt;/span&gt;]&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On configure comme ça nous plait en changeant le mot de passe et les options de localisation. On choisit ensuite le menu Interfacing Option pour activer le SSH afin de piloter le miroir à distance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Enfin, on appuie 2 fois sur Tab pour sélectionner &amp;#34;Finish&amp;#34; et on accepte de redémarrer notre Raspberry Pi.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_rotation_de_lécran"&gt;Rotation de l’écran&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une rotation de l’écran peut être souhaitable suivant le sens de votre miroir. Il nous faut alors modifier un fichier en suivant cette commande : &lt;code&gt;sudo nano /boot/config.txt&lt;/code&gt; et on y ajoute la ligne &lt;code&gt;display_rotate = 1&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Voici les différentes options :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;0 : Orientation normale&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1 : 90 degrés&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2 : 180 degrés&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3 : 270 degrés&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_configuration_de_linterface_graphique"&gt;Configuration de l’interface graphique&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;D’abord, on ajoute un nouvel utilisateur pour se connecter avec lors des connexions SSH. On lance la commande &lt;code&gt;sudo adduser NouvelUtilisateur&lt;/code&gt;. On répond gentillement à tout ce qu’il nous demande.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On souhaite maintenant charger juste un navigateur. Il faut donc choisir votre navigateur préféré, j’ai choisi Chromium. Pour l’installer : &lt;code&gt;sudo apt-get install chromium-browser&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ensuite, pour lancer le navigateur en plein écran sur GitHub, il faut suivre la commande suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;startx /usr/bin/chromium-browser https://github.com/ --window-size=1080,1920 --start-fullscreen --kiosk --incognito -- -nocursor&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il faut prendre garde à l’orientation de l’écran et sa résolution. Pour ma part, je l’avais mis format portrait en full HD.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour l’ajouter au démarrage, édite un fichier par la commande &lt;code&gt;nano ~/.bashrc&lt;/code&gt; sous l’utilisateur &amp;#34;pi&amp;#34; et ajoute la commande.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Il faudra maintenant arrêter l’écran de veille en éditant le fichier lightdm.conf par la commande suivant &lt;code&gt;sudo nano /etc/lightdm/lightdm.conf&lt;/code&gt; et on ajoute &lt;code&gt;xserver-command=X -s 0 dpms&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_pilotage_à_distance"&gt;Pilotage à distance&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Notre miroir n’a ni clavier, ni souris. Et rien n’est moins pratique que de contrôler le miroir par la pensée. On va donc se servir du protocole VNC qui va nous servir à piloter l’interface graphique à distance, comme avec le SSH (ils peuvent d’ailleurs être liés). Pour cela, on installe x11vnc : &lt;code&gt;sudo apt-get install x11vnc&lt;/code&gt;. Ensuite, on peut lancer 1 session avec &lt;code&gt;x11vnc -auth guess&lt;/code&gt; une fois startx lancé par SSH.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_contrôle_du_téléviseur"&gt;Contrôle du téléviseur&lt;/h3&gt;
&lt;div class="paragraph float-right"&gt;
&lt;p&gt;&lt;span class="image"&gt;&lt;img src="gpio.png" alt="GPIO"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Cela découle directement du soudage du bouton. Dans un premier, on installe WiringPi en suivant les instructions de ce &lt;a href="http://wiringpi.com/download-and-install/"&gt;lien&lt;/a&gt;. Cela nous permettra d’utiliser facilement les GPIO ! Pour plus d’informations, je vous laisse checker le &lt;a href="http://blog.idleman.fr/raspberry-pi-06-utiliser-le-gpio-et-interagir-avec-le-monde-reel/"&gt;blog d’Idleman&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Une fois installé, on peut commencer les festivités. On paramètre d’abord le GPIO pour être en mode &amp;#34;out&amp;#34; : &lt;code&gt;gpio mode 7 out&lt;/code&gt;. Comme je l’ai dit précédemment, j’ai choisi le GPIO 7 (en suivant le schéma joint). On peut ensuite piloter le port en utilisant &lt;code&gt;gpio write 7 bit&lt;/code&gt; en remplaçant &amp;#34;bit&amp;#34; par 1 pour du 3,3V ou 0 pour du 0V.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;On peut voir que le bouton réagit par front descendant en s’amusant à changer ces valeurs (donc pour simuler le bouton appuyé, on place le GPIO à 0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ainsi, pour simuler l’appui du bouton, on utilise la ligne suivante :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;gpio write 7 0 &amp;amp;&amp;amp; sleep 1 &amp;amp;&amp;amp; gpio write 7 1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Pour paramétrer le GPIO en mode out et à l’état 1 (repos du bouton), il nous faut éditer le fichier /home/pi/.bashrc et rajouter les lignes suivantes :&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;gpio mode 7 out
gpio write 7 1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Ainsi à chaque démarrage, on configure le GPIO 7 en mode Out et à l’état 1.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Cafetière à Induction Domotisée</title><link>https://nicolasguilloux.eu/articles/cid/</link><pubDate>Sun, 25 Jun 2017 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/cid/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Cafetière à Induction Domotisée" /&gt;&lt;div class="paragraph"&gt;
&lt;p&gt;La Cafetière à Induction Domotisée, aka CID, est une cafetière avec plus d’un atout dans sa poche.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le but de ce projet était de faire du café rapidement, silencieusement avec la même qualité que les cafetières à dosette. En bref, combler les lacunes de ces dernières en ajoutant une partie domotique.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Le projet a été commencé par mes soins, puis poursuivi dans le cadre des projets de deuxième année de l’ENSEA avec &lt;a href="https://www.linkedin.com/in/loirevalentin/" target="_blank" rel="noopener"&gt;Valentin Loire&lt;/a&gt;. Nous poursuivons jusqu’à ce jour le développement.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="quoteblock"&gt;
&lt;blockquote&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;&lt;a href="https://nicolasguilloux.github.io/cid/" target="_blank" rel="noopener"&gt;Voir sa page de présentation&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;div class="video-wrapper"&gt;
 &lt;iframe loading="lazy" 
 src="https://www.youtube.com/embed/DSbic6T9NO8" 
 allowfullscreen 
 title="YouTube Video"
 &gt;
 &lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;</description></item><item><title>Douglas</title><link>https://nicolasguilloux.eu/articles/douglas/</link><pubDate>Wed, 01 Jan 2014 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/douglas/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Douglas" /&gt;&lt;p&gt;Douglas est une enceinte Bluetooth Low-Cost. Une batterie pour portable recyclée, à peu près 15€ de l&amp;rsquo;huile de coude et vous voilà avec un objet essentiel pour toute sortie entre amis.
Pourquoi l&amp;rsquo;ourson ? Parce que c&amp;rsquo;est mignon, ça protège bien le matériel qu&amp;rsquo;il y a dedans et que c&amp;rsquo;est original.&lt;/p&gt;
&lt;p&gt;Douglas est fonctionnel, mais toujours en développement. En effet, je souhaite y apporter quelques fonctionnalités comme la visualisation de la charge de la batterie, le réveil de l&amp;rsquo;enceinte sans besoin de bouton physique (hormis pour l&amp;rsquo;appairage).&lt;/p&gt;
&lt;h1 id="version-1"&gt;Version 1
&lt;/h1&gt;&lt;p&gt;Douglas a surtout pour principe de ne pas couter cher en achetant le minimum possible. Ainsi, seuls les objets ayant un lien dans la liste suivante ont été achetés, le reste étant de la récupération.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une batterie Li-Ion&lt;/li&gt;
&lt;li&gt;Un amplificateur symétrique&lt;/li&gt;
&lt;li&gt;Deux haut-parleurs 3W&lt;/li&gt;
&lt;li&gt;Un circuit de charge pour batterie Li-Ion&lt;/li&gt;
&lt;li&gt;Un module Bluetooth A2DP (le BK800L)&lt;/li&gt;
&lt;li&gt;Des résistances de 10kΩ, des boutons poussoirs&lt;/li&gt;
&lt;li&gt;Des fils, de l&amp;rsquo;étain et un fer à souder&lt;/li&gt;
&lt;li&gt;Une plaquette pour souder&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On en a en tout pour une 15aine d&amp;rsquo;euros, on s&amp;rsquo;en sort donc pas trop mal. Il reste maintenant à souder tous les composants ensemble afin que tout fonctionne correctement.&lt;/p&gt;
&lt;p&gt;Les choses sérieuses arrivent et il faudra être bien concentré pour la suite des évènements. En effet, le module Bluetooth est un enfer à souder pour peu qu&amp;rsquo;on n&amp;rsquo;ait ni fil à wrapper, ni un fer à souder digne de ce nom&amp;hellip; J&amp;rsquo;ai donc fait au possible.
J&amp;rsquo;ai dénudé un fil multibrin pour découper des brins de longueur 3cm. J&amp;rsquo;ai ensuite soudé chaque brin sur les cosses du module. C&amp;rsquo;est fastidieux et ça a tendance à déconner. Le mieux aurait été de faire un PCB, mais quand on a pas le matériel, on se débrouille quand même !&lt;/p&gt;
&lt;p&gt;Je n&amp;rsquo;ai pas utilisé toutes les pins mais seulement les suivantes : 1, 2, 4, 5, 6, 7, 12, 16, 17, 25, 26, 29, 32.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai préféré relier toutes les masses (GND sur le schéma) à la masse pour éviter au maximum les interférences. Je ne sais pas si c&amp;rsquo;est utile, mais ça me rassure. De plus, je n&amp;rsquo;ai choisi que les pins qui m&amp;rsquo;intéressaient à savoir les boutons, le son et l&amp;rsquo;alimentation. On peut très bien utiliser les pins Rx/Tx pour renommer le module Bluetooth par exemple (et remplacer cet affreux nom &amp;ldquo;BK8000L&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Place maintenant au montage sur la carte. On prend une petite carte qui acceptera tous les composants.
On colle dans un premier temps la batterie sur le circuit. Ensuite, on soude un à un les composants comme le stipule le schéma suivant :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://nicolasguilloux.eu/articles/douglas/schema.png"
	width="947"
	height="536"
	loading="lazy"
	
		alt="Schema"
	
 
	
		class="gallery-image" 
		data-flex-grow="176"
		data-flex-basis="424px"
	
&gt;&lt;/p&gt;
&lt;p&gt;Assurez vous que les soudures soient bien faites afin de ne pas avoir de mauvaises surprises. De plus, prenez garde au soudage du module Bluetooth qui est extrêmement fastidieux compte tenu des petits espaces disponibles, d&amp;rsquo;où l&amp;rsquo;utilité des fils à wrapper.&lt;/p&gt;
&lt;p&gt;Cela donne le résultat suivant. Vous avez théoriquement 4 fils non-reliés qui sont dédiés aux speakers. J&amp;rsquo;ai mis un fil supplémentaire qui est un câble USB directement soudé aux bornes du circuit de charge. J&amp;rsquo;ai donc un port femelle micro-USB ou un câble USB mâle sortant pour recharger facilement.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://nicolasguilloux.eu/articles/douglas/montage.jpg"
	width="1152"
	height="955"
	loading="lazy"
	
		alt="Montage"
	
 
	
		class="gallery-image" 
		data-flex-grow="120"
		data-flex-basis="289px"
	
&gt;&lt;/p&gt;
&lt;p&gt;Pour les enceintes, il a fallu faire 2 caisses de résonnance adaptée aux haut-parleurs et aux dimensions de mon ourson. J&amp;rsquo;ai pris des tubes en carton trouvés par-ci par-là. A vous d&amp;rsquo;adapter comme vous le voulez ou pouvez afin d&amp;rsquo;avoir une bonne caisse de résonnance. Il n&amp;rsquo;y a pas de règle particulière si ce n&amp;rsquo;est que de bien fixer les HP pour éviter toute fuite d&amp;rsquo;air ou vibration.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://nicolasguilloux.eu/articles/douglas/speaker.jpg"
	width="849"
	height="1045"
	loading="lazy"
	
		alt="Speakers"
	
 
	
		class="gallery-image" 
		data-flex-grow="81"
		data-flex-basis="194px"
	
&gt;&lt;/p&gt;
&lt;h1 id="pour-une-prochaine-version"&gt;Pour une prochaine version
&lt;/h1&gt;&lt;p&gt;Douglas v1 souffrait de quelques petits problèmes ergonomiques.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Quand quelqu&amp;rsquo;un le serrait dans ses bras (ce qui arrivait souvent), cela pouvait appuyer sur le bouton situé au niveau du ventre. Un appui long redémarre le module ce qui est frustrant lorsque de la musique est en route.&lt;/li&gt;
&lt;li&gt;Les boutons pour changer de chanson n&amp;rsquo;étaient quasiment jamais utilisés.&lt;/li&gt;
&lt;li&gt;Les boutons volumes seraient souhaitables mais pourraient ne pas être utilisés.&lt;/li&gt;
&lt;li&gt;Changer le volume sur le module s&amp;rsquo;effectue localement. Or, on pourrait souhaiter qu&amp;rsquo;un changement de volume sur Douglas se transmette au Smartphone afin que le volume s&amp;rsquo;actualise sur ce dernier.&lt;/li&gt;
&lt;li&gt;Le circuit de charge n&amp;rsquo;est pas facile d&amp;rsquo;accès.&lt;/li&gt;
&lt;li&gt;La carte en elle même n&amp;rsquo;est pas prévue pour une longue durée de vie, vu les soudures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce sont des petits problèmes qui n&amp;rsquo;en sont pas. Je pinaille, mais c&amp;rsquo;est suffisant pour se lancer dans une version 2 qui pourrait résoudre certains de ces problèmes !&lt;/p&gt;
&lt;p&gt;De plus, j&amp;rsquo;aimerais bien passer pour la version 2 sur du 5W afin d&amp;rsquo;avoir plus de puissance.&lt;/p&gt;
&lt;p&gt;Autre chose qui m&amp;rsquo;embête, c&amp;rsquo;est le nom du module Bluetooth. En effet, il diffuse le nom &amp;ldquo;BK8000L&amp;rdquo;. Ce serait super chouette de pouvoir le modifier en Douglas par exemple.&lt;/p&gt;
&lt;p&gt;Un petit plus serait aussi de pouvoir rediriger le son vers une sortie jack. J&amp;rsquo;ai pensé à ça quand il y a une petite sono sans bluetooth, et qu&amp;rsquo;on souhaite quand même profiter du sans fil sans installation bancale.&lt;/p&gt;
&lt;p&gt;De la même manière, pouvoir brancher un câble Jack dans Douglas pour bénéficier de ses haut-parleurs pourrait être sympathique. Dans le module ci-dessus du moins, les ports Aux_L et Aux_R (20 et 19) ne sont malheureusement pas déportés. Si nous voulons les utiliser, il faudra souder deux fils sur la carte ce qui peut s&amp;rsquo;avérer laborieux et dangereux pour la carte.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://nicolasguilloux.eu/articles/douglas/aux_module.png"
	width="700"
	height="542"
	loading="lazy"
	
		alt="Aux module"
	
 
	
		class="gallery-image" 
		data-flex-grow="129"
		data-flex-basis="309px"
	
&gt;&lt;/p&gt;
&lt;p&gt;Enfin, je souhaiterai oublier les petites batteries Li-Ion si possible. En effet, dans une des enceintes que j&amp;rsquo;avais conçu, l&amp;rsquo;une d&amp;rsquo;elle avait gonflé et comme elles ne sont pas protégées, je ne suis pas rassuré.&lt;/p&gt;
&lt;p&gt;Je préfère utiliser des batteries externes car elles sont généralement protégées par un boitier, et ont une bien plus grande capacité.&lt;/p&gt;</description></item><item><title>Yana</title><link>https://nicolasguilloux.eu/articles/yana/</link><pubDate>Thu, 24 Oct 2013 00:00:00 +0000</pubDate><guid>https://nicolasguilloux.eu/articles/yana/</guid><description>&lt;img src="https://nicolasguilloux.eu/" alt="Featured image of post Yana" /&gt;&lt;p&gt;YANA est une interface domotique développée par &lt;a class="link" href="https://github.com/ldleman" target="_blank" rel="noopener"
 &gt;Idleman&lt;/a&gt;.
L&amp;rsquo;application Android permettait de dicter des ordres afin de déclencher les actions côté serveur. Elle servait donc d&amp;rsquo;interface portable pour contrôler l&amp;rsquo;installation.&lt;/p&gt;
&lt;p&gt;A cause de mes études, j&amp;rsquo;ai dû mettre de côté le développement de l&amp;rsquo;application pour au final l&amp;rsquo;abandonner. En effet, le serveur a beaucoup évolué sans que je puisse poursuivre les mises à jour. Une autre personne a continué le développement et est donc en charge par la suite de maintenir.&lt;/p&gt;
&lt;p&gt;Je remercie :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ldleman" target="_blank" rel="noopener"
 &gt;Valentin Carruesco&lt;/a&gt; pour le développement de YANA serveur.&lt;/li&gt;
&lt;li&gt;Alexandre Roland pour la reprise du développement de YANA Android.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>