From 227b92fe4f42ca1b9a8eeb61dd8e2ff13568193c Mon Sep 17 00:00:00 2001 From: Melvin GABALI Date: Fri, 23 Jan 2026 00:05:04 +0100 Subject: [PATCH] delete external device --- apps/applicationset-external-devices.yaml | 52 -- apps/appproject-dev-endpoints.yaml | 28 -- docs/ARGO-CD-ENDPOINTS.md | 101 ---- docs/EXPORT-CERTIFICATS-EXTERNES.md | 252 ---------- docs/REVERSE-PROXY-EXTERNES.md | 471 ------------------ docs/TROUBLESHOOTING-EXTERNAL-DEVICES.md | 123 ----- helm/external-devices/dev/Chart.yaml | 7 - .../dev/templates/ingressroutes.yaml | 52 -- .../dev/templates/middlewares.yaml | 29 -- .../dev/templates/services.yaml | 47 -- helm/external-devices/dev/values.yaml | 33 -- scripts/patch-appproject-dev.sh | 45 ++ 12 files changed, 45 insertions(+), 1195 deletions(-) delete mode 100644 apps/applicationset-external-devices.yaml delete mode 100644 apps/appproject-dev-endpoints.yaml delete mode 100644 docs/ARGO-CD-ENDPOINTS.md delete mode 100644 docs/EXPORT-CERTIFICATS-EXTERNES.md delete mode 100644 docs/REVERSE-PROXY-EXTERNES.md delete mode 100644 docs/TROUBLESHOOTING-EXTERNAL-DEVICES.md delete mode 100644 helm/external-devices/dev/Chart.yaml delete mode 100644 helm/external-devices/dev/templates/ingressroutes.yaml delete mode 100644 helm/external-devices/dev/templates/middlewares.yaml delete mode 100644 helm/external-devices/dev/templates/services.yaml delete mode 100644 helm/external-devices/dev/values.yaml create mode 100644 scripts/patch-appproject-dev.sh diff --git a/apps/applicationset-external-devices.yaml b/apps/applicationset-external-devices.yaml deleted file mode 100644 index dfff6f7..0000000 --- a/apps/applicationset-external-devices.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: external-devices - namespace: argocd-ops -spec: - generators: - # Les certificats sont créés UNIQUEMENT dans le cluster OPS - # qui a cert-manager installé et accès à Internet pour Let's Encrypt - - merge: - generators: - # Premier générateur : scanne les répertoires Helm pour les certificats - - git: - repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git - revision: main - directories: - - path: "helm/external-devices/*" - # Deuxième générateur : lit la config OPS uniquement - - git: - repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git - revision: main - files: - - path: "configs/*/config.json" - mergeKeys: - - path.basename - template: - metadata: - name: external-devices-{{path.basename}} - annotations: - # Forcer ArgoCD à gérer les Endpoints - argocd.argoproj.io/sync-options: "ServerSideApply=true" - spec: - project: '{{path.basename}}' - source: - repoURL: '{{repository}}' - targetRevision: '{{targetRevision}}' - path: '{{helmPath}}/external-devices/{{path.basename}}' - helm: - valueFiles: - - values.yaml - destination: - name: '{{name}}' - namespace: 'traefik-{{path.basename}}' - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true - # ServerSideApply pour mieux gérer les Endpoints - - ServerSideApply=true - diff --git a/apps/appproject-dev-endpoints.yaml b/apps/appproject-dev-endpoints.yaml deleted file mode 100644 index 80a69b9..0000000 --- a/apps/appproject-dev-endpoints.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# AppProject pour inclure les Endpoints dans ArgoCD -# ⚠️ Ce fichier doit être appliqué manuellement ou via un autre mécanisme -# car les AppProjects ne sont pas gérés par ApplicationSet -# -# Usage: -# kubectl apply -f apps/appproject-dev-endpoints.yaml -# -# Ou modifiez le projet existant : -# kubectl patch appproject dev -n argocd-ops --type merge -p "$(cat apps/appproject-dev-endpoints.yaml)" - -apiVersion: argoproj.io/v1alpha1 -kind: AppProject -metadata: - name: dev - namespace: argocd-ops -spec: - # Inclure les Endpoints dans les ressources autorisées - namespaceResourceWhitelist: - - group: "" - kind: Endpoints - # Autoriser tous les namespaces (ou spécifiez traefik-dev) - sourceNamespaces: - - '*' - # Autoriser tous les clusters (ou spécifiez cluster-dev) - destinations: - - namespace: '*' - server: '*' - diff --git a/docs/ARGO-CD-ENDPOINTS.md b/docs/ARGO-CD-ENDPOINTS.md deleted file mode 100644 index dd9632d..0000000 --- a/docs/ARGO-CD-ENDPOINTS.md +++ /dev/null @@ -1,101 +0,0 @@ -# Configuration ArgoCD pour gérer les Endpoints - -Par défaut, ArgoCD **exclut** les ressources de type `Endpoints` car elles sont généralement gérées automatiquement par Kubernetes. Pour que ArgoCD gère les Endpoints créés par Helm, il faut les inclure explicitement. - -## Solution 1 : Configurer le projet ArgoCD (Recommandé - OBLIGATOIRE) - -⚠️ **IMPORTANT** : Cette étape est **obligatoire**. Sans cette configuration, ArgoCD ne créera jamais les Endpoints, même avec les annotations dans les templates. - -Modifiez le projet ArgoCD pour inclure les Endpoints : - -```bash -# Récupérer la configuration du projet -kubectl get appproject dev -n argocd-ops -o yaml > project-dev.yaml - -# Ajouter resourceInclusions dans le projet -``` - -Ou via l'interface ArgoCD : -1. Allez dans **Settings > Projects** -2. Sélectionnez le projet `dev` -3. Dans **Resource Inclusion**, ajoutez : - - **Group** : (vide) - - **Kind** : `Endpoints` -4. Sauvegardez - -## Solution 2 : Configurer l'application directement - -Modifiez l'application `external-devices-dev` pour inclure les Endpoints : - -```bash -kubectl patch application external-devices-dev -n argocd-ops \ - --type merge \ - -p '{"spec":{"source":{"helm":{"includeCRDs":true}}}}' -``` - -Puis ajoutez la configuration dans l'Application : - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: external-devices-dev - namespace: argocd-ops -spec: - # ... autres configurations ... - source: - helm: - # Inclure les Endpoints - includeCRDs: true - # Ou utiliser resourceInclusions au niveau de l'application - # (nécessite ArgoCD 2.4+) -``` - -## Solution 3 : Modifier la configuration globale d'ArgoCD - -Modifiez le ConfigMap `argocd-cm` pour inclure les Endpoints globalement : - -```bash -kubectl edit configmap argocd-cm -n argocd-ops -``` - -Ajoutez : - -```yaml -resourceInclusions: | - - apiGroups: [""] - kinds: ["Endpoints"] - clusters: ["*"] -``` - -⚠️ **Attention** : Cette modification affecte **toutes** les applications ArgoCD. - -## Solution 4 : Utiliser une annotation sur l'Application - -Si vous utilisez ArgoCD 2.4+, vous pouvez ajouter une annotation directement sur l'Application : - -```yaml -metadata: - annotations: - argocd.argoproj.io/sync-options: IncludeEndpoints=true -``` - -## Vérification - -Après la configuration, vérifiez que les Endpoints sont gérés : - -```bash -# Vérifier que l'application voit les Endpoints -argocd app get external-devices-dev - -# Vérifier que les Endpoints sont créés -kubectl get endpoints omv-backend -n traefik-dev -``` - -## Recommandation - -Pour ce cas d'usage spécifique (Endpoints pour équipements externes), la **Solution 1** (configurer le projet) est recommandée car : -- Elle est limitée au projet `dev` -- Elle n'affecte pas les autres applications -- Elle est persistante et versionnée si vous utilisez GitOps pour les projets - diff --git a/docs/EXPORT-CERTIFICATS-EXTERNES.md b/docs/EXPORT-CERTIFICATS-EXTERNES.md deleted file mode 100644 index 131ecbe..0000000 --- a/docs/EXPORT-CERTIFICATS-EXTERNES.md +++ /dev/null @@ -1,252 +0,0 @@ -# Export des Certificats TLS pour Équipements Externes - -Ce guide explique comment exporter et utiliser les certificats TLS générés par cert-manager pour des équipements externes au cluster Kubernetes (pfSense, OpenMediaVault, NAS, etc.). - -## Vue d'ensemble - -Les certificats TLS sont générés par cert-manager dans le namespace `certificates-ops` et stockés sous forme de secrets Kubernetes. Pour les utiliser sur des équipements externes, il faut : - -1. **Exporter** le certificat depuis Kubernetes -2. **Convertir** au format approprié (PEM, PKCS12, etc.) -3. **Importer** dans l'équipement externe -4. **Automatiser** le renouvellement (optionnel) - -## Méthode 1 : Export manuel avec script - -### Prérequis - -- Accès au cluster Kubernetes avec `kubectl` -- `openssl` installé sur votre machine -- `base64` disponible (généralement inclus) - -### Export du certificat - -Utilisez le script `scripts/export-certificate.sh` : - -```bash -# Export en format PEM (par défaut) -./scripts/export-certificate.sh wildcard-prd-tls certificates-ops cluster-ops ./certs pem - -# Export en format PKCS12 (pour pfSense) -./scripts/export-certificate.sh wildcard-prd-tls certificates-ops cluster-ops ./certs pkcs12 -``` - -### Formats disponibles - -- **PEM** : Format standard, certificat et clé séparés (`.crt` et `.key`) -- **PKCS12/PFX** : Format conteneurisé avec certificat et clé dans un seul fichier (`.p12` ou `.pfx`) - -## Méthode 2 : Export direct avec kubectl - -### Export en format PEM - -```bash -# Définir les variables -SECRET_NAME="wildcard-prd-tls" -NAMESPACE="certificates-ops" -CONTEXT="cluster-ops" -OUTPUT_DIR="./certs" - -# Créer le répertoire -mkdir -p "$OUTPUT_DIR" - -# Extraire le certificat -kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" \ - -o jsonpath='{.data.tls\.crt}' | base64 -d > "$OUTPUT_DIR/certificate.crt" - -# Extraire la clé privée -kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" \ - -o jsonpath='{.data.tls\.key}' | base64 -d > "$OUTPUT_DIR/private.key" -``` - -### Conversion en PKCS12 - -```bash -# Créer un fichier PKCS12 (mot de passe optionnel) -openssl pkcs12 -export \ - -out "$OUTPUT_DIR/certificate.p12" \ - -inkey "$OUTPUT_DIR/private.key" \ - -in "$OUTPUT_DIR/certificate.crt" \ - -name "wildcard-prd" \ - -passout pass: # Laissez vide pour aucun mot de passe -``` - -## Import dans les équipements - -### pfSense - -#### Méthode 1 : Import PKCS12 (recommandé) - -1. Allez dans **System > Certificates** -2. Cliquez sur **Import** -3. Sélectionnez le fichier `.p12` ou `.pfx` -4. Entrez le mot de passe si nécessaire -5. Cliquez sur **Import** - -#### Méthode 2 : Import PEM séparé - -1. Allez dans **System > Certificates** -2. Cliquez sur **Add** -3. Dans **Method**, sélectionnez **Import an existing Certificate** -4. Collez le contenu du fichier `.crt` dans **Certificate data** -5. Collez le contenu du fichier `.key` dans **Private key data** -6. Cliquez sur **Save** - -#### Utilisation dans pfSense - -1. Allez dans **System > Certificates** -2. Sélectionnez le certificat importé -3. Utilisez-le dans : - - **System > Advanced > WebGUI** (certificat HTTPS) - - **Services > HAProxy** (certificats backend) - - **VPN > OpenVPN** (certificats serveur) - -### OpenMediaVault - -1. Allez dans **System > Certificates > SSL** -2. Cliquez sur **Import** -3. Sélectionnez le fichier certificat (`.crt` ou `.p12`) -4. Si vous utilisez PEM, importez séparément : - - **Certificate** : Fichier `.crt` - - **Private Key** : Fichier `.key` -5. Cliquez sur **Save** - -### Synology NAS - -1. Allez dans **Control Panel > Security > Certificate** -2. Cliquez sur **Add** -3. Sélectionnez **Import Certificate** -4. Choisissez le fichier (`.p12` ou `.crt` + `.key`) -5. Entrez le mot de passe si nécessaire -6. Cliquez sur **OK** - -### Autres équipements - -La plupart des équipements réseau supportent l'import de certificats en format : -- **PEM** : Certificat et clé séparés -- **PKCS12/PFX** : Format conteneurisé - -Consultez la documentation de votre équipement pour les détails spécifiques. - -## Automatisation du renouvellement - -Les certificats Let's Encrypt sont valides 90 jours et sont renouvelés automatiquement par cert-manager. Pour synchroniser automatiquement les certificats vers vos équipements externes : - -### Option 1 : Webhook cert-manager - -Créez un webhook qui s'exécute lors du renouvellement du certificat : - -```yaml -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: wildcard-prd-tls - namespace: certificates-ops -spec: - # ... configuration du certificat ... - secretTemplate: - annotations: - cert-manager.io/allow-direct-injection: "true" - # Webhook pour exporter automatiquement - # (nécessite un contrôleur personnalisé) -``` - -### Option 2 : Script CronJob - -Créez un CronJob qui vérifie périodiquement les certificats et les exporte : - -```yaml -apiVersion: batch/v1 -kind: CronJob -metadata: - name: export-certificates - namespace: certificates-ops -spec: - schedule: "0 0 * * *" # Tous les jours - jobTemplate: - spec: - template: - spec: - containers: - - name: export - image: alpine/k8s:1.33.0 - command: - - /bin/sh - - -c - - | - # Exporter le certificat - kubectl get secret wildcard-prd-tls -n certificates-ops \ - -o jsonpath='{.data.tls\.crt}' | base64 -d > /export/cert.crt - # Envoyer vers l'équipement externe (API, SCP, etc.) - # Exemple avec curl vers une API pfSense - # curl -X POST https://pfsense.example.com/api/certificates \ - # -F "cert=@/export/cert.crt" -``` - -### Option 3 : API REST - -Si votre équipement supporte une API REST (comme pfSense), créez un service qui : -1. Surveille les changements de secrets Kubernetes -2. Exporte automatiquement le certificat -3. Envoie une requête API à l'équipement pour mettre à jour le certificat - -## Sécurité - -⚠️ **Important** : Les certificats et clés privées sont des données sensibles. - -- **Ne stockez jamais** les clés privées dans Git -- **Supprimez** les fichiers exportés après import -- **Utilisez des permissions restrictives** sur les fichiers (chmod 600) -- **Chiffrez** les fichiers si vous devez les transférer - -```bash -# Permissions restrictives -chmod 600 certificate.key -chmod 644 certificate.crt - -# Supprimer après import -rm -f certificate.* -``` - -## Dépannage - -### Erreur "secret not found" - -Vérifiez que le secret existe : -```bash -kubectl get secret wildcard-prd-tls -n certificates-ops --context=cluster-ops -``` - -### Erreur "certificate expired" - -Les certificats sont renouvelés automatiquement. Vérifiez le statut : -```bash -kubectl get certificate wildcard-prd-tls -n certificates-ops --context=cluster-ops -``` - -### Format non reconnu par l'équipement - -Essayez de convertir dans un autre format : -```bash -# PEM vers DER -openssl x509 -in certificate.crt -out certificate.der -outform DER - -# PKCS12 avec mot de passe -openssl pkcs12 -export -out certificate.p12 \ - -inkey private.key -in certificate.crt \ - -passout pass:VOTRE_MOT_DE_PASSE -``` - -## Exemples de certificats disponibles - -Dans le namespace `certificates-ops` : - -- `wildcard-dev-tls` : `*.dev.gkdomaine.fr` -- `wildcard-rct-tls` : `*.rct.gkdomaine.fr` -- `wildcard-prd-tls` : `*.prd.gkdomaine.fr` - -Pour lister tous les certificats : -```bash -kubectl get certificates -n certificates-ops --context=cluster-ops -``` - diff --git a/docs/REVERSE-PROXY-EXTERNES.md b/docs/REVERSE-PROXY-EXTERNES.md deleted file mode 100644 index eca8453..0000000 --- a/docs/REVERSE-PROXY-EXTERNES.md +++ /dev/null @@ -1,471 +0,0 @@ -# Reverse Proxy Traefik pour Équipements Externes - -Ce guide explique comment utiliser Traefik comme reverse proxy pour exposer vos équipements externes (pfSense, OpenMediaVault, NAS, etc.) via les certificats TLS générés par cert-manager, **sans exporter les certificats**. - -## Avantages de cette approche - -✅ **Certificats gérés automatiquement** : Les certificats restent dans Kubernetes et sont renouvelés automatiquement par cert-manager -✅ **Configuration centralisée** : Tous les certificats sont gérés au même endroit -✅ **Pas d'export/import** : Plus besoin d'exporter et importer les certificats sur chaque équipement -✅ **Sécurité** : Les certificats ne quittent jamais le cluster Kubernetes -✅ **HTTPS automatique** : Traefik gère le TLS de bout en bout - -## Architecture - -``` -Internet/Intranet - ↓ -Traefik (Kubernetes) ← Certificat wildcard (*.dev.gkdomaine.fr) - ↓ HTTPS -Équipement externe (pfSense, OMV, NAS, etc.) ← HTTP (interne) -``` - -## Prérequis - -1. **Traefik déployé** dans le cluster avec accès aux certificats wildcard -2. **Certificats wildcard** générés (ex: `wildcard-prd-tls` pour la production) -3. **Accès réseau** depuis Traefik vers les équipements externes -4. **Service externe** accessible en HTTP (ou HTTPS avec certificat auto-signé) - -⚠️ **Note** : Pour le moment, seuls les services externes en **production** sont configurés. Les environnements dev et rct peuvent être ajoutés ultérieurement si nécessaire. - -## Configuration de base - -### 1. Créer un IngressRoute pour un équipement externe - -Créez un fichier `helm/traefik/dev/templates/external-pfsense.yaml` : - -```yaml ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: pfsense-external - namespace: traefik-dev -spec: - entryPoints: - - websecure - routes: - - match: Host(`pfsense.dev.gkdomaine.fr`) - kind: Rule - services: - - name: pfsense-backend - port: 80 - scheme: http - # Optionnel : si pfSense utilise HTTPS avec certificat auto-signé - # scheme: https - # serversTransport: pfsense-insecure - tls: - secretName: wildcard-dev-tls -``` - -### 2. Créer un Service Kubernetes pointant vers l'équipement externe - -Créez un fichier `helm/traefik/dev/templates/external-services.yaml` : - -```yaml ---- -# Service pour pfSense -apiVersion: v1 -kind: Service -metadata: - name: pfsense-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.1 # IP interne de pfSense - ports: - - port: 80 - targetPort: 80 - protocol: TCP ---- -# Service pour OpenMediaVault -apiVersion: v1 -kind: Service -metadata: - name: omv-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.10 # IP interne d'OpenMediaVault - ports: - - port: 80 - targetPort: 80 - protocol: TCP ---- -# Service pour Synology NAS -apiVersion: v1 -kind: Service -metadata: - name: synology-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.20 # IP interne du NAS - ports: - - port: 5000 # Port DSM - targetPort: 5000 - protocol: TCP -``` - -### 3. Configuration pour HTTPS backend (certificat auto-signé) - -Si votre équipement utilise HTTPS avec un certificat auto-signé, créez un `ServersTransport` : - -```yaml ---- -apiVersion: traefik.io/v1alpha1 -kind: ServersTransport -metadata: - name: pfsense-insecure - namespace: traefik-dev -spec: - insecureSkipVerify: true # Ignorer la vérification du certificat -``` - -## Exemples complets par équipement - -### pfSense - -```yaml ---- -apiVersion: v1 -kind: Service -metadata: - name: pfsense-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.1 # IP de pfSense - ports: - - port: 80 - targetPort: 80 ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: pfsense - namespace: traefik-dev -spec: - entryPoints: - - websecure - routes: - - match: Host(`pfsense.dev.gkdomaine.fr`) - kind: Rule - services: - - name: pfsense-backend - port: 80 - tls: - secretName: wildcard-dev-tls -``` - -**Configuration pfSense** : -1. Allez dans **System > Advanced > Admin Access** -2. Désactivez **HTTPS Redirect** (Traefik gère le HTTPS) -3. Optionnel : Configurez **Trusted Proxies** avec l'IP de Traefik pour les headers X-Forwarded-* - -### OpenMediaVault - -```yaml ---- -apiVersion: v1 -kind: Service -metadata: - name: omv-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.10 # IP d'OpenMediaVault - ports: - - port: 80 - targetPort: 80 ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: omv - namespace: traefik-dev -spec: - entryPoints: - - websecure - routes: - - match: Host(`omv.dev.gkdomaine.fr`) - kind: Rule - services: - - name: omv-backend - port: 80 - tls: - secretName: wildcard-dev-tls -``` - -**Configuration OpenMediaVault** : -1. Allez dans **System > Certificates > SSL** -2. Désactivez le certificat SSL (Traefik gère le HTTPS) -3. Configurez les **Trusted Proxies** dans **System > Network > General** - -### Synology NAS - -```yaml ---- -apiVersion: v1 -kind: Service -metadata: - name: synology-backend - namespace: traefik-dev -spec: - type: ExternalName - externalName: 192.168.1.20 # IP du NAS - ports: - - port: 5000 # Port DSM - targetPort: 5000 ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: synology - namespace: traefik-dev -spec: - entryPoints: - - websecure - routes: - - match: Host(`nas.dev.gkdomaine.fr`) - kind: Rule - services: - - name: synology-backend - port: 5000 - tls: - secretName: wildcard-dev-tls -``` - -**Configuration Synology** : -1. Allez dans **Control Panel > Network > DSM Settings** -2. Désactivez **HTTPS** (Traefik gère le HTTPS) -3. Configurez **Reverse Proxy** si nécessaire - -### Autres équipements - -Le principe est le même pour tous les équipements : - -1. **Créer un Service** de type `ExternalName` pointant vers l'IP de l'équipement -2. **Créer un IngressRoute** avec : - - Le domaine souhaité (ex: `equipement.dev.gkdomaine.fr`) - - Le service backend créé - - Le certificat wildcard (`wildcard-dev-tls`) - -## Configuration avancée - -### Headers personnalisés - -Pour passer des headers spécifiques à l'équipement backend : - -```yaml -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: pfsense-headers - namespace: traefik-dev -spec: - headers: - customRequestHeaders: - X-Forwarded-Proto: "https" - X-Real-IP: "" ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: pfsense - namespace: traefik-dev -spec: - entryPoints: - - websecure - routes: - - match: Host(`pfsense.dev.gkdomaine.fr`) - kind: Rule - services: - - name: pfsense-backend - port: 80 - middlewares: - - name: pfsense-headers - tls: - secretName: wildcard-dev-tls -``` - -### Authentification basique - -Pour ajouter une authentification HTTP Basic : - -```yaml -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: pfsense-auth - namespace: traefik-dev -spec: - basicAuth: - secret: pfsense-basic-auth # Secret contenant user:password hashé ---- -apiVersion: v1 -kind: Secret -metadata: - name: pfsense-basic-auth - namespace: traefik-dev -type: Opaque -data: - users: | # Format: user:password_hash (généré avec htpasswd) - admin:$apr1$... -``` - -### Redirection HTTP vers HTTPS - -Pour rediriger automatiquement HTTP vers HTTPS : - -```yaml -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: redirect-https - namespace: traefik-dev -spec: - redirectScheme: - scheme: https - permanent: true ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: pfsense-http-redirect - namespace: traefik-dev -spec: - entryPoints: - - web - routes: - - match: Host(`pfsense.dev.gkdomaine.fr`) - kind: Rule - middlewares: - - name: redirect-https - services: - - name: pfsense-backend - port: 80 -``` - -## Structure recommandée - -Créez un chart Helm dédié pour les équipements externes : - -``` -helm/ - └── external-devices/ - └── dev/ - ├── Chart.yaml - ├── values.yaml - └── templates/ - ├── services.yaml - ├── ingressroutes.yaml - └── middlewares.yaml -``` - -**values.yaml** (production) : - -```yaml -externalDevices: - pfsense: - enabled: true - domain: "pfsense.prd.gkdomaine.fr" - ip: "192.168.1.1" - port: 80 - tlsSecret: "wildcard-prd-tls" - - omv: - enabled: true - domain: "omv.prd.gkdomaine.fr" - ip: "192.168.1.10" - port: 80 - tlsSecret: "wildcard-prd-tls" - - synology: - enabled: true - domain: "nas.prd.gkdomaine.fr" - ip: "192.168.1.20" - port: 5000 - tlsSecret: "wildcard-prd-tls" -``` - -## Vérification - -### Vérifier que les services sont créés - -```bash -kubectl get services -n traefik-dev | grep -E "pfsense|omv|synology" -``` - -### Vérifier que les IngressRoute sont créés - -```bash -kubectl get ingressroute -n traefik-dev -``` - -### Tester l'accès - -```bash -# Test depuis l'intérieur du cluster -curl -k https://pfsense.dev.gkdomaine.fr - -# Vérifier les logs Traefik -kubectl logs -n traefik-dev -l app.kubernetes.io/name=traefik --tail=50 -``` - -## Dépannage - -### Erreur "no endpoints available" - -Vérifiez que l'IP de l'équipement est correcte et accessible depuis les pods Traefik : - -```bash -# Depuis un pod Traefik -kubectl exec -n traefik-dev -it -- curl http://192.168.1.1 -``` - -### Erreur "certificate not found" - -Vérifiez que le secret TLS existe : - -```bash -kubectl get secret wildcard-prd-tls -n traefik-prd -``` - -### Équipement non accessible - -Vérifiez : -1. **Réseau** : L'IP est-elle accessible depuis les pods Traefik ? -2. **Firewall** : Le port est-il ouvert sur l'équipement ? -3. **Service** : Le service Kubernetes pointe-t-il vers la bonne IP/port ? - -## Sécurité - -⚠️ **Important** : - -1. **Restreindre l'accès** : Utilisez des NetworkPolicies pour limiter l'accès aux équipements -2. **Authentification** : Ajoutez une authentification (Basic Auth, OAuth, etc.) pour les équipements sensibles -3. **Whitelist IP** : Limitez l'accès aux IPs autorisées si possible -4. **Monitoring** : Surveillez les accès aux équipements via les logs Traefik - -## Avantages vs Export de certificats - -| Critère | Reverse Proxy | Export de certificats | -|---------|---------------|----------------------| -| Gestion des certificats | ✅ Automatique | ❌ Manuel | -| Renouvellement | ✅ Automatique | ❌ Manuel | -| Configuration | ✅ Centralisée | ❌ Par équipement | -| Sécurité | ✅ Certificats dans K8s | ⚠️ Certificats exportés | -| Complexité | ✅ Simple | ❌ Plus complexe | - -## Conclusion - -La solution reverse proxy avec Traefik est **recommandée** car elle : -- Simplifie la gestion des certificats -- Centralise la configuration -- Améliore la sécurité -- Réduit la maintenance - -Les équipements externes n'ont plus besoin de gérer les certificats TLS - Traefik s'en charge complètement ! - diff --git a/docs/TROUBLESHOOTING-EXTERNAL-DEVICES.md b/docs/TROUBLESHOOTING-EXTERNAL-DEVICES.md deleted file mode 100644 index 9491a9b..0000000 --- a/docs/TROUBLESHOOTING-EXTERNAL-DEVICES.md +++ /dev/null @@ -1,123 +0,0 @@ -# Dépannage - External Devices - -## Problème : "no available server" ou Endpoints manquants - -### Symptômes -- Erreur "no available server" dans le navigateur -- `kubectl get endpoints -backend` retourne "NotFound" -- `kubectl describe service -backend` montre `Endpoints: ` - -### Cause -Les Endpoints n'ont pas été créés. Cela peut arriver si : -1. ArgoCD n'a pas encore synchronisé les changements du template -2. Le template n'inclut pas les Endpoints -3. Les Endpoints ont été supprimés - -### Solution - -#### 1. Vérifier le statut ArgoCD - -```bash -# Vérifier le statut de l'application -argocd app get external-devices-dev - -# Vérifier si une synchronisation est nécessaire -argocd app diff external-devices-dev -``` - -#### 2. Forcer une synchronisation - -```bash -# Synchroniser l'application -argocd app sync external-devices-dev - -# Ou via kubectl si ArgoCD est dans le cluster -kubectl patch application external-devices-dev -n argocd-ops \ - -p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{"revision":"HEAD"}}}' \ - --type merge -``` - -#### 3. Vérifier que les Endpoints sont créés - -```bash -# Vérifier les Endpoints -kubectl get endpoints omv-backend -n traefik-dev - -# Vérifier le détail -kubectl get endpoints omv-backend -n traefik-dev -o yaml -``` - -Les Endpoints devraient contenir : -```yaml -subsets: - - addresses: - - ip: 10.78.20.107 # L'IP de votre équipement - ports: - - port: 80 - protocol: TCP -``` - -#### 4. Vérifier la connectivité - -Une fois les Endpoints créés, tester la connexion : - -```bash -# Depuis un pod Traefik -POD=$(kubectl get pods -n traefik-dev -l app.kubernetes.io/name=traefik -o jsonpath='{.items[0].metadata.name}') -kubectl exec -n traefik-dev -it $POD -- curl -v http://10.78.20.107:80 -``` - -### Vérification complète - -```bash -# 1. Service existe -kubectl get service omv-backend -n traefik-dev - -# 2. Endpoints existent -kubectl get endpoints omv-backend -n traefik-dev - -# 3. IngressRoute existe -kubectl get ingressroute omv -n traefik-dev - -# 4. Secret TLS existe -kubectl get secret wildcard-dev-tls -n traefik-dev - -# 5. Test de connectivité -kubectl exec -n traefik-dev -it $(kubectl get pods -n traefik-dev -l app.kubernetes.io/name=traefik -o jsonpath='{.items[0].metadata.name}') -- curl -v http://10.78.20.107:80 -``` - -## Problème : IP non accessible - -### Symptômes -- Endpoints créés mais erreur "connection refused" ou timeout -- `curl` depuis un pod Traefik échoue - -### Solution - -1. **Vérifier l'IP** : L'IP est-elle correcte dans `values.yaml` ? -2. **Vérifier le réseau** : L'IP est-elle accessible depuis les pods Traefik ? -3. **Vérifier le firewall** : Le port est-il ouvert sur l'équipement externe ? -4. **Vérifier le port** : Le port dans `values.yaml` correspond-il au port de l'équipement ? - -```bash -# Test depuis un pod Traefik -POD=$(kubectl get pods -n traefik-dev -l app.kubernetes.io/name=traefik -o jsonpath='{.items[0].metadata.name}') -kubectl exec -n traefik-dev -it $POD -- curl -v --connect-timeout 5 http://10.78.20.107:80 -``` - -## Problème : Certificat TLS manquant - -### Symptômes -- Erreur "certificate not found" dans les logs Traefik -- IngressRoute en erreur - -### Solution - -```bash -# Vérifier que le secret existe -kubectl get secret wildcard-dev-tls -n traefik-dev - -# Si le secret n'existe pas, vérifier qu'il est synchronisé depuis OPS -# Voir docs/tls-sync-wildcard.md -``` - diff --git a/helm/external-devices/dev/Chart.yaml b/helm/external-devices/dev/Chart.yaml deleted file mode 100644 index d547ad3..0000000 --- a/helm/external-devices/dev/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -name: external-devices -description: Chart pour exposer les équipements externes via Traefik reverse proxy -type: application -version: 0.1.0 -appVersion: "1.0" - diff --git a/helm/external-devices/dev/templates/ingressroutes.yaml b/helm/external-devices/dev/templates/ingressroutes.yaml deleted file mode 100644 index de9502d..0000000 --- a/helm/external-devices/dev/templates/ingressroutes.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- range $name, $device := .Values.externalDevices }} -{{- if $device.enabled }} ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: {{ $name }} - namespace: {{ $device.namespace | default $.Values.global.namespace }} - labels: - app: external-device - device: {{ $name }} -spec: - entryPoints: - - websecure - routes: - - match: Host(`{{ $device.domain }}`) - kind: Rule - services: - - name: {{ $name }}-backend - port: {{ $device.port }} - {{- if $device.basicAuth.enabled }} - middlewares: - - name: {{ $name }}-auth - {{- end }} - tls: - secretName: {{ $device.tlsSecret | default $.Values.global.tlsSecret }} -{{- if $.Values.global.redirectHttpToHttps }} ---- -# Redirection HTTP vers HTTPS -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: {{ $name }}-http-redirect - namespace: {{ $device.namespace | default $.Values.global.namespace }} - labels: - app: external-device - device: {{ $name }} -spec: - entryPoints: - - web - routes: - - match: Host(`{{ $device.domain }}`) - kind: Rule - middlewares: - - name: redirect-https - services: - - name: {{ $name }}-backend - port: {{ $device.port }} -{{- end }} -{{- end }} -{{- end }} - diff --git a/helm/external-devices/dev/templates/middlewares.yaml b/helm/external-devices/dev/templates/middlewares.yaml deleted file mode 100644 index e682214..0000000 --- a/helm/external-devices/dev/templates/middlewares.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if .Values.global.redirectHttpToHttps }} ---- -# Middleware pour rediriger HTTP vers HTTPS -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: redirect-https - namespace: {{ .Values.global.namespace }} -spec: - redirectScheme: - scheme: https - permanent: true -{{- end }} - -{{- range $name, $device := .Values.externalDevices }} -{{- if and $device.enabled $device.basicAuth.enabled }} ---- -# Middleware d'authentification basique pour {{ $name }} -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: {{ $name }}-auth - namespace: {{ $device.namespace | default $.Values.global.namespace }} -spec: - basicAuth: - secret: {{ $device.basicAuth.secretName }} -{{- end }} -{{- end }} - diff --git a/helm/external-devices/dev/templates/services.yaml b/helm/external-devices/dev/templates/services.yaml deleted file mode 100644 index 2f3f4e4..0000000 --- a/helm/external-devices/dev/templates/services.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- range $name, $device := .Values.externalDevices }} -{{- if $device.enabled }} ---- -# Service pour {{ $name }} -apiVersion: v1 -kind: Service -metadata: - name: {{ $name }}-backend - namespace: {{ $device.namespace | default $.Values.global.namespace }} - labels: - app: external-device - device: {{ $name }} - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/instance: {{ $.Release.Name }} - annotations: - argocd.argoproj.io/sync-wave: "-1" -spec: - type: ClusterIP - ports: - - port: {{ $device.port }} - targetPort: {{ $device.port }} - protocol: TCP ---- -# Endpoints pour {{ $name }} (pointe vers l'IP externe) -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ $name }}-backend - namespace: {{ $device.namespace | default $.Values.global.namespace }} - labels: - app: external-device - device: {{ $name }} - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/instance: {{ $.Release.Name }} - annotations: - argocd.argoproj.io/sync-wave: "0" - # Forcer ArgoCD à gérer cette ressource même si elle est normalement exclue - argocd.argoproj.io/sync-options: "ServerSideApply=true" -subsets: - - addresses: - - ip: {{ $device.ip }} - ports: - - port: {{ $device.port }} - protocol: TCP -{{- end }} -{{- end }} - diff --git a/helm/external-devices/dev/values.yaml b/helm/external-devices/dev/values.yaml deleted file mode 100644 index be4dc40..0000000 --- a/helm/external-devices/dev/values.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# Configuration pour les équipements externes exposés via Traefik (dev) -# Les certificats TLS sont gérés par cert-manager dans le cluster OPS -# ⚠️ Pour le moment, seuls les services externes en production sont configurés - -externalDevices: - # OpenMediaVault - omv: - enabled: true - domain: "nas.dev.gkdomaine.fr" - ip: "10.78.20.107" # ⚠️ À configurer avec l'IP réelle d'OpenMediaVault - port: 80 - tlsSecret: "wildcard-dev-tls" - namespace: "traefik-dev" - basicAuth: - enabled: false - secretName: "omv-basic-auth" - - # Ajoutez d'autres équipements ici - # exemple: - # autre-equipement: - # enabled: true - # domain: "autre.dev.gkdomaine.fr" - # ip: "192.168.1.30" - # port: 80 - # tlsSecret: "wildcard-dev-tls" - # namespace: "traefik-dev" - -# Configuration globale -global: - namespace: "traefik-dev" - tlsSecret: "wildcard-dev-tls" - redirectHttpToHttps: true - diff --git a/scripts/patch-appproject-dev.sh b/scripts/patch-appproject-dev.sh new file mode 100644 index 0000000..180d85e --- /dev/null +++ b/scripts/patch-appproject-dev.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Script pour patcher le projet ArgoCD 'dev' pour autoriser les Endpoints et le repository + +set -e + +NAMESPACE="${1:-argocd-ops}" +PROJECT="${2:-dev}" + +echo "=== Patch du projet ArgoCD '$PROJECT' ===" +echo "Namespace: $NAMESPACE" +echo "" + +# Vérifier que le projet existe +if ! kubectl get appproject "$PROJECT" -n "$NAMESPACE" &>/dev/null; then + echo "❌ Erreur: Le projet '$PROJECT' n'existe pas dans '$NAMESPACE'" + exit 1 +fi + +echo "📋 Configuration actuelle du projet:" +kubectl get appproject "$PROJECT" -n "$NAMESPACE" -o jsonpath='{.spec}' | jq . 2>/dev/null || kubectl get appproject "$PROJECT" -n "$NAMESPACE" -o yaml | grep -A 20 "^spec:" +echo "" + +# Patcher le projet +echo "🔧 Application du patch..." +kubectl patch appproject "$PROJECT" -n "$NAMESPACE" --type merge -p ' +{ + "spec": { + "sourceRepos": ["https://git.gkdomaine.fr/kubernetes/argocd.git", "*"], + "namespaceResourceWhitelist": [ + { + "group": "", + "kind": "Endpoints" + } + ] + } +} +' + +echo "" +echo "✅ Patch appliqué avec succès !" +echo "" +echo "📋 Vérification:" +kubectl get appproject "$PROJECT" -n "$NAMESPACE" -o jsonpath='{.spec.sourceRepos}' && echo "" +kubectl get appproject "$PROJECT" -n "$NAMESPACE" -o jsonpath='{.spec.namespaceResourceWhitelist}' && echo "" +