Code source wiki de ChoixTechniques
Afficher les derniers auteurs
| author | version | line-number | content |
|---|---|---|---|
| 1 | {{toc depth="2"/}} | ||
| 2 | |||
| 3 | = Choix techniques = | ||
| 4 | |||
| 5 | Cette page explique **pourquoi** l'infrastructure est construite ainsi. Le « comment » est dans les pages de chaque service. Pour chaque choix, on trouve ce qui a été décidé, la raison, ce qui a été écarté et les limites acceptées. | ||
| 6 | |||
| 7 | Un choix qui n'a plus de raison d'être doit être revu, pas conservé par habitude. | ||
| 8 | |||
| 9 | == Contraintes de départ == | ||
| 10 | |||
| 11 | Ces contraintes ne sont pas des choix, mais elles en expliquent plusieurs. | ||
| 12 | |||
| 13 | * **Box opérateur sans hairpin NAT** : depuis le réseau local, le domaine public ne ramène pas vers le serveur. | ||
| 14 | * **IP publique dynamique** : il faut un DNS dynamique. | ||
| 15 | * **Raspberry Pi en Wi-Fi uniquement** : pas de câble possible jusqu'à lui. Débit faible et lien instable sur les gros transferts. | ||
| 16 | * **Matériel domestique** : deux machines, pas de redondance. | ||
| 17 | |||
| 18 | == Architecture == | ||
| 19 | |||
| 20 | === Deux machines, deux rôles === | ||
| 21 | |||
| 22 | **Choix** : le serveur principal porte tout ce qui est exposé à Internet. Le Raspberry Pi reste sur le réseau local. | ||
| 23 | |||
| 24 | **Pourquoi** : le dépôt de sauvegarde et le DNS local ne doivent pas tomber avec le serveur exposé. Si le serveur est compromis ou détruit, les sauvegardes sont ailleurs. | ||
| 25 | |||
| 26 | **Limites** : l'accès distant au Pi passe par le serveur principal ([[Sshwifty>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Sshwifty.WebHome]], ou [[Jellyfin>>Wiki Batcave John.Infrastructure.RaspberryPi.Jellyfin.WebHome]] derrière le [[reverse proxy>>Wiki Batcave John.Infrastructure.ServeurPrincipal.ReverseProxy.WebHome]]). Si le serveur est en panne, le Pi n'est plus joignable de l'extérieur. | ||
| 27 | |||
| 28 | === Tout en conteneurs, piloté par Portainer === | ||
| 29 | |||
| 30 | **Choix** : les services tournent sous Docker, déployés en stacks [[Portainer>>Wiki Batcave John.Infrastructure.Portainer.WebHome]]. Un seul Portainer, sur le serveur principal, pilote les deux machines ; le Pi a un agent. | ||
| 31 | |||
| 32 | **Pourquoi** : une interface unique pour les deux machines, et des stacks qui se relisent et se redéploient. Portainer en version LTS pour limiter les changements de comportement. | ||
| 33 | |||
| 34 | **Limites** : quelques conteneurs viennent des modèles d'applications de Portainer et ne sont pas des stacks. Ils sont signalés dans leur page ; leur configuration n'est pas versionnée comme celle d'une stack. | ||
| 35 | |||
| 36 | == Exposition et sécurité == | ||
| 37 | |||
| 38 | === SWAG comme reverse proxy === | ||
| 39 | |||
| 40 | **Choix** : [[SWAG>>Wiki Batcave John.Infrastructure.ServeurPrincipal.SWAG.WebHome]] (nginx de LinuxServer.io). | ||
| 41 | |||
| 42 | **Pourquoi** : il regroupe nginx, le certificat Let's Encrypt wildcard par validation DNS et des modules prêts à l'emploi (bouncer CrowdSec, tableau de bord). Un certificat wildcard évite de publier chaque sous-domaine dans les journaux de transparence des certificats. | ||
| 43 | |||
| 44 | **Limites** : SWAG est exclu des mises à jour automatiques ; chaque mise à jour se fait à la main après lecture des notes de version. | ||
| 45 | |||
| 46 | === Authelia devant les services === | ||
| 47 | |||
| 48 | **Choix** : [[Authelia>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Authelia.WebHome]] en authentification commune, avec second facteur. | ||
| 49 | |||
| 50 | **Pourquoi** : les services qui n'ont pas de bonne authentification, ou pas d'authentification du tout, ne sont jamais exposés directement. | ||
| 51 | |||
| 52 | **Limites** : Authelia ne recharge pas sa configuration à chaud ; il faut redémarrer le conteneur. | ||
| 53 | |||
| 54 | === CrowdSec plutôt qu'un simple fail2ban sur le serveur === | ||
| 55 | |||
| 56 | **Choix** : [[CrowdSec>>Wiki Batcave John.Infrastructure.ServeurPrincipal.CrowdSec.WebHome]] avec le bouncer intégré à SWAG. Le captcha passe par Cloudflare Turnstile. | ||
| 57 | |||
| 58 | **Pourquoi** : CrowdSec analyse les journaux de plusieurs services et bénéficie des listes de blocage communautaires. Le bouncer dans SWAG agit avant que la requête n'atteigne le service. Turnstile a été préféré à reCAPTCHA. | ||
| 59 | |||
| 60 | **Limites** : | ||
| 61 | * Turnstile impose de désactiver HTTP/2 côté SWAG. | ||
| 62 | * Sur Debian 13, sans rsyslog, il n'y a pas de fichier de journal d'authentification : CrowdSec ne voit pas SSH. rsyslog est donc réinstallé. | ||
| 63 | |||
| 64 | Le Raspberry Pi, lui, n'est pas exposé : un [[fail2ban>>Wiki Batcave John.Infrastructure.RaspberryPi.fail2ban.WebHome]] limité à SSH y suffit. | ||
| 65 | |||
| 66 | === docker-socket-proxy pour l'accès à l'API Docker === | ||
| 67 | |||
| 68 | **Choix** : aucun conteneur ne monte le socket Docker directement pour la surveillance. [[docker-socket-proxy>>Wiki Batcave John.Infrastructure.ServeurPrincipal.DockerSocketProxy.WebHome]] expose l'API en lecture seule, sur un réseau Docker dédié partagé uniquement avec n8n. | ||
| 69 | |||
| 70 | **Pourquoi** : accéder au socket Docker revient à être root sur l'hôte. Le proxy limite l'accès à la liste des conteneurs, sans aucune écriture. | ||
| 71 | |||
| 72 | == DNS == | ||
| 73 | |||
| 74 | === DuckDNS === | ||
| 75 | |||
| 76 | **Choix** : un sous-domaine [[DuckDNS>>Wiki Batcave John.Infrastructure.ServeurPrincipal.DuckDNS.WebHome]] mis à jour par un conteneur. | ||
| 77 | |||
| 78 | **Pourquoi** : gratuit, simple, et compatible avec la validation DNS de Let's Encrypt pour le certificat wildcard. | ||
| 79 | |||
| 80 | **Limites acceptées** : les serveurs DNS de DuckDNS sont parfois instables et le TTL est court, ce qui provoque des échecs d'accès intermittents. | ||
| 81 | |||
| 82 | **Alternative envisagée** : un domaine payant avec DNS chez Cloudflare. Plus fiable, pas encore fait. | ||
| 83 | |||
| 84 | === AdGuard Home pour le hairpin NAT === | ||
| 85 | |||
| 86 | **Choix** : [[AdGuard Home>>Wiki Batcave John.Infrastructure.RaspberryPi.AdGuard Home.WebHome]] sur le Pi, avec une réécriture DNS wildcard du domaine public vers l'IP locale du serveur. | ||
| 87 | |||
| 88 | **Pourquoi** : réglé une fois pour tous les appareils du réseau, y compris les téléphones. | ||
| 89 | |||
| 90 | **Alternative écartée** : une entrée dans ##/etc/hosts## sur chaque machine. Ça marche en dépannage, mais ça ne couvre ni les téléphones ni les nouveaux appareils. | ||
| 91 | |||
| 92 | **Limites** : si le Pi tombe, la résolution locale du domaine tombe avec lui. | ||
| 93 | |||
| 94 | == Mises à jour == | ||
| 95 | |||
| 96 | === Watchtower, version fork === | ||
| 97 | |||
| 98 | **Choix** : le fork ##nickfedor/watchtower## sur les deux machines, mise à jour planifiée la nuit. Détails : [[Watchtower>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Watchtower.WebHome]]. | ||
| 99 | |||
| 100 | **Pourquoi** : le projet d'origine n'est plus maintenu. | ||
| 101 | |||
| 102 | **Limites** : | ||
| 103 | * Le fork refuse de démarrer avec ##--rolling-restart## quand un conteneur a un ##depends_on## ; l'option est donc retirée. | ||
| 104 | * Le fork n'a pas d'API HTTP : les notifications passent par n8n (voir ci-dessous). | ||
| 105 | |||
| 106 | === Exclusions de la mise à jour automatique === | ||
| 107 | |||
| 108 | **Choix** : le reverse proxy, l'authentification, CrowdSec et les bases de données critiques sont exclus par le label ##com.centurylinklabs.watchtower.enable=false##. | ||
| 109 | |||
| 110 | **Pourquoi** : une mise à jour ratée de ces briques coupe l'accès à tout le reste, ou peut abîmer des données. Elles se mettent à jour à la main, notes de version lues. | ||
| 111 | |||
| 112 | === Bases de données épinglées sur une version majeure === | ||
| 113 | |||
| 114 | **Choix** : chaque image de base de données porte une version majeure explicite, jamais ##latest##. | ||
| 115 | |||
| 116 | **Pourquoi** : une montée de version majeure de MariaDB ou PostgreSQL peut demander une migration des fichiers. Épinglée, la base ne reçoit automatiquement que des correctifs mineurs. | ||
| 117 | |||
| 118 | **Conséquence** : les montées de version majeure sont planifiées, avec une copie des fichiers bruts avant l'opération. | ||
| 119 | |||
| 120 | === Notifications de mises à jour par n8n === | ||
| 121 | |||
| 122 | **Choix** : un workflow [[n8n>>Wiki Batcave John.Infrastructure.ServeurPrincipal.n8n.WebHome]] interroge docker-socket-proxy à intervalle régulier et envoie les changements sur Telegram. | ||
| 123 | |||
| 124 | **Pourquoi** : le fork de Watchtower n'offre pas d'API, et n8n était déjà en place. | ||
| 125 | |||
| 126 | == Sauvegarde == | ||
| 127 | |||
| 128 | === Plakar vers le Raspberry Pi === | ||
| 129 | |||
| 130 | **Choix** : Plakar sur le serveur principal envoie chaque nuit vers un dépôt sur le Pi, en SFTP. Détails : [[Sauvegarde>>Wiki Batcave John.Infrastructure.Sauvegarde.WebHome]]. | ||
| 131 | |||
| 132 | **Pourquoi** : | ||
| 133 | * Plakar déduplique et chiffre : après la première sauvegarde complète, les suivantes ne transfèrent que les changements, ce qui compte avec le débit Wi-Fi du Pi. | ||
| 134 | * Le dépôt est sur une autre machine que les données. | ||
| 135 | * Plakar est un logiciel libre français. | ||
| 136 | |||
| 137 | **Limites** : les deux machines sont au même endroit. Il n'y a pas encore de copie hors site. | ||
| 138 | |||
| 139 | === Exports SQL avant chaque sauvegarde === | ||
| 140 | |||
| 141 | **Choix** : chaque base est exportée en SQL juste avant la sauvegarde. Les dossiers de données des bases sont exclus. | ||
| 142 | |||
| 143 | **Pourquoi** : copier les fichiers d'une base en cours d'écriture donne une copie potentiellement incohérente. Un export SQL est cohérent et se restaure même sur une version différente du moteur. | ||
| 144 | |||
| 145 | === Utilisateur SFTP dédié === | ||
| 146 | |||
| 147 | **Choix** : le serveur se connecte au Pi avec un utilisateur réservé à la sauvegarde, limité à SFTP par ##ForceCommand internal-sftp##. | ||
| 148 | |||
| 149 | **Pourquoi** : si la clé de sauvegarde fuite, elle ne donne pas de shell sur le Pi. | ||
| 150 | |||
| 151 | === SSD plutôt que carte SD === | ||
| 152 | |||
| 153 | **Choix** : le dépôt est sur un SSD USB, pas sur la carte SD du Pi. | ||
| 154 | |||
| 155 | **Pourquoi** : une carte SD supporte mal les écritures répétées et volumineuses. | ||
| 156 | |||
| 157 | **Limites** : le pont USB du boîtier décroche sous forte charge d'écriture. Contournement en place (UAS désactivé, parallélisme réduit) ; un hub USB alimenté est prévu. Détails : [[SSD de stockage>>Wiki Batcave John.Infrastructure.RaspberryPi.SSD.WebHome]]. | ||
| 158 | |||
| 159 | == Système == | ||
| 160 | |||
| 161 | === Debian stable sur les deux machines === | ||
| 162 | |||
| 163 | **Choix** : Debian 13 sur le serveur et sur le Pi, y compris à la place de Raspberry Pi OS. | ||
| 164 | |||
| 165 | **Pourquoi** : préférence pour Debian. Raspberry Pi OS n'est qu'une adaptation de Debian : autant partir directement de la distribution d'origine, et avoir le même système et les mêmes habitudes sur les deux machines. | ||
| 166 | |||
| 167 | === Dépôt Raspberry Pi limité par pinning === | ||
| 168 | |||
| 169 | **Choix** : le dépôt Raspberry Pi est actif sur le Pi, mais un pinning APT le limite au noyau, au firmware et aux outils raspi. Détails : [[Noyau et dépôt Raspberry Pi>>Wiki Batcave John.Infrastructure.RaspberryPi.Noyau et dépôt Raspberry Pi.WebHome]]. | ||
| 170 | |||
| 171 | **Pourquoi** : garder Debian pour tout le reste, tout en recevant les mises à jour du noyau et du firmware propres au Pi. Sans ce dépôt, le noyau et le firmware restent figés. | ||
| 172 | |||
| 173 | === Noyau Zabbly sur le serveur === | ||
| 174 | |||
| 175 | **Choix** : le noyau mainline de Zabbly à la place du noyau Debian. Détails : [[Noyau Zabbly>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Noyau Zabbly.WebHome]]. | ||
| 176 | |||
| 177 | **Pourquoi** : historique. À la mise en service du serveur, certains pilotes nécessaires n'étaient pas encore disponibles dans le noyau Debian. | ||
| 178 | |||
| 179 | **Limites** : un dépôt tiers de plus dans la chaîne de confiance. | ||
| 180 | |||
| 181 | **À réévaluer** : le noyau Debian a évolué depuis. Si les pilotes concernés y sont maintenant, le retour au noyau Debian supprime un dépôt tiers. | ||
| 182 | |||
| 183 | === Pas de pip dans le Python système === | ||
| 184 | |||
| 185 | **Choix** : pipx pour les outils en ligne de commande, un venv par script. Voir les règles communes de la page [[Infrastructure>>Wiki Batcave John.Infrastructure.WebHome]]. | ||
| 186 | |||
| 187 | **Pourquoi** : une montée de version de Debian change la version de Python et casse tout ce qui a été installé avec pip dans le Python système. | ||
| 188 | |||
| 189 | === Peu de dépôts tiers === | ||
| 190 | |||
| 191 | **Choix** : un paquet disponible dans Debian s'installe depuis Debian. Un dépôt tiers n'est gardé que s'il apporte quelque chose d'introuvable ailleurs. | ||
| 192 | |||
| 193 | **Pourquoi** : chaque dépôt tiers est un point de confiance de plus, et il peut changer de conditions du jour au lendemain (passage payant, abandon). | ||
| 194 | |||
| 195 | === Reconstruction documentée plutôt qu'image disque === | ||
| 196 | |||
| 197 | **Choix** : pas d'image complète de la carte SD du Pi. La remise en service suit la page [[Reconstruction du Raspberry Pi>>Wiki Batcave John.Infrastructure.RaspberryPi.Reconstruction.WebHome]]. | ||
| 198 | |||
| 199 | **Pourquoi** : la configuration propre au Pi est sauvegardée chaque semaine par un script. Avec cette sauvegarde et la page de reconstruction, une carte neuve se remet en service sans dépendre d'une image qui vieillit à chaque modification. | ||
| 200 | |||
| 201 | == Alertes == | ||
| 202 | |||
| 203 | **Choix** : les alertes (sauvegarde, mises à jour de conteneurs) arrivent sur Telegram, par un bot. | ||
| 204 | |||
| 205 | **Pourquoi** : | ||
| 206 | * Envoyer un message ne demande qu'une requête HTTP vers l'API des bots (un simple ##curl## dans un script), sans serveur supplémentaire à héberger. | ||
| 207 | * n8n a un nœud Telegram intégré. | ||
| 208 | * La notification arrive sur le téléphone, même hors du réseau local. | ||
| 209 | * Gratuit. | ||
| 210 | |||
| 211 | **Alternatives écartées** : | ||
| 212 | * **E-mail** : il faut un serveur SMTP ou un relais, et les messages automatiques finissent souvent en spam. | ||
| 213 | * **Service auto-hébergé (ntfy, Gotify)** : hébergé sur le serveur principal, il tombe avec lui, alors que c'est justement là qu'on a besoin d'être prévenu. | ||
| 214 | |||
| 215 | **Limites** : | ||
| 216 | * Dépendance à un service tiers. Les messages de bot ne sont pas chiffrés de bout en bout : ils ne contiennent donc que des états (réussite, échec, nom du conteneur), jamais de secret ni de détail sensible. | ||
| 217 | * Le jeton du bot est un secret : il est stocké hors du script, dans un fichier lisible par root seulement. | ||
| 218 | * Si le serveur principal est complètement arrêté, aucun message ne part. **L'absence du message ✅ du matin est elle-même une alerte.** |