Choisir son poêle de masse : Un calculateur en ligne pour vous aider

Installer un poêle de masse chez soi, c’est faire le choix d’un chauffage au bois performant et écologique, mais encore faut-il bien le dimensionner. De quelle quantité de chaleur votre maison a-t-elle vraiment besoin en plein hiver ? Quel modèle de poêle de masse conviendrait le mieux à vos besoins ? Ce sont des questions que je me suis posées il y a quelques années, sans trouver d’informations facilement accessibles…

C’est aussi une question récurrente chez les autoconstructeurs : par exemple autour du MiniMasse (auquel je continue de contribuer chez Agir Low-Tech), un petit poêle de masse, pour petit habitat. Beaucoup se disent « chouette c’est petit et pas cher » – oui, mais est-ce adapté à votre espace à chauffer ? Pour répondre à ces interrogations, j’ai développé choisir son poêle de masse, un logiciel libre en ligne qui estime les besoins de chauffage de votre habitat et suggère en conséquence le bon poêle de masse (de conception open source) qui y correspond le mieux.

Plusieurs méthodes de calculs

La première étape pour choisir un poêle de masse est d’évaluer le besoin de chauffage de votre maison, c’est-à-dire la quantité de chaleur qu’il faut fournir pour maintenir une température confortable lors des périodes les plus froides. Selon vos connaissances en thermique du bâtiment et les informations dont vous disposez, le logiciel propose trois méthodes de calcul, du plus simple au plus précis :

  • Mode Basic (méthode G)Pour une estimation rapide. Cette méthode simplifiée utilise un coefficient global G caractérisant les pertes thermiques de votre logement. Vous pouvez choisir une valeur de G correspondant au niveau d’isolation de votre maison (par exemple G≈0,3 pour une maison très bien isolée, jusqu’à G≈1,8 pour un bâtiment ancien non isolé). C’est simple et empirique : on multiplie essentiellement ce coefficient par le volume et par l’écart de température, ce qui donne une idée grossière de la puissance de chauffage requise. Ce mode convient si vous n’êtes pas expert en thermique et voulez un ordre de grandeur rapidement. Toutefois, le résultat reste indicatif : il faudra peut-être affiner si votre projet se précise ou si votre maison a des particularités.
  • Mode Éclairé (méthode Ubat global)Pour un calcul intermédiaire. Ici on raisonne avec le Ubat global, c’est-à-dire le coefficient moyen de déperdition thermique de l’enveloppe du bâtiment. Si votre maison est relativement homogène en terme d’isolation (par exemple une construction récente où toutes les parois ont des performances comparables), cette méthode est un peu plus technique et affine le calcul. Ce mode donne une estimation plus précise que la méthode G tout en restant assez simple si l’isolation est uniforme.
  • Mode Expert (méthode Ubat par paroi)Pour un calcul au plus près de la réalité. Ce mode s’adresse à ceux qui ont de bonnes connaissances du bâtiment ou qui font face à un bâti complexe (ancienne maison rénovée, extension hétérogène, etc.). On détaille chaque paroi de la maison (murs, toit, plancher, fenêtres…), avec leurs dimensions et matériaux, afin de calculer un Ubat précis pour l’ensemble. C’est plus fastidieux (quoique pas insurmontable), mais indispensable si l’isolation n’est pas uniforme ou si vous disposez déjà d’une étude thermique détaillée de votre habitation. Par exemple, en rénovation, on a souvent des parois différentes les unes des autres : la méthode « expert » permet de prendre en compte chaque spécificité pour éviter les erreurs de calcul qu’entraînerait un simple coefficient global. C’est le mode à privilégier si vous voulez un dimensionnement aux petits oignons de votre poêle de masse, notamment dans les projets complexes où la méthode G peut montrer ses limites.

En pratique, l’application vous permet de sélectionner votre « niveau de connaissance » (Débutant, Éclairé ou Expert) dès le début, ce qui ajuste les paramètres disponibles. En mode débutant, l’interface reste épurée avec peu de données à saisir (superficie, volume, isolation estimée…). Plus on monte en expertise, plus on a accès à des réglages pointus (coefficient U personnalisable, ajout des différentes parois, matériaux sur mesure, ponts thermiques, etc.). Chaque utilisateur peut ainsi choisir la méthode adaptée à son cas.

Des données météo en temps réel pour plus de précision

Quel que soit le mode de calcul, le logiciel intègre les données météorologiques de votre localisation pour affiner le résultat. Autrefois, on utilisait une carte de France découpée en zones climatiques (température moyenne de base par département) ; désormais, le logiciel va chercher directement la température de base correspondant à votre commune grâce à une API météo qui reprend les données du projet Européen Copernicus. Concrètement, il vous suffit d’indiquer votre localisation (vous pouvez sélectionner votre ville sur une carte intégrée) et l’outil récupère automatiquement la température de base qui servira de référence pour dimensionner le poêle.

En développant ce logiciel, je me suis vite rendu compte que la température de base était un paramètre crucial, et que la norme qui fait foi en la matière semblait approximative… J’ai donc lancé une enquête auprès de l’AFNOR, Météo France, le COSTIC et autres… (en partie visible ici) pour comprendre comment cette température était actuellement déterminée et quels écarts existaient avec la réalité du terrain. Cette enquête, a permis de révéler que les normes en vigueur, NF P52-612, auraient besoin d’être révisées pour mieux prendre en compte les évolutions climatiques récentes. Et que l’opacité de la méthode de calcul était, au mieux, regrettable. Pour aller plus loin sur ce sujet essentiel, j’ai rédigé un article détaillé sur le site de l’AFPMA : Réviser la température de base NF P52-612, une nécessité.

Pourquoi est-ce important ? Parce que la puissance requise dépend fortement de la température minimale à affronter. Par exemple, une maison en Bretagne n’aura pas le même besoin qu’une maison en Alsace. Grâce à l’API météo, le calculateur s’adapte à votre région en temps réel. Par ailleurs, le logiciel utilise aussi les degrés-jours unifiés (DJU) de votre localisation pour estimer la demande de chauffage sur une saison complète. En effet, au-delà de la puissance instantanée nécessaire par grand froid, on souhaite savoir combien d’énergie sera consommée sur tout l’hiver. Les DJU permettent de calculer cela, et par extension d’estimer la consommation de bois sur la saison de chauffe. Cette estimation de consommation bois a été ajoutée dans le logiciel pour donner une idée des quantités de bûches ou de granulés que vous utiliserez. C’est très utile pour le futur usager : vous pouvez anticiper le volume de bois à prévoir chaque année, et aussi comparer l’efficacité de différents scénarios d’isolation par exemple (voire l’impact d’une amélioration d’isolation sur la consommation annuelle).

Des suggestions de poêles de masse

Une fois les besoins de chauffage calculés, Choisir son poêle de masse passe à la seconde étape : vous suggérer un ou plusieurs modèles de poêles de masse adaptés. L’outil s’appuie pour cela sur une base de données de poêles de masse open source. Ces poêles libres (dont les plans sont partagés) ont des puissances et caractéristiques connues – par exemple le MiniMasse développé par l’association Agir Low-Tech, les modèles Oxa-libre de différentes puissances, l’Uzume, etc. En comparant la puissance de ces poêles disponibles aux déperditions de votre maison calculées précédemment, le logiciel identifie ceux qui correspondent le mieux à votre besoin de chauffage.

Un logiciel libre, gratuit et collaboratif

Choisir son poêle de masse est un logiciel 100 % libre et gratuit. Je l’ai développé dans un esprit d’ouverture : le code source du projet est publié sur Framagit (GitLab) et chacun est invité à y contribuer. Que vous soyez développeur, poêlier, designer ou simple utilisateur, vous pouvez participer à son amélioration. Par exemple, il est possible de proposer de nouvelles fonctionnalités, d’aider à la traduction (l’interface est déjà disponible en français et en anglais, d’autres langues peuvent suivre), d’améliorer le design de l’application, ou encore d’enrichir la base de matériaux pour les parois. En effet, le mode Expert permet de créer des matériaux personnalisés (avec leur conductivité, etc.) et de partager ces données pour qu’elles bénéficient à tous les utilisateurs. Le projet est collaboratif jusqu’au bout : vos contributions, retours et idées sont les bienvenus pour le rendre plus fiable et convivial.

