2cb19809c627afc16e8534535beef8b30885568d
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2cb19809c6 |
doc(reseau) — le confort LAN ne se règle pas dans Traefik : mesure, pièges, voie retenue
Demande : « ne pas avoir le basic auth Traefik quand on est sur le Wi-Fi partagé avec le homelab ». La réponse intuitive — une règle `ClientIP(192.168.1.0/24)` — ne peut pas marcher, et la variante « je regarde CF-Connecting-IP » est un contournement d'authentification. Ce commit écrit la mesure pour qu'on ne re-découvre ni l'une ni l'autre. Mesuré (2026-07-28, homelab) : - `kadans.arcodange.fr` résout vers Cloudflare MÊME depuis le LAN, et redescend par le tunnel cloudflared. L'adresse de socket vue par Traefik est donc toujours celle d'un pod, en 10.42.x.x. - Traefik SAIT qui est le vrai client (journal d'accès : l'IPv6 de la maison, `2a01:cb04:dff:cf00::/64` — pas l'IPv4 qu'`ipify` injecte dans `localIp`), car l'entrypoint `web` fait confiance aux en-têtes venant de 10.42.0.0/16. - Mais le matcher de routeur `ClientIP()`, lui, juge la SOCKET. Prouvé par trois routeurs temporaires vers un Service sans endpoint (503 = règle matchée, 401 = repli sur le routeur normal) : témoin 503, `ClientIP(<IPv6 maison>)` 401, `ClientIP(10.42.0.0/16)` 503. Sondes retirées après mesure. D'où deux pièges, écrits là où on les rencontrerait : - `localIp@file` sur un routeur `.fr` laisserait entrer Internet entier, parce que `10.42.0.0/16` est dans son `sourceRange` et qu'`ipAllowList` juge lui aussi la socket. Vérifié : aucun routeur `.fr` ne le porte aujourd'hui — le piège est latent, et les cinq endroits d'où on pourrait le recopier (2 gabarits `.fr`, 3 values `.lab`) portent désormais l'avertissement. - Un en-tête posé par le client ne peut pas piloter une exemption d'auth : Cloudflare ne retire pas les en-têtes inconnus, et Traefik reste joignable en direct sur 192.168.1.201. Voie retenue, et pourquoi celle-là : la décision « suis-je à la maison ? » doit être prise là où la vraie IP est native et non falsifiable, donc au bord, chez Cloudflare. Une règle de transformation y pré-remplit l'en-tête `Authorization` pour les IP du foyer. Traefik ne bouge pas, aucun certificat public à produire, aucun changement DNS. Surface d'attaque ajoutée : AUCUNE — `kadans:kkadans` est déjà en clair dans le chart de kadans, Cloudflare ne fait que le taper à notre place. Et quand l'IP du foyer dérive, la règle cesse de matcher : le navigateur redemande le mot de passe. Dégradation douce, pas de panne. Le doc écrit l'action Cloudflare mot pour mot (expression, en-tête, valeur, et l'équivalent Terraform pour `cms/cloudflare`) plutôt que de la supposer faite, avec les deux commandes qui la vérifient — et nomme le repli si Cloudflare refuse de modifier `Authorization` : Cloudflare Access avec une politique de bypass, PAS un en-tête secret. Enfin, un contre-exemple utile : le bouncer CrowdSec, lui, juge la VRAIE IP (journal à l'appui). Son `clientTrustedIPs` contient `10.42.0.0/16` sans que ce soit un trou — noté pour que personne ne « corrige » cette ligne en croyant y reproduire le piège. ⚠ Aucun des réglages en cause ne vit dans ce dépôt : les valeurs Helm de Traefik, `dynamic.yaml`/`localIp` et le Middleware crowdsec sont dans `factory` (ansible), le tunnel et le DNS dans `cms`. Ce dépôt reçoit la mesure et les garde-fous parce que c'est lui qui héberge les gabarits `.fr` et les consommateurs de `localIp@file`. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01GdUCA5Uz8QyMwa2P4Pg2hK |
||
|
|
7074a94d7e |
docs(minio) — le raisonnement part dans l'ADR, le code garde ce qui protège
Helm Charts / Detect changed charts (push) Successful in 22s
Helm Charts / Detect changed charts (pull_request) Successful in 16s
MinIO / Auth with gitea for vault (push) Failing after 8m33s
MinIO / Tofu - minio IAC (push) Has been skipped
MinIO / Auth with gitea for vault (pull_request) Failing after 8m32s
MinIO / Tofu - minio IAC (pull_request) Has been skipped
Hashicorp Vault / Auth with gitea for vault (pull_request) Failing after 8m32s
Hashicorp Vault / Tofu - Vault IAC (pull_request) Has been skipped
Helm Charts / Library charts tool (push) Has been skipped
Helm Charts / Library charts tool (pull_request) Has been skipped
Hashicorp Vault / Auth with gitea for vault (push) Failing after 8m31s
Hashicorp Vault / Tofu - Vault IAC (push) Has been skipped
Helm Charts / Application charts pgcat (push) Has been skipped
Helm Charts / Application charts pgcat (pull_request) Has been skipped
Les décisions de conception (qui déclare, qui détient, pourquoi les octets ne passent pas par l'API) vivent désormais dans `factory/doc/adr/20260726-stockage-objet-minio.md`. Le code ne garde que ce qu'un relecteur ne peut pas deviner et qui l'empêcherait de casser quelque chose : l'absence VOLONTAIRE de s3:GetObject/PutObject dans la politique du provisionneur, l'absence VOLONTAIRE de basic-auth sur l'ingress S3, le caractère inconditionnel de la règle Vault, et l'avertissement sur les noms d'actions MinIO non éprouvés. Chaque fichier pointe l'ADR. 283 → 230 lignes sur minio/iac. tofu fmt propre, tofu validate réussi sur les deux racines. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01CoafGWmRVESaWX819USUUA |
||
|
|
1490f4c514 |
feat(minio) — exposer l'API S3 en HTTPS public (s3.arcodange.fr) + CORS de la PWA
Helm Charts / Detect changed charts (push) Successful in 1m6s
Helm Charts / Detect changed charts (pull_request) Successful in 1m5s
Helm Charts / Library charts tool (push) Has been skipped
Helm Charts / Library charts tool (pull_request) Has been skipped
Helm Charts / Application charts pgcat (push) Has been skipped
Helm Charts / Application charts pgcat (pull_request) Has been skipped
Sans ça, la synchronisation des vidéos ne peut pas marcher, et ce sont des faits du navigateur : une page servie en https ne peut pas émettre de requête vers http:// (contenu mixte), et `.lab` n'est pas résolvable hors du LAN. L'ingress existant est en entrypoint `web` sans TLS, sur un domaine interne — donc inutilisable depuis kadans.arcodange.fr, en déplacement COMME à la maison. Même motif que grafana/templates/ingress-public.yaml : entrypoint `web`, TLS terminé par le tunnel Cloudflare (wildcard *.arcodange.fr), middleware crowdsec. Le `.lab` interne reste inchangé. PAS de basic-auth, contrairement à kadans-public : une requête S3 porte sa propre signature (SigV4), et un défi HTTP Basic casserait le PUT présigné auquel le navigateur ne peut pas répondre. L'autorisation vient de l'URL signée et de sa durée de vie courte. CORS déclaré sur les origines EXACTES de la PWA (.fr et .lab), jamais « * » : une URL présignée qui fuiterait serait sinon rejouable depuis n'importe quel site. Sans cette liste, le préflight OPTIONS échoue et le PUT ne part même pas. ⚠ Signalé, NON mesuré : le tunnel Cloudflare plafonne probablement le corps d'une requête (~100 Mo sur les offres gratuites). À éprouver avec un vrai téléversement. Contexte utile : sur le corpus réel du fondateur (707 vidéos, ~2 ans), la durée MOYENNE est de 53 s et deux vidéos seulement dépassent 5 min — au palier « travail » de l'ADR-018, 100 Mo valent ~29 min de cours. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01CoafGWmRVESaWX819USUUA |
||
|
|
84edfc8640 |
feat(minio) — stockage objet S3 du homelab (brique partagée de tools)
Helm Charts / Detect changed charts (push) Successful in 16s
Helm Charts / Detect changed charts (pull_request) Successful in 15s
Helm Charts / Library charts tool (push) Has been skipped
Helm Charts / Library charts tool (pull_request) Has been skipped
MinIO / Tofu - minio IAC (pull_request) Has been skipped
MinIO / Auth with gitea for vault (pull_request) Failing after 8m32s
Helm Charts / Application charts pgcat (pull_request) Has been skipped
Helm Charts / Application charts pgcat (push) Has been skipped
Le fondateur : « on déploie MinIO dans le repo tools du homelab non ? » — oui, c'est bien le pattern : le dossier tools/ porte les briques PARTAGÉES (pgbouncer, clickhouse, grafana…) et le namespace tools les fait tourner ; les charts applicatifs vivent dans le repo de leur app. Décidé de longue date côté produit, jamais déployé : ADR-012 « MinIO local d'abord » (bascule R2 à 100+ utilisateurs / 10 To par mois), ADR-013 (le gratuit reste local-first, MinIO sert les paliers payants). Vérifié avant d'écrire : aucun pod ni service MinIO dans le cluster. Le chart suit la recette du repo (dépendance à la library "tool" + chart amont en SubChart, deux gardes dans templates/) : - mode STANDALONE, 1 réplique : ce qui transite est DÉRIVÉ (le master d'une vidéo reste sur l'appareil de son propriétaire, ADR-018) et Longhorn réplique déjà le volume — l'erasure coding distribué coûterait de la RAM que des Pi 5 n'ont pas à dépenser pour ça ; - 50 Gi sur longhorn ≈ 250 h de cours au palier « travail » (360p, 3,4 Mo/min) ; ⚠ Longhorn réplique : compter ×3 sur la capacité avant d'augmenter ; - ressources bornées (512 Mi / 2 Gi) : la limite protège les voisins de tools ; - API s3.arcodange.lab + console minio.arcodange.lab (Traefik) ; - bucket kadans-videos PRIVÉ — l'accès passera par des URL signées (ADR-0002) ; - identifiants JAMAIS au dépôt : iac/ les génère dans Vault (kvv2/minio/config), le Vault Secrets Operator les matérialise, le chart les lit via existingSecret. Le SA du pod est nommé "minio" (pas le "minio-sa" amont) car le module app_roles borne l'authentification au SA portant le nom de l'app. ⚠ Le workflow minio.yaml écrit ses triggers EN TOUTES LETTRES : une ancre YAML dans un trigger Gitea Actions fait taire push ET pull_request en silence (vécu sur arcodange/kadans, issues 113→117). Les workflows plausible/crowdsec/vault de ce repo en utilisent encore — à vérifier séparément, c'est probablement pourquoi ils ne partent qu'à la main. Vérifié : helm dependency update + helm template (11 ressources rendues, SA et VaultAuth cohérents) + helm lint ✓. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CoafGWmRVESaWX819USUUA |