[{"uuid":"bea327e2-9d1c-4ff6-a5a5-26748c80018b","slug":"anatomie-d-un-script-d-auto-deploiement-bash-fetch-scripts-sh","title":"Script Bash d'auto-déploiement : `fetch_scripts.sh`","category":"informatique","author":"cedric@abonnel.fr","cover":"cover.svg","published":true,"published_at":"2026-05-04 07:04","created_at":"2026-05-12 10:55:39","updated_at":"2026-05-12 11:10:51","tags":[],"plain":"Comment un simple script Bash peut télécharger, mettre à jour et synchroniser une bibliothèque de scripts distants — et pourquoi il faut le lire avec un œil critique.\r\n\r\nfetchscripts.sh\r\n📝 Note — Cet article est une autocritique. Le script analysé ici est de ma propre fabrication, déployé sur mes propres machines. L'exercice consiste à le relire avec la distance d'un reviewer extérieur, pour identifier ce qui tient la route et ce qui mériterait d'être repris.\r\n\r\nLe contexte\r\n\r\nL'idée derrière ce script est élégante : centraliser une collection de scripts utilitaires dans un dépôt Git public (ici, une instance Forgejo auto-hébergée), puis fournir un unique point d'entrée que l'on télécharge sur n'importe quelle machine. Ce point d'entrée se met à jour tout seul, propose à l'opérateur de choisir quels sous-ensembles de scripts récupérer, et maintient une synchronisation locale du dépôt distant.\r\n\r\nC'est typiquement le genre d'outil qui se déploie en une ligne :\r\n\r\n\r\n\r\nDécortiquons ce qu'il fait, étape par étape, puis voyons où il faudrait taper.\r\n--\r\n\r\nÉtape 1 — L'auto-mise à jour\r\n\r\n\r\n\r\nCe qui se passe : le script télécharge sa propre version distante dans , la compare octet-à-octet avec lui-même (), et si elle diffère, il s'écrase, se rend exécutable, et se relance via (qui remplace le processus courant — pas d'empilement de shells).\r\n\r\nPourquoi c'est malin : ça garantit qu'à chaque exécution, l'opérateur travaille avec la version canonique du dépôt. Pas besoin de mécanisme de versioning, pas de vérification de hash, pas de paquet à publier.\r\n\r\nPourquoi c'est risqué : on y reviendra dans la critique, mais en résumé — l'auto-mise à jour silencieuse depuis une URL en HTTPS sans signature est une porte d'entrée pour la chaîne d'approvisionnement.\r\n--\r\n\r\nÉtape 2 — Récupération du catalogue de dossiers\r\n\r\n\r\n\r\nLe dépôt distant contient un fichier qui liste les catégories de scripts disponibles (par exemple : , , , …). Ce fichier est la source de vérité : ajouter une catégorie côté serveur la rend immédiatement disponible côté client.\r\n\r\n (alias ) lit le fichier ligne à ligne dans un tableau Bash. Plus propre qu'une boucle .\r\n\r\nUn dossier est marqué comme obligatoire — il sera toujours téléchargé, sans demander à l'utilisateur.\r\n--\r\n\r\nÉtape 3 — Mémoire de la sélection précédente\r\n\r\n\r\n\r\nÀ chaque exécution, le script relit la sélection de la fois précédente. C'est ce qui permet à l'interface graphique (étape suivante) de pré-cocher les bons dossiers : on n'a pas à refaire son choix à chaque mise à jour.\r\n--\r\n\r\nÉtape 4 — L'interface \r\n\r\n\r\n\r\n est l'outil de dialogue ncurses standard sur Debian/Ubuntu — il affiche cette boîte bleue familière avec des cases à cocher, navigable au clavier. Idéal en SSH.\r\n\r\nLa gymnastique est un classique : écrit son interface sur stdout et sa réponse sur stderr. Il faut donc échanger les deux pour capturer la sélection dans tout en laissant l'interface s'afficher.\r\n\r\nL'expression est une astuce courante pour tester l'appartenance à un tableau Bash — on entoure d'espaces pour éviter les correspondances partielles ( qui matcherait ).\r\n--\r\n\r\nÉtape 5 — Synchronisation : ajouts et suppressions\r\n\r\n\r\n\r\nLogique de diff : tout ce qui était sélectionné avant et ne l'est plus est supprimé du disque. Ça maintient le répertoire local propre — pas de scripts orphelins qui traînent.\r\n\r\n renvoie la sélection sous forme de chaîne entre guillemets (), d'où le pour les retirer avant de constituer le tableau.\r\n--\r\n\r\nÉtape 6 — Téléchargement des fichiers de chaque dossier\r\n\r\n\r\n\r\nMême logique récursive d'un niveau plus bas : chaque dossier contient son propre listant ses fichiers. On télécharge ceux qui y figurent, on supprime ceux qui n'y figurent plus, et on rend tout exécutable.\r\n\r\nC'est une forme de artisanal, basé sur des manifestes plats. Ça fonctionne sans avoir à installer sur la machine cible — seuls et sont requis.\r\n--\r\n\r\nCritique : ce qui marche, ce qui inquiète\r\n\r\nLes bons côtés\r\n\r\nLa logique d'idempotence est solide. Le script peut tourner cent fois de suite, il convergera toujours vers le même état : les dossiers sélectionnés contiendront exactement les fichiers du manifeste, ni plus, ni moins. C'est le bon réflexe DevOps.\r\n\r\nL'auto-bootstrap est ergonomique. Une seule URL à retenir, tout le reste se télécharge tout seul. Pour une bibliothèque personnelle de scripts d'admin, c'est imbattable en simplicité.\r\n\r\nPas de dépendances exotiques. , , : tout est disponible nativement sur Debian. Le script tourne aussi bien sur un conteneur LXC fraîchement provisionné que sur une machine établie.\r\n\r\nLe manifeste séparé ( et ) découple la liste des fichiers de leur contenu. C'est plus simple qu'un parsing HTML de l'index Git, et ça reste sous contrôle éditorial.\r\n\r\nLes angles morts\r\n\r\n1. Aucune vérification d'intégrité\r\n\r\nC'est le point critique. Le script télécharge du code exécutable en HTTPS, sans vérifier :\r\nni signature GPG,\r\nni hash SHA256,\r\nni même que le serveur a bien répondu correctement.\r\n\r\n en mode silencieux n'échoue pas visiblement : si la requête renvoie une page d'erreur 404 ou une page de connexion captive Wi-Fi en HTML, elle sera écrite dans le fichier de destination. La vérification suivante () considérera ce HTML comme « différent », fera le , et au prochain le shell essaiera d'exécuter du HTML. Au mieux ça crashe, au pire ça exécute des balises interprétables.\r\n\r\nPire encore pour l'auto-update : si quelqu'un compromet l'instance Forgejo (ou interpose un proxy malveillant capable de servir un certificat valide pour ), le prochain télécharge et exécute du code arbitraire avec les privilèges de l'utilisateur courant — souvent root pour ce genre d'outils d'admin.\r\n\r\nCorrectif minimal : publier un fichier signé GPG dans le dépôt, le télécharger, vérifier sa signature avec une clé connue localement, puis valider chaque fichier téléchargé contre ce manifeste.\r\n\r\n2. sans gestion d'erreur\r\n\r\n\r\n\r\nSi échoue (réseau coupé, DNS HS, certificat expiré), sera soit vide soit absent. retournera « différent », et le script écrasera la version locale par un fichier vide. À la prochaine exécution, plus rien ne fonctionne.\r\n\r\nCorrectif : vérifier le code de retour de , vérifier que le fichier téléchargé n'est pas vide, et vérifier qu'il commence bien par avant d'écraser quoi que ce soit.\r\n\r\n\r\n\r\n3. Le perd les modifications de l'environnement\r\n\r\nSi le script a été lancé par (donc sans le bit exécutable, sans shebang utilisé), vaut . Après , on un fichier qui pourrait ne pas être dans le . En pratique ça marche parce qu'on est dans le bon répertoire, mais c'est fragile — un quelque part dans le script suffirait à le casser.\r\n\r\n4. Injection via les noms de fichiers du manifeste\r\n\r\n\r\n\r\nLe contenu de est utilisé directement dans une URL et dans un chemin de fichier local. Si quelqu'un peut écrire dans ce fichier manifeste (ce qui revient à pouvoir pousser sur le dépôt Forgejo), il peut y mettre des chemins comme et écrire en dehors du répertoire prévu.\r\n\r\n neutralise partiellement la chose côté nom local, mais l'URL côté distant accepte n'importe quoi. C'est moins critique que la première faille, mais ça mérite un filtre regex ( uniquement).\r\n\r\n5. et la sélection vide\r\n\r\nSi l'utilisateur ne coche rien et valide, est vide. Le script continue avec seulement , ce qui est probablement le comportement attendu. Mais si n'est pas installé (rare mais possible, par exemple sur Alpine ou un Debian minimal sans ), le script échoue avec une erreur peu explicite. Un test préalable éviterait la déconvenue.\r\n\r\n6. Pas de log, pas de mode dry-run\r\n\r\nPour un outil qui supprime des fichiers (), l'absence d'option qui afficherait ce qui serait fait sans rien toucher est gênante. Une frappe distraite sur la checklist, et un dossier entier disparaît sans warning.\r\n\r\n7. Le verrou manquant\r\n\r\nRien n'empêche deux instances de de tourner en parallèle (par exemple via et un opérateur en interactif). Un sur un fichier de lock éviterait des courses sur les opérations de download/delete.\r\n--\r\n\r\nVerdict\r\n\r\nC'est un script utile, lisible, et bien construit pour un usage personnel sur des machines de confiance. La logique de synchronisation est saine, l'ergonomie est appréciable, l'auto-bootstrap est élégant.\r\n\r\nMais dès qu'on franchit la frontière du « j'utilise ça sur mes propres machines avec mon propre dépôt », les manques se font sentir : pas de vérification d'intégrité, pas de gestion d'erreur réseau, pas d'option de récupération. Dans un contexte d'équipe ou de production, ces points sont bloquants.\r\n\r\nPistes d'évolution prioritaires\r\n\r\n1. Signature ou checksum : publier un signé GPG, le vérifier avant tout ou exécution.\r\n2. en tête de script pour faire échouer proprement à la première erreur.\r\n3. Vérifier : code de retour, fichier non vide, shebang présent.\r\n4. Backup avant écrasement : conserver la version précédente () pour pouvoir revenir en arrière.\r\n5. Option pour visualiser sans appliquer.\r\n6. Filtre regex sur les noms de fichiers du manifeste pour éviter les traversées de chemin.\r\n7. Lock file** via pour éviter les exécutions concurrentes.\r\n\r\nAvec ces ajouts, on passe d'un script « pratique » à un outil de déploiement digne de ce nom — sans rien perdre de sa simplicité initiale."},{"uuid":"ac1e56af-57b3-443f-bbae-5d6ad7db153c","slug":"creer-un-script-de-hook-let-s-encrypt-pour-dovecot","title":"Créer un script de Hook Let's Encrypt pour Dovecot","category":"Informatique","author":"cedric@abonnel.fr","cover":"","published":true,"published_at":"2023-12-29 17:14:22","created_at":"2023-12-29 17:14:22","updated_at":"2023-12-29 17:14:22","tags":[],"plain":"Pour mettre en place un hook qui redémarre Dovecot après chaque renouvellement de certificat avec Let's Encrypt (généralement géré par Certbot), vous devez ajouter un script de hook dans le répertoire approprié ou spécifier le hook directement dans la commande de renouvellement de Certbot. Voici comment vous pouvez procéder : 1. Création d'un Script de Hook\nVous pouvez créer un script qui redémarre Dovecot. Par exemple: Enregistrez ce script quelque part sur votre système, par exemple, . Assurez-vous de rendre le script exécutable : 2. Utiliser Certbot avec le Hook\nLorsque vous exécutez Certbot pour renouveler vos certificats, vous pouvez spécifier des hooks à exécuter avant ou après le renouvellement. Ajouter le Hook de Renouvellement Automatique : Si vous avez configuré Certbot pour renouveler automatiquement vos certificats (ce qui est la configuration recommandée), vous pouvez ajouter votre script de hook directement dans la configuration de renouvellement de Certbot. Pour chaque certificat dans , il y a un fichier de configuration correspondant. Vous pouvez ajouter les lignes suivantes au fichier de configuration de votre domaine (par exemple, ): 3. Utiliser des Hooks Directoires\nCertbot vérifie également automatiquement trois répertoires pour les scripts à exécuter comme hooks :\n: Avant le renouvellement.\n: Après le renouvellement réussi d'un certificat.\n: Après la tentative de renouvellement (qu'elle soit réussie ou non). Placer votre script dans assurera qu'il s'exécute après chaque tentative de renouvellement, ce qui est idéal pour des actions comme redémarrer Dovecot. 4. Testez votre Configuration\nAprès avoir mis en place le hook, vous devriez tester le processus pour vous assurer que tout fonctionne comme prévu. Vous pouvez simuler un renouvellement avec Certbot en utilisant une option de test (cela ne remplacera pas vos certificats actuels) : Si tout est correctement configuré, Certbot renouvellera le certificat en mode test et exécutera votre script pour redémarrer Dovecot. Assurez-vous que Dovecot fonctionne correctement après l'exécution du script. Notes Importantes :\nSécurité : Vérifiez que seuls les utilisateurs appropriés ont des permissions d'écriture sur le script et les fichiers de configuration pour éviter des modifications non autorisées.\nLogs : Surveillez vos logs pour vous assurer que les renouvellements et les redémarrages de Dovecot se passent comme prévu. Certbot et Dovecot écrivent tous deux des logs qui peuvent être utiles en cas de problème.\nCompatibilité : Vérifiez que les versions de Certbot et Dovecot que vous utilisez supportent les configurations et méthodes décrites ici, car les logiciels peuvent changer avec le temps. En ayant un hook bien configuré, vous vous assurez que Dovecot utilise toujours un certificat à jour, maintenant ainsi la sécurité de votre service de messagerie."},{"uuid":"60acde33-f1fa-4ab5-867e-8fb506211186","slug":"script-bash-upload","title":"Script Bash pour upload de CSV","category":"Électronique","author":"cedric@abonnel.fr","cover":"","published":true,"published_at":"2023-02-16 15:39:20","created_at":"2023-02-16 15:39:20","updated_at":"2023-02-16 15:39:20","tags":[],"plain":"Dans le script Bash, la commande \"curl\" permet d'envoyer le fichier vers la page PHP d'upload. Voici un exemple de code Bash qui télécharge tous les fichiers CSV dans un répertoire, à l'exception de celui qui a été modifié le jour même. Pour exclure le fichier CSV modifié le jour même de l'envoi, on a utilisé la commande find pour localiser tous les fichiers CSV dans le répertoire spécifié qui ne sont pas modifiés aujourd'hui. Ensuite, on boucle sur cette liste de fichiers et exécuter le code d'envoi de fichier pour chaque fichier trouvé. Pour chaque fichier, nous avons calculé le SHA-1 localement, envoyé le fichier au script PHP, récupéré le SHA-1 calculé par le script PHP et comparé les deux valeurs de hachage. Si les valeurs de hachage sont identiques, nous avons affiché un message de confirmation et déplacé le fichier CSV dans le dossier . Si les valeurs de hachage ne sont pas identiques, nous avons affiché un message d'erreur."},{"uuid":"57d5fbd4-0bd2-44a1-896c-151aa527f713","slug":"execution-unique-d-un-script-bash","title":"Exécution unique d'un script BASH","category":"Informatique","author":"cedric@abonnel.fr","cover":"","published":true,"published_at":"2020-12-25 22:14:45","created_at":"2020-12-25 22:14:45","updated_at":"2020-12-25 22:14:45","tags":[],"plain":"Il arrive que l'on est besoin d'exécuter de manière un script. C'est à dire que le script ne doit pas démarré alors que le précédent lancement n'est pas terminé. Il faut savoir que lorsqu'un script ou un programme s'exécute, le système d'exploitation lui attribue un identifiant unique, appelé process id. Le script doit s'assurer une execution unique. Pour se faire, il déclarera son process id dans un fichier. Le fichier sera consulté systématiquement au démarrage. Si le process id est toujours en cours d'exécution, alors l'exéction qui vient de démarrer, s'arrêtera. Voici l'algo proposé : En BASH, voici le code proposé pour un script de sauvegarde :"},{"uuid":"3ba3a438-208a-415d-b650-ff820949bca1","slug":"dovecot","title":"Dovecot - fournisseur IMAP","category":"Informatique","author":"cedric@abonnel.fr","cover":"","published":true,"published_at":"2023-02-09 23:37:17","created_at":"2023-02-09 23:37:17","updated_at":"2023-02-09 23:37:17","tags":[],"plain":"Dovecot est un serveur de messagerie populaire, open source basé sur le protocole IMAP (Internet Message Access Protocol). Dovecot permet aux utilisateurs de recevoir et gérer leurs emails en utilisant le protocole IMAP. IMAP est un protocole de messagerie qui permet de synchroniser les emails entre plusieurs appareils, de sorte que vous pouvez accéder à vos emails n'importe où et n'importe quand. Dovecot est une implémentation populaire et fiable de ce protocole, utilisée par de nombreux fournisseurs de messagerie pour leur service de messagerie. L'un des avantages de l'utilisation du protocole IMAP est que vous n'avez pas besoin de télécharger vos emails sur chaque appareil que vous utilisez pour les consulter. Au lieu de cela, vous pouvez accéder à vos emails en temps réel sur tous vos appareils, et les actions que vous effectuez sur un appareil (comme lire un email, le marquer comme lu, ou le déplacer dans un dossier) seront automatiquement synchronisées avec les autres appareils. Cela signifie que vous avez toujours une vue à jour de vos emails, peu importe où vous vous trouvez. Certificat IMAP\nL'utilisation d'un certificat pour IMAP est importante pour garantir la sécurité des communications entre le client et le serveur. Les certificats pour IMAP sont généralement stockés dans le répertoire de configuration de votre serveur de messagerie, qui dépend de votre implémentation spécifique d'IMAP. Sur un système Debian avec Dovecot, vous pouvez trouver les certificats dans le répertoire . Ce répertoire peut inclure des fichiers tels que le certificat SSL, la clé privée et d'autres informations de sécurité nécessaires à la configuration de Dovecot. Il est important de s'assurer que les fichiers de certificat sont protégés et accessibles uniquement aux utilisateurs autorisés pour garantir la sécurité du système. Voir l'article : \n- Vous pouvez utiliser la commande OpenSSL pour afficher les informations d'une clé privée. La syntaxe de base pour afficher les informations d'une clé privée est la suivante : openssl x509 -noout -text -in /etc/dovecot/private/dovecot.pem\n \nPour afficher uniquement les dates associées à la clé, vous pouvez utiliser la commande suivante: openssl x509 -noout -in /etc/dovecot/private/dovecot.pem -enddate -startdate Redémarrage de Dovecot\nIl est généralement conseillé de redémarrer Dovecot pour prendre en compte les mises à jour de la configuration ou pour résoudre les problèmes de fonctionnement. Cependant, il est important de faire attention à la fréquence à laquelle vous redémarrez le service, car un redémarrage excessif peut entraîner une interruption temporaire du service et affecter les utilisateurs connectés. Il est donc conseillé de programmer un redémarrage de Dovecot uniquement lorsque cela est absolument nécessaire, par exemple lorsque vous apportez des modifications importantes à la configuration ou lorsque vous effectuez des mises à jour du logiciel Dovecot. Il est également important de planifier le redémarrage de Dovecot en dehors des heures de pointe pour minimiser l'impact sur les utilisateurs. sudo systemctl restart dovecot\n- Voici un exemple de script bash pour tester la date d'expiration de et pour redémarrer le service Dovecot s'il est à moins de 10 jours de l'expiration, et pour envoyer un e-mail à si le redémarrage n'a pas résolu le problème : \n!/bin/bash delayexpiration=10 Tester la date d'expiration de mx.exemple.fr:993\nexpirationdate=$(echo | openssl sclient -connect mx.exemple.fr:993 -servername mx.exemple.fr 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2) Convertir la date d'expiration en timestamp\nexpirationtimestamp=$(date -d \"$expirationdate\" +%s) Calculer le nombre de jours restants jusqu'à l'expiration\ntodaytimestamp=$(date +%s)\ndiff=$[^note: (expirationtimestamp - todaytimestamp) / 86400 ] Si le nombre de jours restants est inférieur à 10, redémarrer Dovecot\nif [ $diff -lt $delayexpiration ]; then\n sudo systemctl restart dovecot\n # Tester à nouveau la date d'expiration de mx.exemple.fr:993\n newexpirationdate=$(echo | openssl sclient -connect mx.exemple.fr:993 -servername mx.exemple.fr 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)\n newexpirationtimestamp=$(date -d \"$newexpirationdate\" +%s)\n newdiff=$[^note: (newexpirationtimestamp - todaytimestamp) / 86400 ]\n # Si la date d'expiration n'a pas été résolue, envoyer un e-mail à toto@exemple.fr\n if [ $newdiff -lt $delayexpiration ]; then\n echo \"Le certificat de mx.exemple.fr:993 est proche de son expiration.\" | mail -s \"[ALERTE] Expiration SSL mx.exemple.fr:993 - $newdiff jours restants\" toto@exemple.fr\n fi\nfi\n Vous pouvez planifier ce script en utilisant crontab pour le faire exécuter à intervalles réguliers. Par exemple, vous pouvez le faire exécuter tous les jours à 4 heures du matin en ajoutant la ligne suivante à votre crontab :"}]