Autre aspect de cette philosophie ouverte : plusieurs versions et déclinaisons du calculateur existent pour différents usages. L’outil de base – disponible sur choisir.poeledemasse.org – est pensé pour les autoconstructeurs ou particuliers qui veulent concevoir et dimensionner eux-mêmes leur poêle de masse (c’est cette version que je mets en avant dans cet article). Mais à partir de ce tronc commun, j’ai réalisé des adaptations spécifiques :

  • Minimasse – accessible via https://minimasse.choisir.poeledemasse.org – est une version simplifiée dédiée au modèle MiniMasse. Elle permet de tester en deux temps trois mouvements si un MiniMasse peut suffire pour chauffer votre habitation, ou s’il faut envisager un poêle plus grand. C’est très pratique pour ceux qui sont tentés par ce poêle de masse très compact et économique : on peut vérifier instantanément si « ça passe ou pas » avant de se lancer. Si le MiniMasse ne convient pas, l’outil élargit automatiquement la recherche aux autres poêles de masse open source disponibles afin de vous suggérer une alternative adaptée.
  • Uzume – A une déclinaison intégrée au site d’Uzume (un acteur bien connu dans le domaine des poêles de masse open source). Sur la page d’Uzume consacrée au dimensionnement, ce module permet aux lecteurs de calculer leur besoin de chauffage et de comprendre quel poêle il leur faut, sans quitter le site d’Uzume. Pour moi c’est une belle reconnaissance de voir ce calculateur utilisé de cette manière !
  • Étude et Dimensionner – (etude.poeledemasse.org et dimensionner.poeledemasse.org) sont deux instances du logiciel à destination des professionnels. L’idée est de fournir aux poêliers et bureaux d’étude un outil en ligne pour dimensionner les poêles de leurs clients et partager les résultats facilement. Par exemple, un artisan peut saisir toutes les données d’une maison en rénovation dans etude.poeledemasse.org, et envoyer le lien du résultat au client ou à un collègue. Chacun peut ainsi consulter l’étude thermique en ligne, avec les chiffres clés. C’est une façon moderne de remplacer les tableurs que les poêlier utilisait jusque-là, tout en profitant de la transparence et de l’évolutivité du logiciel. À noter que ces versions « pros » peuvent avoir un design ou des options légèrement adaptés (par exemple, afpma.choisir.poeledemasse.org est une variante orientant l’utilisateur vers un artisan poêlier de l’AFPMA prêt de chez lui.

En résumé, choisir son poêle de masse s’inscrit dans une démarche low-tech et open source : il vise à démocratiser le dimensionnement des poêles de masse, en rendant ces calculs techniques accessibles au plus grand nombre, gratuitement. Évidemment, les résultats fournis restent indicatifs et ne remplace en rien une (vraie) étude thermique : il est toujours recommandé de faire valider son projet par un professionnel qualifié (par exemple un artisan membre de l’AFPMA) pour s’assurer que tout est en ordre dans les moindres détails. Toutefois, cet outil offre déjà une base pour orienter vos choix et vous auto-former. Il peut vous éviter de grosses erreurs (comme sous-dimensionner votre poêle et avoir froid, ou le surdimensionner et l’utiliser inefficacement) en amont de votre projet.

Pour vos questions poêles de masse : un forum dédié aux poêles de masse open source existe ! Venez discuter du MiniMasse, du poêlito et compagnie…
forum.poeledemasse.org

Crowdsec – ispconfig / iptables

Je suis passé de fail2ban (que j’utilise depuis lonnngtemps) à Crowdsec pour les raisons suivantes :

  • fail2ban est (très) gourmand en ressource serveur (trop)
  • Crowdsec dispose d’un volet « scénario » que je trouve bien malin et qui le rend « plus intelligent » et permet de mutualiser les IP frauduleuse.

Au final je bloque certainement plus d’attaques pour bien moins de CPU (surtout) consommés.

C’est plutôt flagrant sur le côté « économie de ressources CPU » sur les graph :

Comparatif stats (munin) avant avec fail2ban et après avec crowdsec

Mise en œuvre

Mon contexte : des serveurs avec le panel ISPconfig (ce dernier écoute sur le port 8080 – important pour la suite) sur Debian 11.

Je ne vais pas détailler ici ce qu’il y a dans la documentation Crowdsec, d’autant que ça peut changer. Pour mon OS (Debian) actuellement c’est :

# Installation du dépôt
curl -s https://install.crowdsec.net | sudo sh
# Installation de crowdsec
apt install crowdsec

Du coup, comme ISPconfig écoute déjà sur le port 8080 et que Crowdsec utilise ce port pour son API il faut modifier celui-ci (moi je passe à 8079) :

sed -i -e "s/8080/8079/g" /etc/crowdsec/config.yaml
sed -i -e "s/8080/8079/g" /etc/crowdsec/local_api_credentials.yaml
systemctl restart crowdsec

ISPconfig n’utilise pas logrotate pour la rotation de log apache, il a son propre processus intégré. Pour que Crowdsec puisse lire tout les logs HTTP (ici apache) il va falloir lui donner le chemin. MAIS. ISPconfig nomme les logs par date et créer un lien symbolique vers « access.log » :

# ls /var/log/ispconfig/httpd/david.mercereau.info/ -la
total 173480
drwxr-xr-x   2 root root     4096 30 juin  12:19 .
drwxr-xr-x 176 root root    12288 21 juin  16:05 ..
[...]
-rw-r--r--   1 root root  4712747 29 juin  23:59 20240629-access.log
-rw-r--r--   1 root root  2836678 30 juin  14:08 20240630-access.log
lrwxrwxrwx   1 root root       19 30 juin  12:19 access.log -> 20240630-access.log
lrwxrwxrwx   1 root root       55 30 juin  00:12 yesterday-access.log -> /var/www/clients/client3/web196/log/20240629-access.log

Ceci cause un problème pour la surveillance des changement crowdsec : https://github.com/crowdsecurity/crowdsec/issues/574. On pourrait indiquer /var/log/ispconfig/httpd/*/access.log mais il faudrait modifier le paramètre : https://docs.crowdsec.net/docs/data_sources/file/#poll_without_inotify et les performances (occupation) CPU s’en font directement sentir… C’est dommage. J’ai donc préféré indiquer /var/log/ispconfig/httpd//*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*.log à crowdsec :

echo "filenames:
  # Vhost
  - /var/log/ispconfig/httpd/*/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*.log
labels:
  type: apache2" > /etc/crowdsec/acquis.d/ispconfig.yaml

Mais pour que le « nouveau » log soit pris en considération je fais un restart du service crowdsec à 0:20 (la rotation ayant lieu à ~0:10) chez moi au vu des date de création des fichiers de logs :

20 0 * * * systemctl restart crowdsec

C’est un peu du bricolage mais c’est le meilleurs compromis que j’ai jusque là.

EDIT : j’ai changé mon fusil d’épaule pour (aussi) ménager le nombre de fichier suivi par crowdsec (j’ai un serveur avec 200 vhost). En effet je me suis rendu compte que /var/log/apache2/other_vhosts_access.log était surveillé via /etc/crowdsec/acquis.yaml donc il y avait double surveillance des access. J’ai donc juste ajouté les « error.log » dans mon /etc/crowdsec/acquis.d/ispconfig.yaml

filenames:
  - /var/log/ispconfig/httpd/*/error.log
labels:
  type: apache2

J’ajoute d’autres « collection » en fonction des services que j’ai sur ce serveur :

cscli collections install crowdsecurity/base-http-scenarios
cscli scenarios install   crowdsecurity/http-bf-wordpress_bf  crowdsecurity/http-bf-wordpress_bf_xmlrpc  crowdsecurity/http-wordpress_user-enum  crowdsecurity/http-wordpress_wpconfig
cscli collections install crowdsecurity/dovecot
echo "filenames:
  - /var/log/mail.log
labels:
  type: syslog " > /etc/crowdsec/acquis.d/mail.yaml 
cscli collections install fulljackz/pureftpd

A ce stade il n’y a aucun ‘effet’ (pas de blocage). De mon côté j’utilise le firewall iptables donc j’ai utiliser le bouncer qui va bien pour lui :

apt install crowdsec-firewall-bouncer-iptables

De la même façon on change le port pour joindre l’API

sed -i -e "s/8080/8079/g" /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
systemctl restart crowdsec-firewall-bouncer

Des commandes utiles :

cscli decision list  
cscli alert list
# Pour voir toutes les IP blacklisté (intégrant les IP renvoyé par l'API centrale crowdsec
ipset list crowdsec-blacklists 
# Supprimer une IP bloqué
cscli decisions delete -i x.x.x.x

Il est possible d’aller bien plus loin, avant de blacklisté on peut demander un captcha à l’utilisateur : https://www.it-connect.fr/comment-proteger-son-site-wordpress-avec-crowdsec/ (pas mal…)

Ressources :

Bémols

Du fait de la « mutualisation » des blacklistes il y a de la data qui est envoyé chez un tiers… bon même si la société est Française le site est hébergé à San Francisco (mention légal) Typiquement le modèle économique est de récupérer de la data (les IP malveillantes) sur les « crowdsec community » pour détecter des intrusions et vendre des bases d’IP à bloquer aux autres… (note : ce partage vers l’API centrale est désactivable : FAQ / Troubleshooting | CrowdSec)

Le dashboard local est déprécié Cscli dashboard deprecation | CrowdSec au profil de l’APP en ligne crowdsec non open source pour le coup… (pour le coup c’est pas indispensable à l’usage de Crowdsec)

J’ai l’impression que le modèle économique se dessine et que ça se ferme un peu…

Toute proportion gardé bien sûr, on parle d’IP malveillante et non de data utilisateur… Je voudrais pas faire mon « libo-terroriste » hein :slight_smile:

Plugin Munin

Moi j’aime bien monitorer ce qui ce passe et comme le dashboard local Crowdsec n’est plus maintenu, a minima j’ai fais un plugin pour avoir des graph’ dans Munin :

Il permet d’avoir des graph’s par pays et par scénario.

Commande lumière pour percussion (DMX/Raspberry pi)

J’ai un petit groupe de musique dans lequel je fais de la percussion avec petit set Cajon + accessoires, pour faire une mini batterie transportable à vélo… Nous sommes amateurs ; j’ai rejoint le groupe en cours de route, et ils avaient collectivement acheté la table de mixage et la sono pour les concerts. De mon côté, je me suis dit que j’allais mettre au pot en achetant les lumières.

Un jour, à la déchetterie, j’ai trouvé 2 petits projecteurs LED RVB pilotables par DMX : « Algam Lighting SLIMPAR 710 HEX« . Ils étaient hors d’usage, mais après le passage entre les mains d’un ami magicien de l’électronique, ils ont ressuscités 🙂

Je me suis tout de même procuré une interface USB>DMX (Enttec Open DMX USB Interface Bundle) afin de pouvoir piloter mes jouets.

Les projecteurs LED RVB connectés en DMX via USB

Point consommation électrique

Consommation de la sono sur une répète

La consommation électrique est un point important. Nous avons une petite sono qui consomme ~60W de moyenne, avec des pics à 120W. Il nous arrive de jouer en « autonomie » (dans les bois par exemple) sur ma batterie de vélo 48V, avec un convertisseur 48V-350W de chez Victron. Celle-ci nous permet de tenir ~4h de concert sans problème (on a un set de ~1h alors on est large). Les 2 projecteurs LED consomment ~10W chacun, ce qui fait qu’on devrait pouvoir largement jouer notre concert, même avec les 2 projecteurs, même avec 3 rappels 🙂

Console DMX pour Cajon

Je me suis lancé dans la création d’une commande DMX pour mon Cajon. Afin de pouvoir jouer + commander les lumières par le protocole DMX.

Démonstration vidéo

Préparation lumière sur logiciel

Je suis parti sur le logiciel QLC+, qui est open source, plutôt complet (pour ce que j’ai à faire) et léger. J’ai l’ambition de faire tourner ma mini console sur un Raspberry pi. Dans QLC+, je peux préparer des séquences / ambiances par morceau, et passer d’une ambiance à une autre.

Par exemple, sur la capture ci-après – qui correspond au morceau « Tu veux ou tu veux pas », il y a plusieurs ambiances selon si c’est le moment de l’intro, du refrain, d’un solo…. J’utilise les cadres avec pagination pour « passer au morceau suivant ».

Je vous partage mon fichier qxf, qui permet au logiciel QLC+ de « comprendre » ces projecteurs. Je l’ai créé à partir de l’Éditeur d’appareil QLC+ (qlcplus-fixtureeditor) :

Je vous partage aussi mon fichier avec l’enchaînement des ambiances (un morceau par page) dans la console virtuel. Pour une meilleure compréhension…

Les commandes sur Cajon

Je décide qu’il me faut donc 4 boutons :

  • Pour passer à l’ambiance lumière suivante
  • Revenir à l’ambiance lumière précédente (en cas de pépin)
  • Passer à la page/morceau/séquence suivant
  • Taper la pulsation (s’il y a des ambiances qui « clignotent », je veux que celles-ci soient en rythme…). 2 tapes à intervalle suffisent à donner la pulsation, il ne reste qu’à la suivre…. A noter que la pulsation peut être détectée via un micro USB sur le Raspberry Pi avec le Audio Trigger dans QLC+. C’est ce que j’ai finalement privilégié…

Rapidement, je me rends compte qu’il me faudra doubler ces 4 commandes :

  1. 4 boutons accessibles aux mains (si j’ai les pieds occupés)
  2. 4 mêmes boutons accessibles aux pieds (si j’ai les mains occupées)…

Et oui, parce que ça dépend des morceaux… Parfois je fais du cabassa, parfois du cajon…

Voilà le schéma de câblage / branchement sur le Raspberry pi des boutons :

Schéma de câblage / branchement sur le Raspberry

Si vous suivez, vous voyez 3 boutons sur le schéma alors qu’il y en a 4… J’ai changé d’avis en cours de route, et j’ai pas changé mon schéma. Mais vous avez l’idée générale…

Une fois soudé, j’ai tout rangé dans des petites boîtes en chutes de contre plaqué ou autres qui traînaient :

Une fois que mes ambiances sont « calées », et que les connexions sont faites, je peux installer un linux (avec interface) sur un Raspberry pi. Désormais, il me faut faire en sorte que les boutons que j’ai connectés sur le GPIO du Raspberry interagissent avec QLC+.

Option 1 : websockets

Option très propre, puisque QLC+ intègre un websockets (moyennant le lancement avec un « -w » de QLC+) qui permet d’interagir avec le logiciel lancé en tâche de fond par script :

import asyncio
import websockets

async def test():
    async with websockets.connect('ws://127.0.0.1:9999/qlcplusWS') as websocket:
        # Play
        await websocket.send("2|PLAY")
        response = await websocket.recv()
        print(response)
 
asyncio.get_event_loop().run_until_complete(test())

Seulement, toutes les fonctionnalités des consoles virtuelles ne sont pas implémentées… Par exemple, je ne pouvais pas ajuster le tempo (Widget durée).

Option 2 : simuler un clavier

C’est l’option retenue, je simule l’appui sur une touche de clavier quand un bouton est pressé (signal GPIO d’un bouton poussoir). Je m’explique :

QLC+ peut facilement être piloté par clavier, les raccourcis sont facilement paramétrables. Ainsi, j’ai paramétré plusieurs raccourcis :

  • d : démarrer le séquenceur du morceau
    • f : stopper le séquenceur du morceau
    • q : ambiance suivante
    • s : ambiance précédente
  • z : page suivante (morceau suivant)
  • x : allumer le micro pour détecter le tempo
  • w : déterminer la durée (taper le tempo)

Ensuite, pour simuler mes touches de clavier en fonction des boutons pressés (GPIO activé), j’ai fait un petit script en python avec la librairie pyautogui qui simule un clavier, voici les dépendances :

sudo apt install python3-rpi.gpio
pip install pyautogui

Et voici le script

#-------------------------------------------------------------------------------
# Bibliothèques
#-------------------------------------------------------------------------------
import RPi.GPIO as GPIO                 #bibliothèque RPi.GPIO
import time                             #bibliothèque time
from pyautogui import press, typewrite, hotkey 	#clavier virtuel
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Configuration
#-------------------------------------------------------------------------------
pin1 = 17                                #broche utilisé en entrée
pin2 = 18                                #broche utilisé en entrée
pin3 = 27                                #broche utilisé en entrée
pin4 = 22                                #broche utilisé en entrée
pinLed = 23                              # Broche de la led
ledUpTime = 500                         # Temps d'allumage de la LED
# Temp de rebond : 
temps = 100                              #valeur attente en msec

#-------------------------------------------------------------------------------
# Préparation
#-------------------------------------------------------------------------------
GPIO.setwarnings(False)                 #désactive le mode warning
GPIO.setmode(GPIO.BCM)                  #utilisation des numéros de ports du
                                        #processeur
GPIO.setup(pin1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(pin2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(pin3, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(pin4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(pinLed, GPIO.OUT, initial=GPIO.LOW) 
                                        #mise en entrée du port GPIO 22
                                        #et activation résistance soutirage
                                        #au ground
# Passer sur Qlight+ si ce n'est pas le cas
print("alt tab")
hotkey('alt', 'tab')
time.sleep(3)                       

#-------------------------------------------------------------------------------
# Lancement
#-------------------------------------------------------------------------------
ledup=False
if __name__ == '__main__':
     GPIO.output(pinLed, GPIO.HIGH) # Turn on
     time.sleep(2)
     GPIO.output(pinLed, GPIO.LOW) # Turn off
     print("Début du programme")        #IHM
     print("Sortie par ctrl-c\n")       #IHM
     try:
         while True:                    #boucle infinie
             # Gestion de l'extinciton de la led
             if (ledup != False) :
                 now = time.time()
                 if (now < ledup+ledUpTime):
                     GPIO.output(pinLed, GPIO.LOW) # Turn off
                     ledup = False
             # Gestion des boutons
             entree1 = GPIO.input(pin1)   #lecture entrée
             entree2 = GPIO.input(pin2)   #lecture entrée
             entree3 = GPIO.input(pin3)   #lecture entrée
             entree4 = GPIO.input(pin4)   #lecture entrée
             if (entree1 == False):       #si touche appuyée
                 GPIO.output(pinLed, GPIO.HIGH) # Turn on
                 print("Press f (Stop séquence)")
                 press('f')
                 time.sleep(0.5)
                 print("BP 1 appuyé")     #IHM
                 print("Press z (Page suivant) - N")
                 press('z')
                 time.sleep(0.5)
                 print("Press d (Start séquence)")
                 press('d')
                 time.sleep(0.5)
                 print("Press x (Allumer le micro)")
                 press('x')
                 ledup = time.time()
             if (entree2 == False):       #si touche appuyée
                 GPIO.output(pinLed, GPIO.HIGH) # Turn on
                 ledup = time.time()
                 print("BP 4 appuyé - T")     #IHM
                 print("w (tape)")
                 press('w')
             if (entree3 == False):       #si touche appuyée
                 GPIO.output(pinLed, GPIO.HIGH) # Turn on
                 ledup = time.time()
                 print("BP 2 appuyé - P")     #IHM
                 print("Press q (Pas prédent)")
                 press('q')
                 time.sleep(0.5)
             if (entree4 == False):       #si touche appuyée
                 GPIO.output(pinLed, GPIO.HIGH) # Turn on
                 ledup = time.time()
                 print("BP 3 appuyé - S")     #IHM
                 print("s (Pas suivant)")
                 press('s') 
                 time.sleep(0.5)
             time.sleep(temps / 1000)   #attente en msec 
     except KeyboardInterrupt:          #sortie boucle par ctrl-c
         GPIO.cleanup()                 #libère toutes les ressources
         print("\nFin du programme\n")  #IHM

Pour le lancement, au démarrage du Raspberry, je place des fichiers « .desktop » dans le répertoire .config/autostart/ de l’utilisateur « pi » que j’utilise pour lancer l’interface graphique.

Le script qui simule le clavier est lancé avec .config/autostart/button-qlcplus-controle.desktop

[Desktop Entry]
Type=Application
Name=button-qlcplus-controle
GenericName=button
Exec=/usr/bin/python /home/pi/DMX/button-qlcplus-controle.py  > /tmp/button-qlcplus-controle.log
Terminal=true
StartupNotify=true

Pour le lancement de QLC+, c’est le fichier .config/autostart/qlcplus.desktop :

[Desktop Entry]
Type=Link
Name=Q Light Controller Plus Web
Icon=qlcplus
Exec=qlcplus -f -k -w -o DMX/fichierQLC.qxw
StartupNotify=false

Retour visuel

Même si c’est pas indispensable, pour savoir où on en c’est pratique d’avoir un retour visuel sur la console virtuelle de QLC+. Ce que j’ai fait, c’est que j’ai mis le Raspberry Pi en mode « Hotspot Wifi » (en gros, comme votre box – des tuto plein le web pour faire ça…), et je m’y connecte avec mon téléphone portable. De là, je peux :

  • Voir la console en mode web (lancer QLC+ avec un « -w »)
  • Voir l’écran avec VNC (sur un téléphone linux, j’utilise AVNC).

Voilà ce que ça donne :

En situation

Des photos en situation :

ISPconfig : migrer Mailman2 vers Sympa

Debian 11 ne supporte plus mailman2, et mailman2 n’est plus maintenu depuis… (trop longtemps) il était donc grand temps de changer d’outil pour les mailings liste… Oui mais voilà, mon panel c’est ISPconfig et celui-ci ne supporte pour le moment QUE mailman2 🙁 (pas de mailman3 ni de sympa prévu)

Pour l’instant mon serveur est en Debian 10, mais dans l’optique d’un migration vers Debian 11 il fallait avancer. Après avoir tester mailman3 je me suis dit qu’il était très lourd (en ressources serveurs) par rapport à mon besoin (il s’avère être dimensionné pour les gros système) de plus il c’est un jeune logiciel alors que Sympa a de la bouteille, sont développement est encore soutenu, il est léger et des scripts de migration existe, ça serait donc Sympa !

A noter que beaucoup migre vers Discourse qui ouvre d’autres possibilités.

Tant pi pour l’intégration dans le panel ISPconfig pour le moment.. Un jour peut être…

Installation

Installation de sympa

Sur mon serveur Debian 10 j’ai commencé par installer Sympa en parallèle de Mailman2 :

# Pour éviter une erreur dpkg
echo "retzo.net" > /etc/mailname
apt install sympa # dire non à toutes les questions apt... on s'en occupe après...

Ensuite je crée la base de donnée MySql « sympa » avec un utilisateur restreint.

SELECT PASSWORD('MOTDEPASSE');
# Récupérer le hash du mot de passe
CREATE USER 'sympa'@'localhost' IDENTIFIED VIA mysql_native_password USING '*F72C19A910531DA39D6EC7BB91BEB11A37753023'; 
GRANT USAGE ON *.* TO 'sympa'@'localhost' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
CREATE DATABASE IF NOT EXISTS `sympa`;
GRANT ALL PRIVILEGES ON `sympa`.* TO 'sympa'@'localhost';
FLUSH PRIVILEGES;

Modification de l’URL (j’aime pas /wws/ je préfère /sympa ) dans le fichier /etc/apache2/conf-enabled/sympa.conf

-    ScriptAlias /wws /usr/lib/cgi-bin/sympa/wwsympa-wrapper.fcgi
+    ScriptAlias /sympa /usr/lib/cgi-bin/sympa/wwsympa-wrapper.fcgi

Je modifie ensuite le fichier /etc/sympa/sympa/sympa.conf

- listmaster      listmaster@retzien.fr
+ listmaster      adresse-email-admin@retzo.net
- lang    en
+ lang    fr
- wwsympa_url     http://retzo.net/wws
+ wwsympa_url     http://lists.retzo.net/sympa
+ db_type        MySQL
+ db_host        localhost
+ db_port        3306
+ db_name        sympa
+ db_user        sympa
+ db_passwd      plvlOBpDuljmz0Dh

Je relance sympa pour qu’il crée les tables :

service sympa restart ; service apache2 restart

Lancer la commande suivante et lire les instructions selon votre cas

sympa_wizard --check

Pour ma part le check révèle surtout qu’il manque Data::Password

cpan install Data::Password

Intégration dans postfix (multi domaines)

Ensuite j’ai suivi la documentation pour les « multi-domaines » avec Postfix : https://sympa-community.github.io/manual/install/configure-mail-server-postfix.html#virtual-domain-setting

Pour la suite on va enter ces variables dans le terminal, ça nous simplifia la lecture :

SYSCONFDIR=/etc/sympa
EXPLDIR=/var/lib/sympa/list_data

Créer le fichier $SYSCONFDIR/list_aliases.tt2

#--- [% list.name %]@[% list.domain %]: list transport map created at [% date %]
[% list.name %]@[% list.domain %] sympa:[% list.name %]@[% list.domain %]
[% list.name %]-request@[% list.domain %] sympa:[% list.name %]-request@[% list.domain %]
[% list.name %]-editor@[% list.domain %] sympa:[% list.name %]-editor@[% list.domain %]
[% list.name %]-subscribe@[% list.domain %] sympa:[% list.name %]-subscribe@[%list.domain %]
[% list.name %]-unsubscribe@[% list.domain %] sympa:[% list.name %]-unsubscribe@[% list.domain %]
[% list.name %][% return_path_suffix %]@[% list.domain %] sympabounce:[% list.name %]@[% list.domain %]

Ajouter les lignes suivantes à la fin du fichier /etc/sympa/sympa/sympa.conf

sendmail_aliases /etc/sympa/sympa_transport
aliases_program postmap
aliases_db_type hash

Créer les fichiers qui vont bien :

touch $SYSCONFDIR/transport.sympa
touch $SYSCONFDIR/virtual.sympa
touch $SYSCONFDIR/sympa_transport
chmod 644 $SYSCONFDIR/sympa_transport
chown sympa:sympa $SYSCONFDIR/sympa_transport
postmap hash:$SYSCONFDIR/transport.sympa
postmap hash:$SYSCONFDIR/virtual.sympa
/usr/lib/sympa/bin/sympa_newaliases.pl
postmap hash:$SYSCONFDIR/sympa_transport
chmod 640 $SYSCONFDIR/sympa_transport $SYSCONFDIR/sympa_transport.db
chgrp postfix $SYSCONFDIR/sympa_transport $SYSCONFDIR/sympa_transport.db

Dans le fichier /etc/postfix/master.cf ajouter à la fin :

sympa   unix    -       n       n       -       -       pipe
flags=hqRu null_sender= user=sympa argv=/usr/lib/sympa/bin/queue ${nexthop}
sympabounce unix -     n       n       -       -       pipe
flags=hqRu null_sender= user=sympa argv=/usr/lib/sympa/bin/bouncequeue ${nexthop}

Modifier le fichier /etc/postfix/main.cf comme suite, supprimer ce qui est mailman au profil de sympa :

- alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases
- alias_database = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases
+ alias_maps = hash:/etc/aliases
+ alias_database = hash:/etc/aliases
- virtual_alias_maps = hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, proxy:mysql:/etc/postfix/mysql-virtual_alias_maps.cf, proxy:mysql:/etc/postfix/mysql-virtual_email2email.cf
- virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf
- virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf
+ virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, proxy:mysql:/etc/postfix/mysql-virtual_alias_maps.cf, proxy:mysql:/etc/postfix/mysql-virtual_email2email.cf, hash:/etc/sympa/virtual.sympa
+ virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf, hash:/etc/sympa/transport.sympa
+ virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf, hash:/etc/sympa/transport.sympa, hash:/etc/sympa/sympa_transport, hash:/etc/sympa/virtual.sympa
- transport_maps = hash:/var/lib/mailman/data/transport-mailman, proxy:mysql:/etc/postfix/mysql-virtual_transports.cf
---
+ transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf, hash:/etc/sympa/transport.sympa, hash:/etc/sympa/sympa_transport

Attention : cette modification sera a faire à chaque mise à jours d’ISPconfig si vous choisissiez de reconfigurez les services.

Si vous voulez que cette modification soit « incluse » dans ISPconfig, même après mise à jour il vous fait récupérer le fichier du répertoire d’installation qui correspond à votre distribution (chez moi Debian) : ispconfig3/install/tpl/debian_postfix.conf.master et le mettre dans /usr/local/ispconfig/server/conf-custom/install/ sur votre serveur et d’appliquer les mêmes changements que précédemment cité dans le main.cf.

Ajouter les domaines

Contrairement à ce qui est dans la documentation : https://sympa-community.github.io/manual/install/configure-mail-server-postfix.html#virtual-domain-setting dans « Adding new domain »

Si vous ajouter dans le fichier transport.sympa la ligne

mail.example.org                error:User unknown in recipient table

SI ce domaine contient des boîtes e-mails dans ISPconfig, celles-ci ne fonctionneront plus. Il est donc préférable, dans notre cas de ne pas ajouter cette ligne (sauf si ce le nom de domaine est uniquement fait pour les mailings listes)

Un petit script script bash qui liste les domaines présent dans mailman et qui crée les configurations pour Sympa :

cat /var/lib/mailman/data/virtual-mailman | egrep -v "^$|^#|mailman" | cut -d@ -f2 | cut -d" " -f1 | sort | uniq > /tmp/mailman_domaine_liste
SYSCONFDIR=/etc/sympa
EXPLDIR=/var/lib/sympa/list_data
while read -r line;
do
    echo $line
    mkdir -m 755 $SYSCONFDIR/$line
    touch $SYSCONFDIR/$line/robot.conf
    chown -R sympa:sympa $SYSCONFDIR/$line
    mkdir -m 750 $EXPLDIR/$line
    chown sympa:sympa $EXPLDIR/$line
    echo "http_host  lists.$line
listmaster adresse-email-admin@retzo.net
create_list  listmaster
wwsympa_url     http://lists.$line/sympa" > $SYSCONFDIR/$line/robot.conf
    echo "sympa@$line          sympa:sympa@$line
listmaster@$line     sympa:listmaster@$line
bounce@$line         sympabounce:sympa@$line
abuse-feedback-report@$line  sympabounce:sympa@$line" >>  $SYSCONFDIR/transport.sympa
    echo "sympa-request@$line  postmaster@retzo.net
sympa-owner@$line    postmaster@retzo.net" >>  $SYSCONFDIR/virtual.sympa
done < /tmp/mailman_domaine_liste
postmap hash:$SYSCONFDIR/transport.sympa
postmap hash:$SYSCONFDIR/virtual.sympa

Migration avec mailman2sympa

Il existe un script « mailman2sympa » : https://www.sympa.org/contribs/migration_and_archives/index#mailman2sympa après usage j’ai contribué à son amélioration (débugge) sur Github : https://github.com/LAKostis/mailman2sympa/pulls?q=is%3Apr+author%3Akepon85 le mainteneur du dépôt git n’est pas l’auteur du script : https://github.com/LAKostis/mailman2sympa/commit/f628cd2b968b2e1959f0e631e895b189e8110f1d

Quelques dépendances non satisfaite chez moi :

apt install jq libjson-perl procmail

Téléchargement du script :

cd ~
git clone https://github.com/LAKostis/mailman2sympa.git
cd mailman2sympa
mv conf/mailman2sympa.conf.debian conf/mailman2sympa.conf

Modifier le fichier conf/mailman2sympa.conf

- DOMAIN=''
+ DOMAIN="retzo.net"
- PASSWORDDB=""
+ PASSWORDDB="zXne&375"
- DEFAULT_OWNER=""
+ DEFAULT_OWNER="adresse-email-admin@retzo.net"

Puis lancer le script de migration :

rm -fr /tmp/mailman ; bash mailman2sympa.sh

Si, comme moi vous avez plusieurs domaine il vous faut recommencer en éditant conf/mailman2sympa.conf :

- DOMAIN="retzo.net
+ DOMAIN="autredomaine.net

Et relancer le script mailman2sympa.sh, boucler tant que vous avez des domaines à importer…

A propos des archives, à la fin, connectez vous http://lists.retzo.net/sympa/serveradmin/archives (utiliser « première connexion » la première fois) et lancer une reconstitution des archives

Enfin re-générer le fichier sympa_transport précisé dans la variable sendmail_aliases du fichier sympa.conf

root@srvmail:~# /usr/lib/sympa/bin/sympa.pl --make_alias_file
Sympa aliases file /var/spool/sympa/tmp/sympa_aliases.179676 was made.  You probably need to install it in your SMTP engine.
root@srvmail:~# cat  /var/spool/sympa/tmp/sympa_aliases.179676 > /etc/sympa/sympa_transport
root@srvmail:~# postmap /etc/sympa/sympa_transport

Désactiver mailman

Avant de le désinstaller on peut passer par une période de transition en désactivant l’interface par exemple, dans le fichier /etc/mailman/apache.conf

-ScriptAlias /cgi-bin/mailman/ /usr/lib/cgi-bin/mailman/
+RedirectPermanent /cgi-bin/mailman/ /sympa/

DKIM / DMARC

Pour sympa il y a pas mal de configuration DMARc/DKIM : https://www.sympa.org/doc/formation/sympa_avance

Pour que ça fonctionne avec ISPconfig il faut ajouter l’utilisateur « sympa » au groupe « amavis »

usermod -a -G amavis sympa

Ensuite dans les fichiers « robot.conf » (/etc/sympa/DOMAIN/robot.conf) il faut ajouter en fin de fichier :

dkim_feature on
dkim_private_key_path	/var/lib/amavis/dkim/retzo.net.private
dkim_signature_apply_on any
dkim_signer_domain	retzo.net
dkim_selector	default
dmarc_protection_mode dmarc_reject

Redirection de la page du panel ISPconfig

ISPconfig ne supoprte pas Sympa mais Mailman, pour éviter que des utilisateurs crée des listes mailman (et donc génère des erreurs) je redirige la page « Mailing list » du panel vers la documentation. Pour ça modifier la page /usr/local/ispconfig/interface/web/mail/templates/mail_mailinglist_list.htm

+ <script type="text/javascript">
+ window.location.href = "https://lists.retzo.net/";
+ </script>
+ 
+ <p>Cette page du panel n'est plus à utiliser, vous allez être rediriger vers la page de Sympa : <a href="https://lists.retzo.net/">https://lists.retzo.net/</a></p>
+ 
+ <!--
73c80
-     
---
+ -->

Service web pour alléger vos boîtes mails (télécharger une archive)

À quand remonte la dernière fois que vous avez eu besoin de lire cet e-mail du 15 septembre 2012 ? Ça fait longtemps n’est-ce pas ?

Préambule

Le stockage de ces e-mails n’est pas sans impact énergétique : en effet, les serveurs (gros ordinateurs) qui hébergent ces vieux e-mails sont allumés en permanence pour vous permettre, un jour peut-être, de relire cet e-mail du 15 septembre 2012 dont vous n’avez même plus le souvenir. Deux solutions peuvent s’offrir à vous pour diminuer cet impact :

  • Supprimer vos vieux e-mails, la solution la plus sobre, radicale ;
  • Archiver vos e-mails sur une clé USB / un disque dur externe, votre ordinateur ; en tout cas, un système d’archivage « froid », c’est-à-dire qui ne sera pas allumé en permanence.

Un service web et open source pour faire ça

Lighten Mailbox est une interface web qui permet de faire du ménage dans sa boîte mail. Ce ménage se fait soit en supprimant des vieux messages, soit en les téléchargeant au format EML ou HTML/TXT. La sélection des messages se fait par critère de date (début/fin), puis en sélectionnant les dossiers IMAP concernés.

Exemple d’utilisation : Télécharger et archiver (exemple de rendu) ces emails vieux de 2 ans en les enregistrant sur un disque dur externe, puis (quand vous vous êtes assuré de l’intégrité des données) supprimer ces messages.

Exemple d’index d’archive : https://lighten-mailbox.zici.fr/archive/example/ (utilisable hors ligne, dans un navigateur internet depuis une clé usb par exemple…)

Une vidéo vaut mieux que de grands discours :

Autoconfig (thunderbird) & Autodiscover (outlook) sur messagerie hébergé ISPconfig

Thunderbird et Outlook représente une grosse part de marché dans les clients de messagerie. Je m’occupe de plusieurs service de messagerie (pro, asso…) et il est bien commode pour les usagés que « ça tombe en marche » tout seul pour le paramétrage…

A savoir :

  • Thunderbird chercher les paramètres dans un XML sur http://autoconfig.votredomain.fr/mail/config-v1.1.xml
  • Outlook cherche l’enregistrement DNS _autodiscover._tcp.votredomain.fr l’url à contacter et ensuite récupère le XML : https://url_donner_dans_le_dns/Autodiscover/Autodiscover.xml

Du coup nous allons rassemblé ces 2 demandes avec un htaccess et un script PHP qui génère le bon format XML fonction de si c’est outlook our thunderbird qui demande…

Pour cela il faut :

  • Créer un site « autoconfig.votredomain.fr » (ou un alias si vous avez plusieurs site) et faire pointer l’enregistrement DNS bien sûr…
  • Créer l’enregistrement DNS SRV type :
    • _autodiscover._tcp.votredomain.fr. 3600 IN SRV 10 10 443 autoconfig.votredomain.fr.

Dans le site autoconfig.votredomain.fr il vous suffit de glisser 2 fichiers à la racine :

Fichier .htaccess contient :

RewriteEngine On
RewriteRule ^Autodiscover/Autodiscover.xml autoconfig-mail.php
RewriteRule ^mail/config-v1.1.xml autoconfig-mail.php

Fichier autoconfig-mail.php contient :

<?php

/*
By David Mercereau
Licence Beerware
*/

function extract_domain($domain) {
    if(preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $domain, $matches)) {
        return $matches['domain'];
    } else {
        return $domain;
    }
}

$domain = extract_domain($_SERVER['SERVER_NAME']);
$mailServeur='mail.'.$domain;

if (preg_match('/^\/mail\/config-v1\.1\.xml/', $_SERVER['REQUEST_URI'])) {
	header('Content-Type: text/xml');
    header('Content-Type: application/xml');
	?>
<clientConfig version="1.1">
	<emailProvider id="<?= $domain ?>">
	  <domain><?= $domain ?></domain>
	  <displayName><?= $domain ?></displayName>
	  <displayShortName><?= $domain ?></displayShortName>
	  <incomingServer type="imap">
		 <hostname><?= $mailServeur ?></hostname>
		 <port>143</port>
		 <socketType>STARTTLS</socketType>
		 <username>%EMAILADDRESS%</username>
		 <authentication>password-cleartext</authentication>
	  </incomingServer>
	  <outgoingServer type="smtp">
		 <hostname><?= $mailServeur ?></hostname>
		 <port>587</port>
		 <socketType>STARTTLS</socketType>
		 <username>%EMAILADDRESS%</username>
		 <authentication>password-cleartext</authentication>
	  </outgoingServer>
	  <documentation url="https://webmail.<?= $domain ?>">
		  <descr lang="fr">Connexion Webmail</descr>
		  <descr lang="en">Webmail connexion</descr>
	  </documentation>
	  <documentation url="http://projet.retzo.net/projects/hebergement/wiki">
		<descr lang="fr">Documentation</descr>
		<descr lang="en">Generic settings page</descr>
	  </documentation>
	</emailProvider>
</clientConfig>
	<?php
} else {
	// Outlook
	//get raw POST data so we can extract the email address
	$data = file_get_contents("php://input");
	preg_match("/\<EMailAddress\>(.*?)\<\/EMailAddress\>/", $data, $matches);

	//set Content-Type
	header('Content-Type: text/xml');
    header('Content-Type: application/xml');
	echo '<?xml version="1.0" encoding="utf-8" ?>'; 
	?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
   <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
	   <Account>
		   <AccountType>email</AccountType>
		   <Action>settings</Action>
		   <Protocol>
			   <Type>IMAP</Type>
			   <Server><?= $mailServeur ?></Server>
			   <Port>993</Port>
			   <DomainRequired>off</DomainRequired>
			   <LoginName><?php echo $matches[1]; ?></LoginName>
			   <SPA>off</SPA>
			   <SSL>on</SSL>
			   <AuthRequired>on</AuthRequired>
		   </Protocol>
		   <Protocol>
			   <Type>POP3</Type>
			   <Server><?= $mailServeur ?></Server>
			   <Port>995</Port>
			   <DomainRequired>off</DomainRequired>
			   <LoginName><?php echo $matches[1]; ?></LoginName>
			   <SPA>off</SPA>
			   <SSL>on</SSL>
			   <AuthRequired>on</AuthRequired>
		   </Protocol>
		   <Protocol>
			   <Type>SMTP</Type>
			   <Server><?= $mailServeur ?></Server>
			   <Port>587</Port>
			   <DomainRequired>off</DomainRequired>
			   <LoginName><?php echo $matches[1]; ?></LoginName>
			   <SPA>off</SPA>
			   <Encryption>TLS</Encryption>
			   <AuthRequired>on</AuthRequired>
			   <UsePOPAuth>off</UsePOPAuth>
			   <SMTPLast>off</SMTPLast>
		   </Protocol>
	   </Account>
   </Response>
</Autodiscover>
	<?php
}

?>

Des ressources :

Migration Plesk 18 > ISPconfig 3

Pour l’association le Retzien.fr (dont je fais parti) j’ai effectué une migration de Plesk 18 vers ISPconfig 3. Plesk avait été mis en œuvre avant mon arrivé car l’administrateur en place connaissait le produit. Mais c’est un produit payant, de plus en plus cher, et pour une association qui a du mal à avoir un équilibre financier c’était difficile à assumer. Plesk est très « beau » et user friendly mais en tant qu’administrateur système je le trouve plutôt opaque (on ne sais pas exactement ce qu’il fait, pas trop de respect des « us et coutumes » de Linux (position des fichiers de config…), ET CE N’EST PAS LIBRE !!!

ISPconfig est libre et propose un script de migration (ISPConfig Migration Toolkit) mais ne supporte pas les dernières versions de Plesk, car le chiffrement des mots de passe n’est plus compatible. Du coup j’ai dû bricoler… Ce bricolage est l’objet de cet article.

Note : ici il n’est question que de la partie mail/DNS et compte client, car c’est la seule fonctionnalité du serveur, les fonctions web n’ont pas été testées.

Installation ISPconfig + Migration Toolkit

Je ne détaille pas ici la procédure d’installation d’ISPconfig 3 et l’usage du « Migration Toolkit » qui sont déjà bien documentés, dans mon cas :

Suite à l’usage du « Migration toolkit », même si le Plesk source n’est pas supporté, je n’ai pas d’erreur mais j’ai plusieurs problèmes que je vais essayer de régler par différents scripts.

Préambules : Les scripts suivants utilisent l’API d’ISPconfig (il faut donc créer un utilisateur distant, dans Système/utilisateur distant). ils doivent donc les lancer depuis le serveur source (Plesk).

Authentification IMAP

Le problème

Il est impossible de se connecter au serveur avec les comptes IMAP. Le log dit :

Error: sql(xxxxxxx@retzien.fr,::1,<MdFia/2k3toAAAAAAAAAAAAAAAAAAAAB>): Invalid password in passdb: crypt() failed: Invalid argument

Effectivement le chiffrement en base est différent :

Mais on va s’en sortir en rusant, en effet Plesk ne crypte/ »hash » pas les mots de passe mais les chiffre :

  • Crypter / « hasher » : c’est convertir définitivement un chaîne (ici un mot de passe) en un code. Pour savoir si le mot de passe proposé pour l’authentification est bon il faut crypter / « hasher » le mot de passe et le comparer.
  • Chiffrer : c’est convertir une chaîne (le mot de passe ici) avec une clé, cette fonction est réversible, et qui détient la clé peut donc déchiffrer la chaîne (le mot de passe)
  • Plus d’info sur la différence ici

Les mots de passe dans Plesk sont donc « lisibles » pour qui possède la clé de déchiffrement (l’administrateur par exemple ou un hacker qui obtiendrait l’accès au serveur…)

Pour vous en persuader, lancez la commande ci après et vous obtiendrez un beau tableau 1er colonne « émail », 2ème « mot de passe en clair »

/usr/local/psa/admin/sbin/mail_auth_view

Mais pourquoi les mots de passes ne sont ils pas cryptés ?

Plesk propose le support de l’authentification « mot de passe chiffré ». Et cette fonctionnalité est de fait contrainte à avoir le mot de passe en clair sur le serveur car il faut pouvoir le déchiffrer.

Exemple de méthode d’authentification sous Thunderbird

ISPconfig ne supporte pas cette fonctionnalité, car qu’il considère que ce serait un trop gros trou dans la sécurité du serveur, et qu’avec le chiffrement de la connexion SSL/TLS ou START/TLS ce n’est pas nécessaire d’en remettre une couche.

Effet de bord important : si vos utilisateurs ont configurés leur client de messagerie en « mot de passe chiffré » il faudra leur faire modifier ce paramétrage (IMAP & SMTP)

De ce que je comprends, cette méthode d’authentification chiffrée avait sa place quand les serveur IMAP/SMTP ne proposait pas de chiffrement de connexion SSL/TLS ou START/TLS.

Les sources de ce que j’avance :

La solution

La solution consiste, sur le serveur Plesk à lancer le script ci-après qui :

  • Lance la commande Plesk « magique » pour voir les mots de passe déchiffrés
  • « Parse » le résultat… Se connecte à ISPconfig et change le mot de chaque boîte émail
<?php
 
/* 
 * licence Beerware
 * By David Mercereau : http://david.mercereau.info
 */
 
// Plan B : https://www.besuchet.net/2016/06/plesk-11-encrypted-hashed-password-authentication-php-on-psa-database/
 
// ISPconfig Remote Config
$CONFIG['remoteUser'] = 'retzien';
$CONFIG['remotePassword'] = 'XXXXXXXXXX';
$CONFIG['remoteSoapLocation'] = 'https://192.168.1.64:8080/remote/index.php';
$CONFIG['remoteSoapUri'] = 'https://192.168.1.64:8080/remote/';
$CONFIG['logfile'] = '/tmp/migration-email-password.log';
 
function toLog($txt, $level) {
	file_put_contents($GLOBALS['CONFIG']['logfile'],date("[j/m/y H:i:s]")." - ".$level." - $txt \r\n",FILE_APPEND);
	echo "[$level] $txt\n";
}
 
// Connexion to ISPconfig
$client = new SoapClient(null, array('location' => $CONFIG['remoteSoapLocation'],
	'uri'      => $CONFIG['remoteSoapUri'],
	'stream_context'=> stream_context_create(array('ssl'=> array('verify_peer'=>false,'verify_peer_name'=>false))),
	'trace' => 1));
 
// Login
if($session_id = $client->login($CONFIG['remoteUser'], $CONFIG['remotePassword'])) {
	toLog('Login Ok. Session ID:'.$session_id, 'info');
}
 
# Launch plesk command for auth view in plain text
exec('/usr/local/psa/admin/sbin/mail_auth_view', $out, $return);
if ($return == 0 || $out[0] == null){
	foreach ($out as $line) {
		$lineExplode = explode('|', $line);
		if (isset($lineExplode[1]) && isset($lineExplode[3])) {
			$email = str_replace(' ', '', $lineExplode[1]);
			$password = str_replace(' ', '', $lineExplode[3]);
			# Verification data
			if (filter_var($email, FILTER_VALIDATE_EMAIL) && $password != '') {				
				# mail_user_get
				try {
					$mail_user_get = $client->mail_user_get($session_id, array('email' => $email));
					if (count($mail_user_get) > 0) {
						# Update data
						$mail_user_get['password']=$password;
						$mail_user_get['move_junk']='y';
						$affected_rows = $client->mail_user_update($session_id, 0, $mail_user_get[0]['mailuser_id'], $mail_user_get);
						if ($affected_rows == 0) {
							toLog('No change for '.$email, 'error');
						} else {
							toLog('Ok for '.$email, 'info');
						}
					} else {
						toLog('email '.$email.' not present in ISPconfig', 'warn');
					}
				} catch (SoapFault $e) {
					echo $client->__getLastResponse();
					die('SOAP Error: '.$e->getMessage());
				}
			} 
		}
	}
}
 
if($client->logout($session_id)) {
	toLog('Logged out.', 'info');
}
 
?>

IMAP subscriptions

La souscription au dossier IMAP (le fait de voir ou non certains dossiers et/ou d’en cacher d’autres) n’a pas migré, donc si l’utilisateur avait ajouté un dossier IMAP, il ne le voyez plus sur le nouveau serveur, pourtant le dossier est bien là.. c’est fâcheux. Pour corriger ça, lancez ce petit script sur le Plesk (source) :

#!/bin/bash
target='root@192.168.1.64'
find  /var/qmail/mailnames/ -name subscriptions | while IFS=$'\n' read f ; do
	domain=$(echo $f | cut -d/ -f5)
	user=$(echo $f | cut -d/ -f6)
	echo ${user}@${domain}
	scp /var/qmail/mailnames/${domain}/${user}/Maildir/subscriptions ${target}:/var/vmail/${domain}/${user}/Maildir/
done

DKIM & Spam policy

Ce script ajoute une politique de spam “normal” (modifiable) et récupère les anciennes clefs DKIM générées par Plesk pour les appliquer dans ISPconfig. Ceci pour éviter d’avoir à retoucher au DNS pendant la migration (toujours à lancer depuis le Plesk) :

&lt;?php
 
/* 
 * licence Beerware
 * By David Mercereau : http://david.mercereau.info
 */
 
// ISPconfig Remote Config
$CONFIG['remoteUser'] = 'retzien';
$CONFIG['remotePassword'] = 'XXXXXXX';
$CONFIG['remoteSoapLocation'] = 'https://192.168.1.64:8080/remote/index.php';
$CONFIG['remoteSoapUri'] = 'https://192.168.1.64:8080/remote/';
$CONFIG['logfile'] = '/tmp/migration-email-password.log';
$CONFIG['DKIM-Selector'] = 'default';
$CONFIG['policy_id'] = 5;
$CONFIG['priority'] = 5;
 
function toLog($txt, $level) {
	file_put_contents($GLOBALS['CONFIG']['logfile'],date("[j/m/y H:i:s]")." - ".$level." - $txt \r\n",FILE_APPEND);
	echo "[$level] $txt\n";
}
 
// Connexion to ISPconfig
$client = new SoapClient(null, array('location' => $CONFIG['remoteSoapLocation'],
	'uri'      => $CONFIG['remoteSoapUri'],
	'stream_context'=> stream_context_create(array('ssl'=> array('verify_peer'=>false,'verify_peer_name'=>false))),
	'trace' => 1));
 
// Login
if($session_id = $client->login($CONFIG['remoteUser'], $CONFIG['remotePassword'])) {
	toLog('Login Ok. Session ID:'.$session_id, 'info');
}
 
$mail_domain_record = $client->mail_domain_get($session_id, array('active' => 'y'));
 
foreach ($mail_domain_record as $mail_domain) {
	# DKIM
	if (is_dir('/etc/domainkeys/'.$mail_domain['domain'])) {
		$getPrivateKey=file_get_contents('/etc/domainkeys/'.$mail_domain['domain'].'/'.$CONFIG['DKIM-Selector']);
		exec('openssl rsa -in /etc/domainkeys/'.$mail_domain['domain'].'/'.$CONFIG['DKIM-Selector'].' -pubout', $out, $return);
		if ($return == 0 || $out[0] == null){
			$getPublicKey='';
			foreach ($out as $line) {
				$getPublicKey.=$line."\n";
				//~ if (!preg_match('/^---/', $line))  {
					//~ $getPublicKeyDns.=$line;
				//~ }
			}
			$mail_domain['dkim'] = 'y';
			$mail_domain['dkim_selector'] = $CONFIG['DKIM-Selector'];
			$mail_domain['dkim_private'] = $getPrivateKey;
			$mail_domain['dkim_public'] = $getPublicKey;
			$affected_rows = $client->mail_domain_update($session_id, 0, $mail_domain['domain_id'], $mail_domain);
			if ($affected_rows == 0) {
				toLog('DKIM No change for '.$mail_domain['domain']. ' already exist ?', 'error');
			} else {
				toLog('DKIM Ok for '.$mail_domain['domain'], 'info');
			}
		}
	} else {
		toLog($mail_domain['domain'].' haven\'t got dkim key on plesk', 'warn');
	}		
	# Spam Policy add in domain 
	try {
		$client_id = 1;
		$params = array(
			'server_id' => 1,
			'priority' => $CONFIG['priority'],
			'policy_id' => $CONFIG['policy_id'],
			'email' => '@'.$mail_domain['domain'],
			'fullname' => '@'.$mail_domain['domain'],
			'local' => 'Y'
		);
		$affected_rows = $client->mail_spamfilter_user_add($session_id, $client_id, $params);
		toLog('Spam policy Ok for '.$mail_domain['domain'], 'info');
	} catch (SoapFault $e) {
		toLog('Spam policy no change for '.$mail_domain['domain']. ' already exist ?', 'error');
	}
}
 
if($client->logout($session_id)) {
	toLog('Logged out.', 'info');
}
 
?>

Les mailings lists

Les mailings lists ne sont pas migrées, pourtant c’est du « Mailman 2 » des 2 côtés donc ça ne devrait pas être très compliqué.

Ce script est à lancer depuis le Plesk en mode « CLI » (ligne de commande) et vous avez quelques paramètres à modifier au début.

Le script :

  • Liste les mailings lists avec la commande /var/lib/mailman/bin/list_lists
  • Les créer dans ispconfig
  • Donne les commandes rsync pour synchroniser les données (archives, paramètres…)
 <?php
 
/* 
 * licence Beerware
 * By David Mercereau : http://david.mercereau.info
 */
 
// ISPconfig Remote Config
$CONFIG['remoteUser'] = 'retzien';
$CONFIG['remotePassword'] = 'XXXXX';
$CONFIG['remoteSoapLocation'] = 'https://192.168.1.64:8080/remote/index.php';
$CONFIG['remoteSoapUri'] = 'https://192.168.1.64:8080/remote/';
$CONFIG['logfile'] = '/tmp/migration-email-password.log';
$CONFIG['clientId'] = 3;
 
function toLog($txt, $level) {
	file_put_contents($GLOBALS['CONFIG']['logfile'],date("[j/m/y H:i:s]")." - ".$level." - $txt \r\n",FILE_APPEND);
	echo "[$level] $txt\n";
}
 
// Connexion to ISPconfig
$client = new SoapClient(null, array('location' => $CONFIG['remoteSoapLocation'],
	'uri'      => $CONFIG['remoteSoapUri'],
	'stream_context'=> stream_context_create(array('ssl'=> array('verify_peer'=>false,'verify_peer_name'=>false))),
	'trace' => 1));
 
// Login
if($session_id = $client->login($CONFIG['remoteUser'], $CONFIG['remotePassword'])) {
	toLog('Login Ok. Session ID:'.$session_id, 'info');
}

# Launch plesk command for auth view in plain text
exec('/var/lib/mailman/bin/list_lists -b', $out, $return);
if ($return == 0 || $out[0] == null){
	foreach ($out as $line) {
			unset($host_name);
			unset($owner);
		exec('/usr/lib/mailman/bin/config_list -o /tmp/'.$line.' '.$line.' ; grep ^host_name /tmp/'.$line.' | cut -d"\'" -f2', $host_name, $return);
		exec('/usr/lib/mailman/bin/config_list -o /tmp/'.$line.' '.$line.' ; grep ^owner /tmp/'.$line.' | cut -d"\'" -f2', $owner, $return);
		try {
			$params = array(
				'server_id' => 1,
				'domain' => $host_name[0],
				'listname' => $line,
				'email' => $owner[0],
				'password' => 'temp123!'
			);
			$mailinglist_id = $client->mail_mailinglist_add($session_id, $CONFIG['clientId'], $params);
			toLog('Ok for '.$line.'@'.$host_name[0]);
		} catch (SoapFault $e) {
			toLog('SOAP Error: '.$line. ' - '. $e->getMessage(), 'error');
		}
	}
}
 
if($client->logout($session_id)) {
	toLog('Logged out.', 'info');
}
 
echo "Patienteez 5min que Ispconfig est tout ajouté puis : \n";
echo "for list in \$(/var/lib/mailman/bin/list_lists -b); do\n
	rsync -az --progress  /var/lib/mailman/archives/public/\$list/ root@192.168.1.64:/var/lib/mailman/archives/public/\$list/\n
	rsync -az --progress  /var/lib/mailman/archives/private/\$list/ root@192.168.1.64:/var/lib/mailman/archives/private/\$list/\n
	rsync -az --progress  /var/lib/mailman/archives/private/\${list}.mbox root@192.168.1.64:/var/lib/mailman/archives/private/\n
	rsync -az --progress  /var/lib/mailman/lists/\$list/ root@192.168.1.64:/var/lib/mailman/lists/\$list/\n
done\n";
 
?>

En sortie le script donne quelques commandes « rsync » à exécuter par un copier / coller direct dans le terminal du serveur source (Plesk) pour synchroniser les données (archives, paramètres…)

Ensuite sur le serveur decdestination (ISPconfig) lancez la commande :

/var/lib/mailman/bin/check_perms -f

Conclusion

La migration c’est bien passée, c’est transparent pour l’utilisateur, à part le problème de « mot de passe chiffré » à « mot de passe normal », qu’il faut faire changer avant la migration de préférence.

En continuant à utiliser le site, vous acceptez l’utilisation des cookies (au chocolat) Plus d’informations

Les cookies sont utilisés à des fin de statistique de visite du blog sur une plateforme indépendante que j'héberge moi même. Les statistiques sot faites avec un logiciel libre. Aucune information n'est redistribué à google ou autre. Je suis seul autorisé à lire ces informations

Fermer