0 Votes

Code source wiki de Choix Techniques

Modifié par john le 2026/09/23 19:42

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
62 * Turnstile impose de désactiver HTTP/2 côté SWAG.
63 * 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é.
64
65 Le Raspberry Pi, lui, n'est pas exposé : un [[fail2ban>>Wiki Batcave John.Infrastructure.RaspberryPi.fail2ban.WebHome]] limité à SSH y suffit.
66
67 === docker-socket-proxy pour l'accès à l'API Docker ===
68
69 **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.
70
71 **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.
72
73 == DNS ==
74
75 === DuckDNS ===
76
77 **Choix** : un sous-domaine [[DuckDNS>>Wiki Batcave John.Infrastructure.ServeurPrincipal.DuckDNS.WebHome]] mis à jour par un conteneur.
78
79 **Pourquoi** : gratuit, simple, et compatible avec la validation DNS de Let's Encrypt pour le certificat wildcard.
80
81 **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.
82
83 **Alternative envisagée** : un domaine payant avec DNS chez Cloudflare. Plus fiable, pas encore fait.
84
85 === AdGuard Home pour le hairpin NAT ===
86
87 **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.
88
89 **Pourquoi** : réglé une fois pour tous les appareils du réseau, y compris les téléphones.
90
91 **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.
92
93 **Limites** : si le Pi tombe, la résolution locale du domaine tombe avec lui.
94
95 == Mises à jour ==
96
97 === Watchtower, version fork ===
98
99 **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]].
100
101 **Pourquoi** : le projet d'origine n'est plus maintenu.
102
103 **Limites** :
104
105 * Le fork refuse de démarrer avec ##--rolling-restart--##-- quand un conteneur a un ##depends_on## ; l'option est donc retirée.--
106 * Le fork n'a pas d'API HTTP : les notifications passent par n8n (voir ci-dessous).
107
108 === Exclusions de la mise à jour automatique ===
109
110 **Choix** : le reverse proxy, l'authentification, CrowdSec et les bases de données critiques sont exclus par le label ##com.centurylinklabs.watchtower.enable=false##.
111
112 **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.
113
114 === Bases de données épinglées sur une version majeure ===
115
116 **Choix** : chaque image de base de données porte une version majeure explicite, jamais ##latest##.
117
118 **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.
119
120 **Conséquence** : les montées de version majeure sont planifiées, avec une copie des fichiers bruts avant l'opération.
121
122 === Notifications de mises à jour par n8n ===
123
124 **Choix** : un workflow [[n8n>>Wiki Batcave John.Infrastructure.ServeurPrincipal.n8n.WebHome]] interroge docker-socket-proxy à intervalle régulier et envoie les changements sur Telegram.
125
126 **Pourquoi** : le fork de Watchtower n'offre pas d'API, et n8n était déjà en place.
127
128 == Sauvegarde ==
129
130 === Plakar vers le Raspberry Pi ===
131
132 **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]].
133
134 **Pourquoi** :
135
136 * 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.
137 * Le dépôt est sur une autre machine que les données.
138 * Plakar est un logiciel libre français.
139
140 **Limites** : les deux machines sont au même endroit. Il n'y a pas encore de copie hors site.
141
142 === Exports SQL avant chaque sauvegarde ===
143
144 **Choix** : chaque base est exportée en SQL juste avant la sauvegarde. Les dossiers de données des bases sont exclus.
145
146 **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.
147
148 === Utilisateur SFTP dédié ===
149
150 **Choix** : le serveur se connecte au Pi avec un utilisateur réservé à la sauvegarde, limité à SFTP par ##ForceCommand internal-sftp##.
151
152 **Pourquoi** : si la clé de sauvegarde fuite, elle ne donne pas de shell sur le Pi.
153
154 === SSD plutôt que carte SD ===
155
156 **Choix** : le dépôt est sur un SSD USB, pas sur la carte SD du Pi.
157
158 **Pourquoi** : une carte SD supporte mal les écritures répétées et volumineuses.
159
160 **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]].
161
162 == Système ==
163
164 === Debian stable sur les deux machines ===
165
166 **Choix** : Debian 13 sur le serveur et sur le Pi, y compris à la place de Raspberry Pi OS.
167
168 **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.
169
170 === Dépôt Raspberry Pi limité par pinning ===
171
172 **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]].
173
174 **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.
175
176 === Noyau Zabbly sur le serveur ===
177
178 **Choix** : le noyau mainline de Zabbly à la place du noyau Debian. Détails : [[Noyau Zabbly>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Noyau Zabbly.WebHome]].
179
180 **Pourquoi** : historique. À la mise en service du serveur, certains pilotes nécessaires n'étaient pas encore disponibles dans le noyau Debian.
181
182 **Limites** : un dépôt tiers de plus dans la chaîne de confiance.
183
184 **À 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.
185
186 === Pas de pip dans le Python système ===
187
188 **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]].
189
190 **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.
191
192 === Peu de dépôts tiers ===
193
194 **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.
195
196 **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).
197
198 === Reconstruction documentée plutôt qu'image disque ===
199
200 **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]].
201
202 **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.
203
204 == Alertes ==
205
206 **Choix** : les alertes (sauvegarde, mises à jour de conteneurs) arrivent sur Telegram, par un bot.
207
208 **Pourquoi** :
209
210 * 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.
211 * n8n a un nœud Telegram intégré.
212 * La notification arrive sur le téléphone, même hors du réseau local.
213 * Gratuit.
214
215 **Alternatives écartées** :
216
217 * **E-mail** : il faut un serveur SMTP ou un relais, et les messages automatiques finissent souvent en spam.
218 * **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.
219
220 **Limites** :
221
222 * 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.
223 * Le jeton du bot est un secret : il est stocké hors du script, dans un fichier lisible par root seulement.
224 * 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.**