0 Votes

Code source wiki de ChoixTechniques

Version 1.1 par john le 2026/09/23 19:41

Afficher les derniers auteurs
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.**