• chevron_right

      Tipi – L’auto-hébergement facile

      news.movim.eu / Korben · Thursday, 24 August, 2023 - 07:00 · 2 minutes

    C’est aujourd’hui que prend fin votre calvaire d’avoir à installer et configurer manuellement chaque service auto-hébergé sur votre serveur perso.

    Grâce au logiciel open source Tipi, vous allez pouvoir profiter de plus de 120 applications préconfigurées et personnalisables. L’idée derrière ce projet est de démocratiser l’auto-hébergement, et je peux dire que c’est un succès.

    Le cœur de Tipi est un orchestrateur Docker, qui permet de lancer et gérer plusieurs services sur un seul serveur. N’ayez pas peur, il est conçu pour être accessible à tous, quelles que soient vos compétences techniques.

    Lorsque vous commencez à utiliser Tipi, vous êtes accueilli par une interface web sympathique qui vous permet de gérer très facilement tous vos services mais également d’en ajouter et de les paramétrer. Et si jamais vous vous sentez limité par les applications disponibles, pas d’inquiétude : L’app store inclus dans Tipi vous permettra de demander l’ajout de nouveaux services à la communauté.

    Pour vous donner un peu plus envie, voici un aperçu des différentes applications auto-hébergées que vous pouvez installer sur votre serveur. Il y a par exemple Adguard , un excellent bloqueur de publicités dont je vous ai déjà parlé, ou Bazarr , un gestionnaire de sous-titres pour les films et séries. Et bien sûr pour les développeurs, il existe même une interface Web pour Visual Studio Code appelée Code-Server . Avec Tipi, les possibilités sont nombreuses.

    Firefly III vous permettra par exemple de suivre vos dépenses et vos revenus en un seul endroit, sans partager vos informations financières avec des services tiers. J’ai également trouvé Gladys Assistant qui est un assistant personnel qui prend soin de votre vie privée tout en vous aidant à gérer votre domotique.

    D’autres outils incroyables pour la gestion et la synchronisation de fichiers, la gestion de tâches, la surveillance de serveurs, la gestion de médias, et bien plus encore sont également disponibles. Vous y trouverez aussi WikiJS , un wiki open source extensible, Tautulli , un compagnon pour Plex, et Resilio , une solution basée sur P2P pour la synchronisation et le partage de fichiers.

    Pour le tester, il y a également une démo ici . (user : user@runtipi.io / mdp : password)

    L’installation est facile . Il vous faudra un Linux du genre Ubuntu 18.04 LTS, Docker et le plugin Docker Compose. Ensuite, pour l’installer, il suffit de récupérer et lancer la dernière version avec la commande suivante :

    curl -L https://setup.runtipi.io | bash

    Et voilà ! A vous des tas d’applications auto-hébergées sans prise de tête. Tipi est un projet plutôt exceptionnel qui rend abordable l’auto-hébergement pour le plus grand nombre.

    Je vous encourage à l’essayer par vous-même. Vous trouverez plus d’infos par ici .

    • chevron_right

      Immich – La solution de sauvegarde auto-hébergée pour vos photos et vidéos

      news.movim.eu / Korben · Thursday, 3 August, 2023 - 07:00 · 2 minutes

    Il était une fois, un Développeur nommé Alex qui cherchait désespérément une solution de sauvegarde auto-hébergée pour ses photos et vidéos de son magnifique bébé. Mais Alex ne voulait pas mettre tout ça dans un cloud privé tenu par les GAFAM.

    Alors en bon geek, Alex a créé sa propre solution : Immich ! C’est une application mobile et web disponible sous licence MIT, axée sur la confidentialité, la collecte de « souvenirs » et bien sûr la facilité d’utilisation.

    Voyez ça comme un Google Photos mais en version auto-hébergeable. D’ailleurs l’une des grandes fonctionnalités d’Immich est la sauvegarde automatique de vos photos et vidéos directement depuis votre smartphone et votre ordinateur. Plus besoin de se soucier de tout perdre dans un crash de disque dur ! Immich gère tout pour vous.

    Aussi, si vous êtes un(e) passionné(e) de photographie, vous serez encore plus joyeux puisqu’il prend même en charge les formats RAW ! Vous pouvez également rechercher des images en utilisant des métadonnées, des noms d’objets, des visages, et même CLIP dont je vous ai déjà parlé. Impressionnant, non ?

    Si vous avez un appareil Android ou iOS , vous pouvez récupérer l’appli mobile.

    Docker Compose est la méthode recommandée pour exécuter Immich en production donc créez un répertoire de votre choix pour y mettre les fichiers docker-compose.yml et .env.

    Ensuite, placez-vous dans le répertoire que vous avez créé et récupérez ces fichiers à l’aide des commandes suivantes :

    wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
    wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

    Vous pouvez aussi les récupérer à la main depuis votre navigateur. Renommez le fichier example.env en .env et éditez la pour modifier les valeurs concernant la base de données et l’emplacement où seront stockés les fichiers…etc.

    Enfin, lancez le docker-compose comme ceci :

    docker-compose up -d

    Et pour récupérer les dernières mises à jour de Immich, utilisez cette commande :

    docker-compose pull && docker-compose up -d

    Pour vous aider à en savoir plus, je vous invite à consulter la documentation officielle et pourquoi ne pas jeter un coup d’œil à la démo . Notez cependant que l’application est encore en développement, alors ne la considérez pas comme l’unique moyen de stockage pour vos photos et vidéos. Les backups c’est comme les billets de 100 €, c’est mieux quand y’en a plusieurs !

    À découvrir ici .

    • chevron_right

      Organisez vos comics, magazines et livres avec Komga

      news.movim.eu / Korben · Sunday, 2 April, 2023 - 07:00 · 1 minute

    Si vous cherchez un bon moyen d’auto-héberger vos magazines, vos livres et bandes dessinées, ne cherchez plus, Komga est la solution !

    Si les comics vous intéressent et que vous avez tout ça au format numérique, c’est forcement un peu galère pour organiser tout ça et s’y retrouver. Grâce à Komga vous pourrez vous sortir de ce pétrin et créer des bibliothèques pour vos BDs afin d’organiser totalement vos collections.

    Komga est donc un serveur de comics / mangas open source et gratuit. Vous pouvez même y mettre vos magazine PDF ou vos livres. Il supporte les formats epub, pdf, cbz et cbr et une fois en place, vous profiterez d’une jolie d’une interface web responsive.

    Organisez vos comics avec Komga

    Vous pourrez ainsi organiser votre bibliothèque avec des collections et des listes de lecture, et même modifier les métadonnées de vos séries de BDs et de vos livres. Komga permet également d’importer automatiquement les métadonnées intégrées à ces fichiers et vous pouvez tout lire sans quitter votre navigateur via le lecteur web.

    Gérez vos magazines avec Komga

    D’ailleurs plusieurs modes de lecture sont dispo et vous pouvez même gérer plusieurs users avec un contrôle d’accès par bibliothèque, mais également des restrictions d’âge.

    En plus de cela, il dispose d’une API REST et de nombreux outils et scripts développés par la communauté qui sont capables d’interagir avec Komga.

    Vous pourrez, d’un clic, télécharger les fichiers à l’unité ou des séries entières de BDs entières et si vous avez des petits soucis de mémoire lors de vos imports, l’outil est également capable de détecter les fichiers en double et même les pages en double. Komga peut également importer automatiquement les BDs déposées dans un répertoire.

    Stockez vos livres avec Komga

    Le plus beau là-dedans, c’est que ça s’installe très facilement avec Docker Compose, ou lancé directement via le .jar fourni (java). Donc vous l’aurez compris, ça peut tourner sur un Windows, un Linux mais également un NAS.

    Si vous voulez tester par vous-même, une démo est accessible ici : https://demo.komga.org/

    • Login: demo@komga.org
    • Password: komga-demo
    • chevron_right

      Comment suivre les performances de votre connexion internet avec Speedtest Tracker ?

      news.movim.eu / Korben · Sunday, 19 March, 2023 - 08:00

    Aujourd’hui, je vous propose de jeter un coup d’oeil à une nouvelle application trop cool à auto-héberger baptisée simplement Speedtest Tracker .

    Alors c’est quoi ce truc ? Eh bien, c’est une application de suivi des performances de votre connexion Internet qui lance à interval régulier, des mesures de vitesse via le service Speedtest d’Ookla.

    Alors pourquoi l’utiliser ?

    Et bien son objectif, c’est de constituer un historique des performances de votre connexion Internet, afin que vous puissiez être immédiatement informé lorsque vous n’êtes pas aux débits annoncés par votre fournisseur d’accès.

    Si ça vous intéresse, je vous invite à prendre connaissance de la documentation ici où tout est expliqué sur comment on installe ça. Vous verrez, c’est hyper simple puisque ça utilise Docker.

    C’est un outil vraiment pratique pour tous ceux qui veulent suivre les performances de leur connexion Internet au fil du temps et je me suis dit que ça vous intéresserait.

    Amusez-vous bien !

    • At chevron_right

      La virtu pour les nuls : le stockage

      raspbeguy · pubsub.gugod.fr / atomtest · Sunday, 26 January, 2020 - 23:00 · 24 minutes

    Mise en garde : cet article va être très long, car j'ai pensé qu'il serait intéressant d'exposer ma démarche complète pour la conception de mon infrastructure, et de présenter aussi non seulement ce que j'ai mis en place, mais également ce que je n'ai pas retenu. En plus on va parler de plein de tec...

    Mise en garde : cet article va être très long, car j'ai pensé qu'il serait intéressant d'exposer ma démarche complète pour la conception de mon infrastructure, et de présenter aussi non seulement ce que j'ai mis en place, mais également ce que je n'ai pas retenu. En plus on va parler de plein de technos différentes donc vous n'êtes pas obligé de tout lire si vous voulez. D'un autre côté vous êtes toujours libre de faire ce que vous voulez donc je sais pas de quoi je me mêle.

    L'introduction reste générale, objective, et pose les contraintes, la première partie expose la solution choisie, et la deuxième partie aborde la mise en œuvre.

    Comme tout ingénieur système sain d'esprit, j'aime bien les infrastructures qui ont de la gueule. Par là, j'entends une infra qui soit à l'épreuve de trois fléaux :

    • Le temps : Les pannes étant choses fréquentes dans le métier, les différents éléments de l'infrastructure, tant matériels que stratégiques, doivent pouvoir être facilement et indépendamment ajoutés, remplacés ou améliorés.
    • L'incompétence : Les opérateurs étant des êtres humains plus ou moins aguerris, le fonctionnement de l'infrastructure doit être le plus simple possible et sa maintenance doit réduire au maximum les risques d'erreurs de couche 8.
    • L'utilisation : Personne ne doit être en mesure d'utiliser l'infrastructure d'une façon ou dans un objectif non désiré par ses concepteurs. C'est valable pour certains utilisateurs finaux qui tenteraient d'exploiter votre œuvre dans un but malveillant, aussi bien que d'éventuels changements d'équipe qui ne comprend rien à rien (cf. les dangers de l'incompétence).

    Risques de Corona

    J'aurais pu aussi préciser que votre infrastructure doit également être à l'épreuve du coronavirus, mais pas grand risque de ce côté là, quoiqu'il ne faille pas confondre avec la bière Corona, qui, si renversée négligemment sur un serveur, peux infliger des dégâts regrettables.

    Concrètement, dans le cadre d'un cluster de virtualisation, ça se traduit par quelques maximes de bon sens :

    • On fait en sorte qu'une VM puisse être exécutée sur n'importe quel hyperviseur.
    • N'importe quel opérateur doit être en mesure d'effectuer des opérations de base (et de comprendre ce qu'il fait) sans corrompre le schmilblick, à toute heure du jour ou de la nuit, à n'importe quel niveau de sobriété, et s'il est dans l'incapacité physique, il doit pouvoir les expliquer à quelqu'un qui a un clavier et qui tient debout.
    • La symphonie technologique (terme pompeux de mon cru pour désigner les différentes technos qui collaborent, s'imbriquent et virevoltent avec grâce au grand bal des services) doit s'articuler autour de technos et protocoles indépendants, remplaçables, robustes et s'appuyant les uns sur les autres.

    Que de belles résolutions en ce début d'année, c'est touchant. Alors pour retomber sur terre, on va parler du problème épineux de l'unicité des instances de VM.

    Et bien oui, le problème se pose, car dans un cluster, on partage un certain nombre de ressources, ça tombe sous le sens. Dans notre cas, il s'agit du système de stockage. Comme on l'a déjà évoqué, chaque nœud du cluster doit pouvoir exécuter n'importe quelle VM. Mais le danger est grand, car si on ne met pas en place un certain nombre de mécanismes de régulation, on risque d'exécuter une VM à plusieurs endroit à la fois, et c'est extrêmement fâcheux. On risque de corrompre d'une part les systèmes de fichiers de la VM concernée, ce qui est déjà pénible, mais en plus, si on effectue des modifications de la structure de stockage partagé à tort et à travers, on risque d'anéantir l’ensemble du stockage du cluster, ce qui impactera l'ensemble du service. C'est bien plus que pénible.

    La solution de stockage

    La virtualisation

    L'outil de gestion de machines invitées que je préfère est libvirt, développé par les excellents ingénieurs de Redhat. À mon sens c'est le seul gestionnaire de virtualisation qui a su proposer des fonctionnalités très pratiques sans se mettre en travers de la volonté de l'utilisateur. Les commandes sont toujours implicites, on sait toujours ce qui est fait, la documentation est bien remplie, les développeurs sont ouverts, et surtout, libvirt est agnostique sur la gestion des ressources, c'est à dire qu'il manipule des concepts simples qui permettent à l'opérateur de le coupler à ses propres solutions avec une grande liberté.

    Voici une liste d'autres solutions, qui ne me correspondent pas :

    • Proxmox : Il s'agit d'une de ces solutions qui misent sur le tout-en-un, et donc contraire à l'approche KISS. Cela dit, son approche multi-utilisateurs est très intuitive surtout quand on a pas de compétences poussées en virtualisation, du fait de la présence d'une interface web intuitive. Il s'agit d'une solution satisfaisante lorsqu'on souhaite utiliser un unique nœud mais dès lors qu'on construit un cluster, Proxmox fait intervenir des élément très compliqués qui peuvent vite se retourner contre vous lors de fausses manipulations qui peuvent vous sembler bénignes. De ce fait, sa difficulté d'utilisation et de maintenance augmente de façon spectaculaire, et c'est ce contraste que je lui reproche.
    • oVirt : Il s'agit d'une solution également développée par Redhat, avec interface web conne proxmox et beaucoup (peut-être trop) de fonctionnalités, et qui utilise libvirt pour faire ses opérations. Cependant, comme j'ai du mal à voir ce qui est fait sous le capot, j'ai décidé de ne pas l'utiliser.
    • Virtualbox : Du fait de l'omniprésence et de la disponibilité des tutoriels sur Virtualbox, cela aurait semblé être une bonne solution. Mais il y a plusieurs problèmes : en premier lieu cette solution a été conçue principalement autour de son interface graphique, et son interface en ligne de commande est assez pauvre. Ensuite, par Virtualbox on parle d'une part de l'outil de gestion de VM, mais également du moteur d'exécution lui même. Ce moteur nécessite l'installation d'un module tiers dans le noyau du système, et je préfère éviter cette pratique.
    • VMware : Non là je trolle. #Sapucépalibre

    Sous linux, la solution la plus logique pour faire de la virtualisation est QEMU + KVM. Comme je l'ai évoqué, il existe aussi le moteur Virtualbox que j'ai exclu pour les raisons que vous connaissez. On aurait pu aussi s'éloigner de la virtualisation au sens propre et se tourner vers des solutions plus légères, par exemple la mise en conteneurs de type LXC ou Docker.

    Les conteneurs sont de petits animaux très gentils avec un petit chapeau sur la tête pour pouvoir se dire bonjour. Et ils sont très, très intelligents.

    Les conteneurs sont très utiles lorsqu'il s'agit de lancer des programmes rapidement et d'avoir des ressources élastiques en fonction de l'utilisation. L'avantage des conteneurs est qu'ils sont très réactifs en début et en fin de vie, pour la simple raison qu'ils ne possèdent pas de noyau à lancer et donc ses processus sont directement lancés par l'hôte. En revanche, je compte lancer des machines virtuelles complètes, dotées de fonctions propres, parfaitement isolées de l'hôte, et qui vont durer pendant de longues périodes. Pour des services qui doivent durer, les conteneurs n'apportent rien d'autre que des failles de sécurité. Mais bon, c'est à la mode, vous comprenez...

    Bon c'est entendu, partons sur libvirt ne demande pas grand chose pour lier une machine virtuelle à son stockage, ce qui fait qu'il est compatible avec beaucoup de façons de faire. En particulier, si votre stockage se présente sous la forme d'un périphérique en mode block dans votre /dev, libvirt saura en faire bon usage.

    Le partitionnement

    Au plus haut niveau pour le stockage des VM, je me suis tourné naturellement vers LVM. C'est la solution par excellence quand on cherche à gérer beaucoup de volumes modulables et élastiques, avec de très bonnes performances. Besoin d'un nouveau volume ? Hop, c'est fait en une commande. Le volume est trop petit ? Pas de problème, LVM peut modifier la taille de ses partitions sans avoir à s'inquiéter de la présence d'autres partitions avant ou après, LVM se débrouille comme un chef.

    LVM s'articule autour de trois notions :

    • Les LV (logical volumes) : Les partitions haut niveau qui seront utilisées par les VM.
    • Les VG (volumes groups) : un VG est une capacité de stockage sur laquelle on va créer des LV.
    • Les PV (physical volumes) : Les volumes qui sont utilisés pour créer des VG. Un VG peut utiliser plusieurs PV, en addition ou en réplication, de façon similaire au RAID.

    Par défaut, un VG est local, c'est à dire conçu pour n'être utilisé que sur une seule machine. Ce n'est pas ce qu'on souhaite. On souhaite un VG commun à tous les nœuds, sur lequel se trouvent des LV qui, on le rappelle, ne sont utilisés que par un seul nœud à la fois. LVM nous permet de créer un tel VG partagé, en ajoutant un système de gestion de verrous.

    Là encore, il y a beaucoup de façons de faire. Moi, je cherchais un moyen qui ne m'impose pas de mettre en place des technos qui sont très mises en valeur dans la littérature mais sur lesquelles je me suis cassé les dents, à l'installation comme au dépannage. Typiquement, je refusais catégoriquement de donner dans du Corosync/Pacemaker. J'ai déjà joué, j'ai perdu, merci, au revoir. Un jour peut-être vous vanterai-je dans un article les bienfaits de Corosync lorsque j'aurai compris le sens de la vie et obtenu mon prix Nobel de la paix. Ou bien depuis l'au-delà lors du jugement dernier lorsque les bons admins monterons au ciel et les mauvais descendront dans des caves obscures pour faire du Powershell ou se faire dévorer par les singes mutants qui alimentent en entropie les algorithmes de Google. En attendant, j'y touche pas même avec un bâton.

    Une technique qui m'a attiré par sa simplicité et son bon sens fait intervenir la notion de sanlock : plutôt que de mettre en place une énième liaison réseau entre les différents nœuds et de paniquer au moindre cahot, on part du principe que de toute façon, quelle que soit la techno de stockage partagé utilisé, les nœuds ont tous en commun de pouvoir lire et écrire au mème endroit. Donc on va demander à LVM de réserver une infime portion du média pour y écrire quelles ressources sont utilisées, et avec quelles restrictions. Ainsi, les nœuds ne se marchent pas sur les câbles. Moi ça m'allait bien.

    Une photo de groupe de l'équipe admin de mon ancien travail. On venait de changer de locaux.

    D'ailleurs, à ce niveau de l'histoire, je dois dire que je ne suis pas peu fier. En effet, pour mettre au point cette infrastructure, j'ai été inspiré en grande partie par l'infrastructure utilisée dans une de mes anciennes entreprises, dans laquelle j'avais la fonction de singe savant, et je ne comprenais pas (et ne cherchais pas à comprendre) le fonctionnement de mon outil de travail. Après mon départ, quand j'ai cherché à comprendre, j'ai entretenu une correspondance courriel avec un de mes anciens référents techniques, qui a conçu cette infra et pour qui j'ai toujours eu beaucoup de respect.

    Je lui avais demandé des infos sur le sanlocking, ce à quoi il m'a répondu :

    Quand j'ai testé le sanlocking ça avait fonctionné, mais je suis pas allé plus loin. Mais ici on gère vraiment le locking à la main.

    En effet, les VG de stockages étaient de simples VG locaux. Les métadonnées étaient individuellement verrouillées localement sur chaque nœud, et dès lors qu'on voulait provisionner une nouvelle VM, on devait lancer un script qui déverouillait les métadonnées sur le nœud de travail. Du coup, rien n'empêchait un autre nœud de faire la même chose, au risque d'avoir des modifications concurrentes et la corruption de l'univers. Donc, on était obligé de hurler à la cantonade dans l'open space dès qu'on touchait à quoi que ce soit. Si on avait de l'esprit, on aurait pu parler de screamlock à défaut de sanlock. De la même façon, on risquait à tout moment de lancer des VM à deux endroits à la fois !

    En fait on passe petit à petit sur oVirt pour gérer ce cas là. Aujourd'hui sur notre cluster KVM "maison", rien ne nous empêche de démarrer x fois la même machine sur plusieurs hôtes et de corrompre son système de fichiers 😕️ C'est une des raisons de la bascule progressive vers oVirt.

    Donc je suis fier de ne pas avoir eu à passer à oVirt pour faire ça. Libvirt est suffisamment simple et ouvert pour nous laisser faire ce qu'on veut et c'est ce que j'aime.

    Le partage

    Quel PV doit-on choisir pour notre cluster ? Il nous faut un machin partagé, d'une manière ou d'une autre. J'ai envisagé au moins trois solutions :

    • Un LUN iSCSI depuis un SAN (aka. la solution optimale) : Un SAN est un serveur de stockage mettant à disposition des volumes (appelés LUN). Le stockage est donc géré par des appareils dédiés, qui se fichent complètement de la façon dont on utilise ses volumes ni sur combien de nœuds. Le SAN ne sait pas si ses volumes contiennent des systèmes de fichiers, et il ne bronchera pas du tout si vous corrompez leur contenu parce que vous êtes pas fichu de vous organiser. Le soucis avec les SAN, c'est leur coût qui fait souvent dans les cinq chiffres...
    • Une réplication DRBD multimaster (aka. la solution du pauvre) : Si vous êtes comme moi et que les brousoufs ne surpopulent pas votre compte en banque, vous pouvez vous limiter à utiliser le stockage local de vos nœuds, que vous mettez en réplication multimater DRBD. De cette façon, chaque modification du volume sera instantanément répercuté sur l'autre nœud. L'avantage de cette solution est que le stockage est local, donc pour les accès en lecture on ne génère pas de trafic réseau. D'autre part, on a de facto une réplication de l'ensemble des données en cas de panne d'un nœud. Le soucis avec DRBD, c'est qu'il ne supporte, pour l'instant, que deux nœuds. D'un autre côté, comme on est pauvre, on a difficilement plus de deux nœuds de toute façon, mais cela empêche une mise à l'échelle horizontale dans l'immédiat. On peut se consoler en planifiant qu'on pourra passer sans trop d'efforts à la solution SAN quand les finances seront propices.
    • D'autres protocoles plus lourds comme Ceph qui vous promettent la lune et des super fonctions haut niveau (aka. la mauvaise solution) : Attention danger, on rentre dans l'effroyable empire des machines à gaz : on sait pas trop ce que ça fait, ça bouffe des ressources sans qu'on sache pourquoi, et quand ça foire, si on a pas passé sa vie à en bouffer, on peut rien faire. Déjà, Ceph est une solution mise en avant par Proxmox, donc il y a déjà matière à se méfier. En plus, les fameuses fonctions haut niveau, comme le partitionnement, le modèle qu'on a choisit nous pousse à le gérer avec autre chose, ici LVM. Donc merci, mais non merci.

    Notez que peu importe la solution que vous choisirez, comme il s'agit de stockage en réseau, il est fortement recommandé d'établir un réseau dédié au stockage, de préférence en 10 Gbps. Et malheureusement, les cartes réseau et les switchs 10 Gbps, c'est pas encore donné.

    Schéma récapitulatif

    La mise en œuvre

    Lors de la phase de conception, on est parti du besoin haut niveau pour descendre au contraintes matérielles. Pour la mise en œuvre, on va cheminer dans l'autre sens.

    DRBD

    Comme je vous l'ai avoué, d'un point de vue budget infrastructure, j'appartiens à la catégorie des pauvres. J'ai donc du me rabattre sur la solution DRBD.

    Sur chacun de mes deux nœuds, je dispose de volumes de capacité identique, répondant au nom de /dev/sdb.

    Après avoir installé DRBD, il faut créer sur chacun des nœuds la ressource associés à la réplication, qu'on va nommer r0.

    # /etc/drbd.d/r0.res
    
    resource r0 {
        meta-disk internal;
        device /dev/drbd0;
        disk /dev/sdb;
    
        syncer { rate 1000M; }
            net {
                    allow-two-primaries;
                    after-sb-0pri discard-zero-changes;
                    after-sb-1pri discard-secondary;
                    after-sb-2pri disconnect;
            }
        startup { become-primary-on both; }
    
        on node1.mondomaine.net { address 10.0.128.1:7789; }
        on node2.mondomaine.net { address 10.0.128.2:7789; }
    }

    Quelques explications :

    • /dev/sdb est le périphérique de stockage qui va supporter DRBD.
    • /dev/drbd0 sera le volume construit par DRBD
    • Les noms des nœuds doivent correspondre au nom complet de l'hôte (défini dans /etc/hostname) et ne pointe pas obligatoirement vers l'adresse IP précisée, qui est souvent dans un réseau privé dédié au stockage.

    Une fois que c'est fait, on peut passer à la création de la ressource sur les deux machines :

    drbdadm create-md r0
    systemctl enable --now drbd

    DRBD va ensuite initier une synchronisation initiale qui va prendre pas mal de temps. L'avancement est consultable en affichant le fichier /proc/drbd. À l'issue de cette synchronisation, vous constaterez que l'un des nœuds est secondaires. On arrange ça par la commande drbdadm primary r0 sur les deux hôtes (normalement uniquement sur l'hôte secondaire mais ça mange pas de pain de le faire sur les deux).

    LVM

    On a besoin d'installer le paquet de base de LVM ainsi que les outils pour gérer les verrous.

    apt install lvm2 lvm2-lockd sanlock

    La page du manuel de lvmlockd est extrêmement bien ficelée mais je sens que je vais quand même devoir détailler sinon ce serait céder à la paresse. On va donc reprendre les étapes de la même façon que la documentation.

    On prends conscience que c'est bien le type sanlock qu'on veut utiliser. L'autre (dlm) est presque aussi nocive que Corosync.

    Dans le fichier /etc/lvm.conf on modifie :

    use_lvmlockd = 1
    locking_type = 1

    Sur la version de LVM de la Debian actuelle (Buster), le paramètre locking_type est obsolète et n'a pas besoin d'être précisé.

    Ne pas oublier de donner un numéro différent à chaque hôte dans le fichier /etc/lvm/lvmlocal.conf dans la rubrique local dans le paramètre host_id.

    On active sur chaque hôte les services qui vont bien :

    systemctl enable --now wdmd sanlock lvmlockd

    On crée le VG partagé virtVG (sur un seul nœud) :

    vgcreate --shared virtVG /dev/drbd0

    Puis enfin on active le VG sur tous les hôtes :

    vgchange --lock-start

    Vous pouvez dès à présent créer des LV. Pour vérifier que votre VG est bien de type partagé, vous pouvez taper la commande vgs -o+locktype,lockargs. Normalement vous aurez un résultat de ce genre :

      VG     #PV #LV #SN Attr   VSize   VFree   LockType VLockArgs    
      virtVG   1   2   0 wz--ns 521,91g 505,66g sanlock  1.0.0:lvmlock

    Dans la colonne Attr, le s final signifie shared, et vous pouvez voir dans la colonne LockType qu'il s'agit bien d'un sanlock.

    Pour créer un LV de 8 Go qui s'appelle tintin :

    node1:~# lvcreate -L 8g virtVG -n tintin
      Logical volume "tintin" created.
    node1:~# lvs
      LV     VG     Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      prout  virtVG -wi------- 8,00g                                                    
      test   virtVG -wi------- 8,00g                                                    
      tintin virtVG -wi-a----- 8,00g

    Le a de la commande Attr indique que le volume est activé. C'est sur cette notion d'activation qu'on va pouvoir exploiter le verrou. Pour en faire la démonstration, rendez-vous sur un autre hôte (on n'a qu'un seul autre hôte comme on est pauvre).

    node2:~# lvs
      LV     VG     Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      prout  virtVG -wi------- 8,00g                                                    
      test   virtVG -wi------- 8,00g                                                    
      tintin virtVG -wi------- 8,00g

    Notez que tintin n'est pas activé ici, et on a d'ailleurs tout fait pour que l'activation n'ait lieu que sur un seul nœud à la fois. Voyons ce qui se passe si on essaye de l'activer :

    node2:~# lvchange -ay virtVG/tintin
      LV locked by other host: virtVG/tintin
      Failed to lock logical volume virtVG/tintin.

    Cessez les applaudissements, ça m'embarrasse. Donc, pour l'utiliser sur le deuxième nœud il faut et il suffit de le désactiver sur le premier.

    node1:~# lvchange -an virtVG/tintin
    node1:~# lvs
      LV     VG     Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      prout  virtVG -wi------- 8,00g                                                    
      test   virtVG -wi------- 8,00g                                                    
      tintin virtVG -wi------- 8,00g

    Et sur le deuxième on retente :

    node2:~# lvchange -ay virtVG/tintin
    node2:~# lvs
      LV     VG     Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      prout  virtVG -wi------- 8,00g                                                    
      test   virtVG -wi------- 8,00g                                                    
      tintin virtVG -wi-a----- 8,00g

    Magie. Quand un volume est activé, libre à vous d'en faire un système de fichier, de le monter, de faire un dd dessus... Tous ce dont vous aurez besoin c'est du chemin du périphérique /dev/virtVG/tintin. Le plus probable dans le cadre de la virtualisation est qu'il va y être déployé une table de partition MBR ou GPT, auquel cas il faudra, si un jour vous souhaitez explorer ce LV autrement que depuis la VM, lire sa table de partition avec kpartx.

    Virtualisation

    On arrive presque à l'issue de la chaîne des technos. En fait, dès maintenant, libvirt est capable de créer des VM. Mais par contre, en l'état, vous devrez vous charger manuellement de l'activation des LV. C'est un peu fastidieux, surtout dans un milieu industriel.

    D'un point de vue conceptuel, deux possibilités s'offrent à nous :

    • On définit toutes les VM sur tous les hôtes (et bien sûr on ne démarre des VM que sur un seul hôte à la fois).
    • On définit sur un hôte uniquement les VM que cet hôte a le droit d'exécuter pour l'instant

    J'ai choisi la deuxième option pour des raisons de clarté, mais je n'exclue pas de passer à la première option dans le futur pour une raison ou une autre.

    Il faut ensuite adopter une stratégie d'activation des LV. On peut en choisir entre ces deux là :

    • Un hôte active les LV de toutes les VM qui sont définies sur lui.
    • Un hôte active uniquement les LV des VM en cours d'exécution sur lui.

    J'ai choisi la deuxième stratégie, car la première est incompatible avec l'option de définir toutes les VM sur tous les hôtes.

    Selon cette deuxième stratégie, il y a trois opérations de base sur les VM qui nécessitent d'intervenir sur l'activation des LV :

    • La mise en service
    • L'arrêt
    • La migration (le transfert d'une VM d'un hôte à un autre)

    Pour la mise en service, il faut activer le volume (et donc poser un verrou) avant que la machine ait commencé à s'en servir. Pour l'arrêt, il faut désactiver le volume (et donc libérer le verrou) après que la machine ait fini de s'en servir. Pour la migration... c'est plus compliqué.

    Pour la migration à froid, c'est à dire pendant que la machine est à l'arrêt, c'est facile : il faut activer le volume sur la machine cible avant la migration et le désactiver après. Pour la migration à chaud, c'est à dire pendant que la VM est en marche, je vous propose d'étudier la suite des états de la VM et du LV, avec en gras les événements et en italique les périodes :

    1. Avant l'instruction de migration : la VM est en marche sur l'hôte source, donc le LV associé doit être activé sur l'hôte source.
    2. Instruction de migration
    3. Entre l'instruction de migration et la migration effective : la VM est en marche sur l'hôte source, donc le LV associé doit être activé sur l'hôte source ; l'hôte cible vérifie qu'il peut accéder au LV, donc le LV doit être activé sur l'hôte cible.
    4. Migration effective
    5. Après la migration effective : la VM est en marche sur l'hôte cible, donc le LV associé doit être activé sur l'hôte cible.

    Vous le voyez bien : à l'étape 3, il est nécessaire que le LV de la VM soit activé à la fois sur la source et sur la cible. Et là, ce pour quoi on s'est battu depuis le début de cet article vole en éclat, et notre beau château de carte est désintégré par une bourrasque de vent.

    Mais non, il reste de l'espoir, car je ne vous ai pas encore tout dit.

    En fait, par défaut, les verrous des LV sont exclusifs, mais il est aussi possible de poser un verrou partagé :

    lvchange -asy virtVG/tintin

    Lorsqu'un LV est activé avec un verrou partagé, n'importe quel autre hôte a la possibilité d'activer le même LV avec un verrou partagé. Il faudra attendre que tous les hôtes aient désactivé le LV (et donc libéré leurs verrous partagés) pour que le LV puisse à nouveau être activé avec un verrou exclusif.

    Bien entendu, si on laisse un verrou partagé sur plusieurs hôtes pendant une longue période, il est probable qu'un opérateur négligeant finisse par commettre l'irréparable en lançant la VM en question alors qu'elle est déjà en marche ailleurs...

    C'est pourquoi il faut absolument que les périodes d'usage des verrous partagés soient réduites au nécessaire, c'est à dire pendant la migration.

    Heureusement, libvirt vous donne la possibilité de mettre en place des crochets, c'est à dire des scripts qui vont être automatiquement appelés par libvirt au moment où il lance ces opérations. L'emplacement du crochet dont on a besoin est /etc/libvirt/hooks/qemu.

    Nouveau problème : en l'état actuel, en ce qui concerne la migration, libvirt invoque le crochet uniquement sur l'hôte cible, et uniquement avant la migration effective. Nous avons besoin qu'il invoque le crochet à trois autres reprises :

    • Avant la migration effective, sur l'hôte source, pour permettre de muter le verrou exclusif en verrou partagé
    • Après la migration effective, sur l'hôte source et l'hôte, pour permettre de libérer les deux verroux partagés, dans le cas d'une migration à froid

    Dans le cas d'une migration à chaud, libvirt notifie de toute façon, à la source, l'arrêt de la VM et donc la libération du verrou quel qu'il soit, et sur la cible, le démarrage de la VM et donc la pose d'un verrou exclusif qui écraserait un éventuel verrou partagé.

    J'ai remonté le problème aux ingénieurs de Redhat en charge de libvirt, ils sont en train de développer la solution (suivez le fil sur la mailing list). Je publierai mon script dès que ce problème sera réglé.

    À propos de la configuration de libvirt, j'ai un dernier conseil qui me vient à l'esprit. Il ne sert pas à grand chose de configurer le VG en temps que pool de volume, au sens de libvirt. En vérité, on peut très bien démarrer une VM même si son volume est en dehors de tout pool défini dans libvirt. En plus, si le pool est en démarrage automatique, libvirt va activer tous les LV quand il va démarrer, ce qui va provoquer une erreur dans le cas d'un redémarrage d'un hôte dans un cluster en service.

    Le seul avantage de définir un pool auquel je peux penser est que libvirt peut créer des LV sans commande LVM auxiliaire au moment de la création d'une VM. La belle affaire. Personnellement je provisionne déjà mes VM avec un outil auxiliaire qui s'appelle virt-builder, faisant partie de la très utile suite utilitaire libguestfs. Je vous la recommande, elle fera peut être l'objet d'un futur article.

    J'ai déjà beaucoup trop parlé et ça m'a saoulé, alors maintenant je vais la fermer et dormir un peu.

    • At chevron_right

      Le package Jitsi-Meet : la fête du slip

      raspbeguy · pubsub.gugod.fr / atomtest · Wednesday, 22 May, 2019 - 22:00 · 2 minutes

    Aujourd'hui j'ai du installer un serveur Jitsi Meet pour un client. Je ne l'aurais pas prévu mais ça a été la grosse galère pour des raisons tout à fait singulières. Jistti Meet, pour ceux qui ne le connaissent pas, c'est une solution libre pour faire des discussion vidéo qui s'appuie entre autres s...

    Aujourd'hui j'ai du installer un serveur Jitsi Meet pour un client. Je ne l'aurais pas prévu mais ça a été la grosse galère pour des raisons tout à fait singulières.

    Jistti Meet, pour ceux qui ne le connaissent pas, c'est une solution libre pour faire des discussion vidéo qui s'appuie entre autres sur les technologies XMPP et WebRTC. En gros ça a l'avantage de s'appuyer sur une techno de communication existante et ça ne demande pas d'installation de programmes autres qu'un navigateur un minimum récent. C'est compatible Firefox, Chrome, Edge, pour ne citer qu'eux.

    Pour faciliter l'installation, Jitsi met à disposition des dépôts APT permettant d'installer sans galérer cet outil clef en main. En théorie seulement car en pratique il faut quelques étapes préliminaires afin que tous les rouages s'emboîtent correctement.

    J'ai donc déployé une nouvelle VM sous Debian Stretch toute nue et j'ai installé les packets.

    echo 'deb https://download.jitsi.org stable/' >> /etc/apt/sources.list.d/jitsi-stable.list
    wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | apt-key add -
    apt update
    apt install jitsi-meet

    L'installeur pose ensuite quelques questions :

    • La première porte sur le nom du service (comprendre ici le FQDN).
    • La seconde vous demande si vous souhaitez utiliser votre propre certificat ou bien générer un certificat auto-signé. Moi je suis parti sur mon propre certificat, ce qui active les deux questions suivantes.
    • Le chemin du fichier de clef.
    • Le chemin du fichier de certificat.

    Je me dis : cool, cela a l'air de s'être bien passé. Mais je me trompais.

    J'ai refais l'installation plusieurs fois en variant plusieurs paramètres : certificat, chemin des fichiers, installation du reverse proxy avant... Dans certains cas j'avais droit à un handshake TLS foireux, dans d'autres cas des comportements bizarre comme l'impossibilité de rejoindre une room, et dans le reste des cas des erreur APT/DPKG.

    Il se trouve que l'unique suite d'opération qui ait fonctionné pour moi est la suivante :

    • Installer nginx (ou apache si vous aimez utiliser un tank pour casser un œuf). De cette façon, le paquet Jitsi va détecter la présence d'un proxy et va tout seul ajouter son vhost.
    • Obtenir vos certificats (letsencrypt si vous le souhaitez) et faire en sorte que nginx écoute sur les ports 80 et 443) avant l'installation de Jistsi. Si ce n'est pas le cas, le processus java de Jitsi va s'approprier les ports 80 et 443 ce qui va créer une erreur au moment de recharger nginx avec la nouvelle configuration. C'est délicat comme position...
    • Finalement, installer Jitsy.

    J'ai écrit cet article pour économiser un peu de temps au prochains admin qui devront installer ça. Par ailleurs, il est possible que lorsque vous lancerez votre première room, un bug vous frappe: à chaque fois que quelqu'un d'autre rentre dans la room, l'occupant actuel est éjecté... Selon la page du bug sur Github, un reboot de la machine suffit et le bug ne se reproduit apparemment plus. Pour moi ce n'est pas satisfaisant d'appliquer des méthodes à la Windows, mais j'avoue que je n'ai pas eu le courage de chercher plus longtemps.

    • At chevron_right

      Let's Encrypt sur HAProxy (Partie 2)

      raspbeguy · pubsub.gugod.fr / atomtest · Friday, 10 November, 2017 - 23:00 · 8 minutes

    Le fonctionnement de la Terre, avant qu'un certain Galilée y mette son grain de sel, a toujours déchaîné les passions des Hommes et a consommé beaucoup d'encre. Parmi les théories les plus folles, Terry Pratchett nous enseigne dans sa série de livres du Disque Monde que le monde repose sur le dos de...

    Le fonctionnement de la Terre, avant qu'un certain Galilée y mette son grain de sel, a toujours déchaîné les passions des Hommes et a consommé beaucoup d'encre. Parmi les théories les plus folles, Terry Pratchett nous enseigne dans sa série de livres du Disque Monde que le monde repose sur le dos de quatre gigantesques éléphants, eux-même reposant sur la carapace d'une tortue encore plus gigantesque appelée A'Tuin. Les quatre éléphants (Bérilia, Tubul, Ti-Phon l'Immense et Jérakine) se répartissent la charge que représente le poids du disque terrestre grâce à la rotation quotidienne de ce dernier. Si maintenant vous ne voyez pas le rapport entre une cosmologie impliquant des animaux au moins aussi grands que des continents capable de tenir en apnée pendant des milliards d'années et le sujet d'aujourd'hui, alors je ne sais plus quoi faire.

    Nous avons vu il y a quelques jours les principes de base d'un répartiteur de charge et exposé brièvement les concepts fondamentaux de HAProxy. Nous avons également mené une réflexion sur la manière de gérer un certificat sur une architecture avec répartiteur de charge et la voix du bon sens nous a susurré que le certificat devait être porté par HAProxy. Bon, mettons ça en pratique.

    Rangez vos affaires, sortez une feuille, interro surprise. Rappelez-moi ce qu'est le principe de base du protocole ACME. Et comme vous suivez bien et que vous buvez les paroles de l'instituteur comme un breton boit du cidre, vous saurez donc me répondre que l'agent de certification crée un challenge ACME en générant des fichiers de test auxquels le serveur ACME devra pouvoir accéder via HTTP, ces fichiers étant soit servis par l'agent via un serveur web intégré, soit mis à disposition du serveur de notre choix qui servira ces fichiers en statique. C'est en pratique presque toujours la deuxième solution qui est utilisée, sachant que justement, un serveur web tourne déjà sur les ports web standard (80 et 443). On ne veut pas d'interruption de service, non mais.

    Serveur statique

    Nous avons un petit problème ici. Les ports HTTP sont utilisés par HAProxy, qui n'est pas un serveur web, mais un répartiteur de charge. Souvenez-vous, il ne peut pas générer de lui même un flux web, pas même servir des fichiers statiques, il se contente de relayer des flux web créés par d'autres serveurs. Conclusion : il nous faut un serveur web tournant sur la machine hébergeant HAProxy capable de servir des fichiers statiques. L'idée, c'est qu'on va faire écouter ce serveur uniquement en local, et HAProxy se chargera de le propulser sur le réseau publique.

    On n'a que l'embarras du choix pour trouver un serveur web sachant servir du bon vieux statique. On pourrait choisir Nginx ou Lighttpd par exemple, mais comme nous sommes sur OpenBSD, le choix se portera sur le serveur web déjà préinstallé, communément appelé openhttpd.

    Première étape, il faut dire à OpenBSD d'activer le service.

    echo 'httpd_flags=""' >> /etc/rc.conf.local

    Ainsi on pourra démarrer le service, et il sera démarré à chaque démarrage de l'OS.

    Ensuite, il va nous falloir créer un dossier qui va accueillir les fichiers du challenge ACME. Comme le processus httpd est chrooté dans /var/www (sur OpenBSD, on appelle ça un jail), ce dossier sera donc /var/www/htdocs/webroot.

    La configuration de notre httpd sera on ne peut plus simple :

    server "default" { 
        listen on 127.0.0.1 port 1375 #ça fait "let's" en l33t
        root "/htdocs/webroot"
    }

    Démarrons le service :

    /etc/rc.d/httpd start

    Notre serveur statique est prêt.

    Configuration HAProxy

    Il faut dire à HAProxy de rediriger les requêtes ACME vers notre serveur statique fraîchement configuré.

    Pour ça, on va définir un backend dédié à Let's Encrypt, vers lequel seront redirigés tous les flux ACME reçus sur les frontends qui nous intéressent.

    backend letsencrypt-backend
            server letsencrypt 127.0.0.1:1375

    Propre. Syntaxe explicite, pas besoin d'expliquer je pense. Je fais juste remarquer qu'en plus de nommer le backend globalement, je donne un nom au serveur du backend même si ici il n'a aucune forme d'importance, il ne sera jamais appelé ailleurs dans le fichier, c'est néanmoins obligatoire sur HAProxy. Enfin, un nom clair est toujours profitable, car il est éventuellement utilisé dans ses logs, ses statistiques et il rend la lecture du fichier de conf plus facile.

    Le backend est prêt, c'est excellent, mais encore faut-il l'utiliser. Pour être exact, on ne va l'utiliser que si l'URL demandée correspond au chemin classique demandé par le validateur ACME, à savoir /.well-known/acme-challenge/. Reprenons l'exemple de la dernière fois, modifions-le de la sorte :

    frontend mon_super_site
        bind *:80
        mode http
    
        acl url-back-office path_dir /admin
        acl letsencrypt-acl path_beg /.well-known/acme-challenge/
    
        use_backend back-office if url-back-office
        use_backend letsencrypt-backend if letsencrypt-acl
        default_backend mes-frontaux
    
    backend back-office
        server backoffice 192.168.0.14:80
    
    backend mes-frontaux
        balance roundrobin
        server backoffice1 192.168.0.11:80
        server backoffice2 192.168.0.12:80
        server backoffice3 192.168.0.13:80
    
    backend letsencrypt-backend
        server letsencrypt 127.0.0.1:1375

    On a ajouté une ACL et une directive use_backend. Rappelez-vous, une ACL est tout simplement une condition, ici elle porte sur le chemin de l'URL. Rien de nouveau, on a déjà expliqué le concept.

    On recharge le schmilblick :

    /etc/rc.d/haproxy reload

    On est prêt à générer notre premier certificat. Mais on ne va pas le faire tout de suite. Comme vous vous en souvenez, HAProxy veut ses certificats sous une forme un peu spécifique, il nous faut donc traiter le certificat dès qu'il a été généré, et pour ça on va faire un peu de scripting. On pourrait déjà générer le certificat sans le script de post-traitement, mais si on faisait ça, on devrait ensuite éditer la configuration d'acme.sh et c'est un peu barbant, sachant que la commande qui génère le premier certificat génère également par magie la configuration associée pour les renouvellements. Donc ce serait stupide.

    Script de post traitement

    Rien de bien compliqué, je vous rassure. Le principe est simple : HAProxy n’accepte des certificats que sous la forme d'un fichier contenant la chaîne complète de certification et la clef privée, dans cet ordre.

    Le script est très simple. Vous pouvez bien entendu le mettre où bon bous semble, pour ma part j'ai décidé de le mettre dans /etc/haproxy/generate-ssl.sh.

    #!/bin/sh
    
    SITE=$1
    LE_CERT_LOCATION=/root/.acme.sh/$SITE
    HA_CERT_LOCATION=/etc/haproxy/ssl
    
    cat $LE_CERT_LOCATION/fullchain.cer $LE_CERT_LOCATION/$SITE.key > $HA_CERT_LOCATION/$SITE.haproxy.pem
    
    /etc/rc.d/haproxy reload

    LE_CERT_LOCATION représente l'endroit où seront générés les certificats par acme.sh (il s'agit ici de l'emplacement par défaut, mais vous pouvez changer ce chemin à condition d'utiliser l'option adéquate lors de la génération du premier certificat).

    HA_CERT_LOCATION est l'emplacement où seront créés les certificats au format HAProxy. D'ailleurs, n'oubliez pas de créer le dossier en question.

    Le script devra être appelé avec en paramètre le domaine complet principal du certificat. N'oubliez pas de le rendre exécutable.

    Génération du premier certificat

    On y est, maintenant on va enfin pouvoir générer ce satané certificat. Partons du principe que vous avez correctement installé acme.sh, le README du projet est très simple à suivre.

    acme.sh --issue -d mon-super-site.com -w /var/www/htdocs/webroot/ --renew-hook "/etc/haproxy/generate-ssl.sh mon-super-site.com" --debug

    Remarquez que vous pouvez générer un certificat couvrant plusieurs domaines à la fois, il suffit d'ajouter -d mon-domaine-secondaire.com entre le domaine principal et l'option -w. Remarquez l'option --renew-hook, elle permet d'appeler le script qu'on vient de définir à chaque fois qu'un renouvellement est effectué.

    Une fois la commande effectuée avec succès (ça peut prendre une minute ou deux), votre certificat est généré, il vous faut encore ajouter le certificat dans la configuration du frontend comme il suit :

    bind *:443 ssl cert /etc/haproxy/ssl/mon-super-site.com.haproxy.pem

    Comme il s'agit de la première génération et non d'un renouvellement, il est nécessaire d'appliquer le script à la main.

    /etc/haproxy/generate-ssl.sh mon-super-site.com

    Vérifiez, et pleurez de joie. Votre certificat est déployé et fonctionnel. C'est magnifique.

    Automatisation du renouvellement

    Ultime étape, celle qui fait prendre tout son sens à la révolution Let's Encrypt, celle qui fait qu'on peut oublier sans scrupule que tel ou tel site a un certificat proche de l'expiration, il s'agit du renouvellement automatique. Pas de subtilités, une simple ligne dans la crontab fait l'affaire. Et en plus, si je ne dis pas de bêtises, acme.sh s'occupe tout seul d'ajouter cette ligne.

    26 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

    La commande sera lancée tous les jours à minuit vingt-six, libre à vous de changer cet horaire. acme.sh sera assez intelligent pour savoir si votre certificat a besoin d'un coup de jeune ou non, donc rassurez vous, il n'y aura pas un renouvellement par jour.

    Conclusion

    Le protocole ACME peut s'appliquer à toutes les architectures web pour peu qu'on puisse traiter les requêtes du challenge correctement. À moins de disposer d'un stockage partagé (NSF, iSCSI, Samba...), il est indispensable que le challenge ACME soit créé par la machine capable de le traiter.

    Illustration : The Great A'Tuin par Paul Kidby

    • At chevron_right

      Let's Encrypt sur HAProxy (Partie 1)

      raspbeguy · pubsub.gugod.fr / atomtest · Sunday, 5 November, 2017 - 23:00 · 6 minutes

    Vous vous en souvenez peut-être, nous avions effectué un tutoriel Let's Encrypt quelques jours après sa mise en bêta publique. D'ailleurs, il mériterait un petit relooking, vu que quelques détails ont un peu changé, et que d'autres clients ACME ont vu le jour. Par exemple on a honteusement passé sou...

    Vous vous en souvenez peut-être, nous avions effectué un tutoriel Let's Encrypt quelques jours après sa mise en bêta publique. D'ailleurs, il mériterait un petit relooking, vu que quelques détails ont un peu changé, et que d'autres clients ACME ont vu le jour. Par exemple on a honteusement passé sous silence l'excellent acme.sh qui a le mérite de ne pas demander une ribambelle de dépendance en temps que simple script Bash. De plus, le client principal (dont le nom est désormais Certbot) a désormais implémenté des extensions Apache et Nginx qui fonctionnent (presque) comme on le souhaite, à savoir modifier tout seul les configurations des sites pour fonctionner avec Let's Encrypt. Cependant je reste plus enclin à utiliser la méthode manuelle.

    À l'époque, je vous parlais d'une infrastructure simple, à savoir un unique serveur frontal : c'est lui qui interceptait les requêtes et qui les traitait, point barre. L'infra d'un site avec une audience restreinte, car tout doit être traité par une unique machine. Bonjour l'indispo surprise.

    Parlons à présent d'une architecture un peu plus ambitieuse, le genre de topologie qu'on peut trouver en production pour des sociétés importantes (et les technophiles enthousiastes). Cette première partie sera dédiée à l'explication de cette mystérieuse architecture et à la présentation d'une manière de la mettre en œuvre. Dans une seconde partie, on apprendra à y déployer ses certificats Let's Encrypt.

    Souvent donc, on ne se contente pas d'un unique frontal, mais de plusieurs frontaux, sous la coupe d'un répartiteur de charge, (load-balancer en anglais) qui se chargera de réceptionner les requêtes des utilisateurs et de les distribuer aux frontaux, selon une stratégie définie. Cette architecture a quatre avantages :

    • On gagne en charge maximale supportée, donc en nombre de visiteurs.
    • Multiplier les frontaux amoindrit fortement les risques de crash du site, car en cas de panne d'un frontal, les autres frontaux se partagent le trafic.
    • La mise en production d'une nouvelle version d'un site web peut se faire sans aucune interruption de service : il suffit de déployer sur un frontal à la fois.
    • Les frontaux sont sur un réseau privés et non directement accessible sur le réseau global, donc la sécurité du site est renforcée.

    load-balancer

    On constate que le répartiteur de charge est un potentiel goulot d'étranglement et il nous faut donc un programme optimisé pour la haute disponibilité afin que le flux des requêtes ne soit pas le facteur limitant.

    Disons maintenant que l'on souhaite apposer un certificat sur cette architecture. Question à dix sesterces : qui parmi ces serveurs doit porter ce certificat ?

    Si on choisit de faire porter le certificat par les frontaux, cela signifie qu'il faut que tous les frontaux doivent le porter, et qu'il faudra déployer le certificat sur toutes ces machine à chaque renouvellement. Mais surtout, cela signifie que, le trafic étant chiffré jusqu'aux frontaux, le répartiteur de charge ne pourra pas prendre en compte le contenu de la requête dans sa stratégie de répartition, ce qui est fort pénalisant. En effet, il est coutume de configurer le répartiteur de charge pour distribuer certaines URL sur un pool de frontaux différent du pool normal, par exemple le back-office (la page d'administration et de saisie de contenu du site). Enfin dernier point, si vous vous souvenez du fonctionnement du protocole ACME comme décrit dans notre tutoriel, vous saurez que le certificat doit être généré sur la machine qui en fait la demande et qui répondra au challenge ACME. Ceci implique qu'un des frontaux doit être désigné pour la génération des certificat, et donc que le répartiteur de charge doit rediriger toutes les requêtes de type ACME vers ce frontal, ce qui est à la fois moche et justement impossible car notre répartiteur de charge ne peut pas comprendre ce qu'il redirige à cause du chiffrement.

    La solution la plus sensée, qui maintient également le plus l'isométrie des frontaux, est de faire porter le certificat par le répartiteur de charge.

    Zoomons alors sur cette fameuse machine, le répartiteur de charge. On va partir d'un socle OpenBSD. Pourquoi pas un Linux ? Parce qu'on utilise souvent la même machine pour la répartition de charge et pour le pare-feu, et qu'OpenBSD est le système de prédilection pour faire un routeur libre. Et en plus j'aime bien cet OS, ça change un peu les idées.

    Sur ce socle, on va utiliser le répartiteur de charge HAProxy. Les seules tâches de HAProxy sont de porter le certificat du ou des sites (on parle de SSL-offloading) et d'aiguiller le trafic web sur les frontaux. Il ne peut pas générer de flux web par lui-même, il peut seulement relayer une requête à un autre service. Et d'ailleurs il est très bon pour ça.

    HAProxy est organisé en frontends et en backends : un frontend est la façade présentée au monde extérieur qui va recevoir les requêtes des internautes. Un backend est un pool de serveurs frontaux qui va traiter la requête. HAProxy doit donc choisir sur quel backend envoyer une requête, mais il doit également gérer le pool de frontaux que représente ce backend.

    Prenons un exemple de configuration simple. On passera les directives globales HAProxy qui ne sont pas intéressantes et présentent peu de valeur ajoutée. Et bien entendu, on part du principe que vos frontaux sont configurés, écoutent sur des adresses locales et tout le toutim.

    frontend mon_super_site
        bind *:80
        mode http
    
        acl url-back-office path_dir /admin
    
        use_backend back-office if url-back-office
        default_backend mes-frontaux
    
    backend back-office
        server backoffice 192.168.0.14:80
    
    backend mes-frontaux
        balance roundrobin
        server backoffice 192.168.0.11:80
        server backoffice 192.168.0.12:80
        server backoffice 192.168.0.13:80

    Dans cette configuration, le frontend écoute sur toutes les adresses IP attribuées au serveur, sur le port 80 (donc pour le moment, uniquement du trafic en clair). Le mode HTTP signifie qu'on utilise ce frontend pour répartir du flux web, et non pas comme le mode TCP ou l'on redirige un flux TCP intouché.

    On a écrit une ACL, autrement dit une condition. Retenez cette notion car les ACL sont au cœur du principe de HAProxy. Ici notre ACL est vraie si le chemin de l'URL commence par /admin et fausse sinon. On utilisera donc le backendback-office si l'ACL est vraie et sinon, on utilisera le backend par défaut mes-frontaux.

    Le backendback-office est très simple car il ne comporte qu'un serveur. Le backendmes-frontaux comporte trois serveurs répartis en round-robin.

    Et voilà, vous avez un répartiteur de charge. Si vous avez un certificat SSL, vous pouvez ajouter une ligne au frontend :

    bind *:443 ssl cert /chemin/vers/mon/certificat.pem

    Sauf que ça ne marchera pas. En tout cas pas tant que vous aurez mis votre certificat sous la forme attendue par HAProxy, à savoir la clef privée et le certificat dans le même fichier. Nous verrons cela dans la seconde partie, qui vous expliquera également (et finalement) comment diable utiliser Let's Encrypt avec ce bidule. En tout cas, si vous êtes perspicace, vous vous doutez que ça tournera en partie autour des ACL, car il y a bien une raison pour laquelle c'est le seul élément en gras de l'article.

    (Source de l'image d'en-tête : Great A'tuin par Schiraki)

    • At chevron_right

      Ça va devenir RAID dans votre serveur

      raspbeguy · pubsub.gugod.fr / atomtest · Sunday, 20 August, 2017 - 22:00 · 13 minutes

    Récemment j'ai du intervenir sur ma tour parce que j'avais plus tellement de place. J'ai du vite acheter un autre disque dur pour y remédier. Ce qui me donne l'occasion de parler de cette belle technologie sur laquelle je m'étais promis de faire un petit tuto un de ces jours. En théorie RAID est l'a...

    Récemment j'ai du intervenir sur ma tour parce que j'avais plus tellement de place. J'ai du vite acheter un autre disque dur pour y remédier. Ce qui me donne l'occasion de parler de cette belle technologie sur laquelle je m'étais promis de faire un petit tuto un de ces jours.

    En théorie

    RAID est l'acronyme de Redundant Array of Independent Disks (Alignement redondant de disques indépendants), et comme son nom l'indique, il va permettre de regrouper plusieurs disques durs et d'y instaurer une politique de stockage pour faire de la redondance, de l’agrégation de taille, enfin ça répond à plein de besoins différents. En fait on ne devrait pas vraiment parler d'un seul RAID, mais bel et bien de la famille des RAIDs, car en effet il y a autant de RAIDs que de besoins différent.

    On va présenter les assemblages RAID les plus utilisés. Pour plus de détails, je vous conseille la page Wikipédia qui est très claire et qui contient des schémas très explicites.

    Dans la suite, on va beaucoup parler de bandes de stockage : il s'agit d'une quantité de stockage de valeur prédéfinie, qui correspond à une "section" contiguë du disque qui la contient. Dans ce modèle, lors de l'écriture sur le volume, une bande est d’abord remplie avant d'en entamer une suivante. Il s'agit en fait d'abstraire le stockage et de pouvoir mieux comprendre la répartition des données sur les différents disques.

    RAID 0

    Les bandes sont tout bonnement distribuées sur les disques, toujours dans le même ordre. On remplit donc une bande par disque, puis une fois qu'on a touché à tous les disques, on repart du premier disque et on recommence une couche de bandes. Tous les disques contiennent des données différentes. Ainsi, si vous avez n disques durs de capacité exploitable x, la capacité totale du montage sera nx.

    • Avantages : Ce montage permet d'utiliser le plus grand espace possible de votre assemblage. De plus, en moyenne, les accès disques parallèles seront plus rapide, pour peu que ces accès disques se fassent dans des bandes différentes et sur des disques différents.
    • Inconvénients : Il suffit de perdre un seul disque pour corrompre l'intégralité des données. Or, statistiquement, plus on a de disques, plus on a de chances d'en perdre.

    RAID 1

    Les bandes sont écrites à l’identique sur tous les disques. Tous les disques contiennent exactement les même données. Ainsi, si vous avez n disques durs de capacité exploitable x, la capacité totale du montage sera x.

    • Avantages : C'est le montage qui permet la plus grande sécurité des données faces aux pannes : tant qu'il vous reste un disque fonctionnel, vos données sont intactes et complètes. Les accès disques sont aussi nettement améliorés, avec une vitesse théorique multipliée par le nombre de disques dans le montage.
    • Inconvénients : Il est frustrant d'avoir beaucoup de disques durs pour avoir au final l'espace d'un seul disque. Évidemment les données sont très sûres mais quand même, faut pas pousser...

    RAID 5

    Les bandes sont réparties sur tous les disques sauf un, qui reçoit une bande de parité. La bande de parité est tout simplement une bande dont chaque bit est obtenu en appliquant le OU exclusif (XOR) à l'ensemble des bits correspondants dans les bandes alignées des autres disques. Cette bande de parité est attribuée à chaque disque alternativement au fil des couches de bandes remplies. Donc si un disque vient à tomber en panne, pour chaque couche de bande, si la bande du disque en panne est la bande de parité, alors les données de la couche sont intactes. Si la bande contient de la donnée, alors elle peut être recalculée à partir des autres couches de données et celle de parité. C'est du calcul logique, et c'est la force du XOR. Ainsi, si vous avez n disques durs de capacité exploitable x, la capacité totale du montage sera (n-1)x.

    • Avantages : Un bon compromis entre place exploitable et sécurité des données. On se donne le droit de perdre un disque dur dans la bataille. Pour retrouver l'usage des données, il suffit de remplacer le disque défaillant et les données sont reconstruites.
    • Inconvénients : Ça dépends des cas, mais un droit à un unique disque dur en panne, ça peu être peu. Pour certain ça peut être insuffisant.

    RAID 6

    Il s'agit d'une extension du RAID 5 dans laquelle on se permet de pouvoir perdre plus d'un disque. La solution étant d'attribuer plus de bandes de "parité" par couche, une par nombre de pannes maximum permises. Ici, j'utilise les guillemets car il ne s'agit plus vraiment de la parité simple de la logique de base, mais d'un truc chelou reposant sur un principe tout autre dont je ne pas trop vous parler parce que j'en ignore tout. Donc si vous avez n disques durs de capacité exploitable x, et si vous mettez en place k bandes de redondance par couche, la capacité totale du montage sera (n-k)x.

    • Avantages : On se sent un peu plus à l’abri des intempéries matérielles, au pris d'un peu de place de stockage.
    • Inconvénients : Le principe chelou dont je vous ai parlé, enfin dont je ne vous ai pas parlé pour être honnête, eh bien il est tellement chelou qu'il pète pas mal les performances. Et pour couronner le tout, la plupart des implémentations de ce type d'assemblage est bien moins stable que les autres.

    Il est également possible de combiner les RAIDs. Une combinaison fréquente est le RAID 10 (RAID 1 + RAID 0). Par exemple si on a 10 disques, on peu monter 2 RAID 1 de 5 disques chacun, puis assembler ces deux volumes en RAID 0. On a également aussi le RAID 50, combinaison dur RAID 5 et du RAID 0 selon le même principe.

    La gestion du RAID

    Je vous parlais de différentes implémentations du RAID. En fait, le RAID n'est pas un programme en tant que soi, juste un ensemble de spécifications. Du coup chacun y va de sa sauce : il existe des implémentations libres et propriétaires, logicielles et matérielles. Les solutions matérielles se basent sur du matériel dédié (un contrôleur RAID), le système d'exploitation n'a donc pas à s'occuper de ça et le plus souvent ces solutions marchent out of the box, sans avoir besoin de configurer quoi que ce soit. Mais elles ont l'immense inconvénient d'être propriétaire dans leur quasi-totalité, et pour le coup il n'existe aucun standard. Dans certains cas, si votre contrôleur RAID rend l'âme, il vous faudra acquérir exactement le même modèle de contrôleur, sinon, peu importe que vos disques soient tous intacts, plus rien ne pourra les lire, et vous serez alors en légitime position d'être fort contrarié. À mon humble avis, le principal argument des RAIDs matériel auparavant était les meilleures performances. Aujourd'hui cet avantage est de plus en plus obsolète, car désormais les machines sont bien plus puissantes qu'il y a 15 ans et les programmes de RAID ont été nettement optimisés et stabilisés. Cette différence de performance est aujourd'hui presque intangible.

    En pratique

    J'ai hérité par un ami d'une tour de bureau. Elle est bien cool car elle contient une grande baie de disques et pas mal de ports SATA (bien entendu, vous pouvez faire votre RAID avec des disques branchés en USB si vous le souhaitez). J'ai donc décidé d'en faire un NAS fait main.

    Choix des armes

    J'ai donc initialement acheté 3 disques de 3 To chacun (des Western Digital Red, gamme dédiée justement aux usage en RAID) et j'ai opté pour un RAID 5 logiciel. Et sur Linux, le programme de RAID par excellence est mdadm. J'ai décidé de garder branché le disque dur d'origine (500 Go) mais de ne pas l'intégrer au RAID, il sert uniquement de disque de démarrage. Notez que si j'avais voulu optimiser les performances, j'aurais pu troquer ce disque pour un petit SSD, mais bon, je suis déjà content comme ça.

    Par ailleurs, pour faire de la place dans la baie de disques, j'ai du déménager le disque de démarrage dans la baie frontale, celle destinée à accueillir les périphériques comme le lecteur optique.

    Le 4ème disque du RAID, on en parlera plus tard. Je l'ai acheté bien après.

    Pour ça j'ai utilisé un adaptateur 3,5 pouces vers 5,25 pouces bien pratique, qui m'a permis de fixer bien solidement le disque dur au lieu de le laisser se balader dans la tour.

    Partitionnement et formatage

    Du côté software, je me retrouve avec un disque sda de démarrage, et sdb, sdc et sdd des disques vierges prêts à être assemblés en RAID. Avant ça, j'ai besoin de les partitionner. J'utilise donc fdisk pour les trois disques à tour de rôle, je choisis une table de partitions GPT et j'y crée une unique partition de type "Linux RAID" (code 29 dans fdisk).

    Création de l'assemblage RAID

    C'est tout bête, ça tient en une seule ligne de commande :

    mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1

    Dans cette commande, j'indique que le nom du volume abstrait sera /dev/md0, que ce sera un RAID 5, qu'il comporte 3 disques et je lui précise les partitions que je veux utiliser.

    Pour suivre l'évolution de la création de l'assemblage, jetez un coup d'oeil au fichier /proc/mdstat. Ce fichier sera votre nouvel ami, c'est lui qu'il faudra consulter dès que vous ferez une opération qui touche au RAID.

    Puis j'ajoute l'assemblage à la configuration de mdadm pour que celui-ci me l'assemble au démarrage :

    mdadm --detail --scan >> /etc/mdadm.conf

    Puis il ne vous reste plus qu'à mettre votre système de fichier préféré sur le volume créé !

    mkfs.ext4 /dev/md0

    Pour que votre assemblage soit monté au démarrage, j'ajoute à mon /etc/fstab :

    /dev/md0 /mnt/data ext4 defaults 0 0

    Il ne faut pas confondre assemblage et montage, il s'agit de deux étapes lors de la connexion d'un RAID. On doit assembler un RAID afin qu'il soit reconnu comme un volume propre, puis on doit monter notre volume pour pouvoir lire et écrire dessus.

    Enfin on monte le volume :

    mkdir /mnt/data
    mount /mnt/data

    Ayé vous avez un RAID 5 qui fonctionne !

    Il est recommandé de procéder régulièrement à des reconstruction de RAID, opération qui va vérifier la cohérence de l'assemblage. Il s'agit d'une opération transparente mais qui dure plusieurs heures et qui va se traduire par une forte augmentation de l'activité des disques. Pour ça il vous faudra lancer un petit programme sans arguments, raid-check, à un intervalle raisonnable, disons, toutes les semaines. Choisissez un horaire de faible activité, comme la nuit du samedi au dimanche à 3h du matin. Pour ça, faites vous plaisir, entre la crontab et les timers de systemd, on manque pas de solutions.

    Ajout d'un nouveau disque à l'assemblage

    Mon RAID 5 était constitué de 3 disques de 3 To ce qui nous fait 6 To exploitables, si vous avez bien suivi. 6 To, c'est un grand espace, il m'a suffi pendant presque 2 ans... Puis j'ai eu besoin de plus de place. J'ai donc racheté un autre disque (même modèle, même taille) que j'ai fourré dans ma tour. Je vous avoue que sur le coup, j'étais encore puceau au niveau extension de RAID, j'ai donc flippé énormément et j'ai fait une sauvegarde de mes 6 To sur divers disques externes que j'ai pu trouver dans ma caverne. Je vous raconte pas comme c'était pénible...

    Petites observations à ce niveau :

    1. Remarquez que l'ordre des disques dans le nommage des périphériques physiques (sdX) et tout sauf fixe. En théorie, il faut être préparé à ce que vos disques changent de noms. Votre petit sdb chéri que vous avez bordé et vu s'endormir dans le creux douillet de son lit un soir peut très bien vous trahir et s'appeler sdc au petit matin dès le prochain redémarrage. Bon c'est un peu exagéré, mais une chose est sure, il ne faut jamais faire confiance au nommage des périphériques physiques (c'est pour ça entre autres qu'il faut privilégier la désignation par UUID dans la fstab).
    2. mdadm se fiche complètement du nommage de ses périphériques. Il utilise sa propre magie noire pour déterminer les membres d'un assemblages. En conclusion, ne vous tracassez pas pour retrouver le nom de vos disques de votre assemblage, mdadm, lui, s'y retrouvera toujours.

    Cependant, faites quand même gaffe lorsque vous allez ajoutez votre nouveau disque dur. Par exemple chez moi, le nouveau disque s'est vu nommé sdb, tandis que les autres s'étaient vu relégués en sdc, sdd et sde. Faut juste le savoir et traiter les disques pour ce qu'ils sont, et non pas des étiquettes à trois lettres.

    Tout ce que j'ai eu à faire, en définitive, a été de partitionner-formater mon nouveau disque ainsi que l'ont été ses aînés, puis j'ai lancé les deux commandes suivantes :

    mdadm --add /dev/md0 /dev/sdb1
    mdadm --grow --raid-devices=4 --backup-file=/root/grow\_md0.bak /dev/md0

    La première va juste indiquer à mdadm qu'on lui ajoute un disque, mais sans plus. C'est la deuxième commande qui va lancer l'opération de reconstruction (rééquilibrage de l'assemblage). Opération qui dure plusieurs heures, donc suivez son déroulement dans /proc/mdstat.

    Une fois que c'est terminé, il faut maintenant procéder à l'extension du système de fichier lui même. Et là vous priez pour avoir choisi un système de fichier pas trop stupide qui accepte ce genre d'opération. Rassurez-vous, ext4 le supporte très bien.

    Il le supporte même tellement bien que vous pouvez le faire directement à chaud, sans démonter votre volume. Pour ça, premièrement, si vous utilisez une connexion SSH, ouvrez une session tmux. Il serait bête qu'un incident réseau de rien du tout vienne corrombre tout votre système de fichire tout de même. Puis il vous faudra exécuter :

    resize2fs -p /dev/md0

    Il va vous mettre en garde et ronchonner un tantinet que votre disque est toujours monté, mais écoutez, il s'en remettra, dans la vie on fait pas toujours ce qu'on veut. Les minutes passent, vous vous rongez les ongles, vous prenez un café, vous videz un pot de glace, et normalement, si tout se passe bien, le système de fichier aura été étendu à tout l'espace disponible sur l'assemblage. Félicitations !

    Conclusion

    J'ai rencontré beaucoup de monde m'ayant dit qu'ils préféraient rester éloigner autant que possible de RAID parce que ça leur faisait peur. En réalité, il n'y a rien d'effrayant là dedans. mdadm est un outil ma foi fort bien codé et les années ont prouvé qu'il était fiable. Il ne faut pas avoir peur du RAID. Enfin un peu quand même, faut pas faire n'importe quoi.