diff --git a/apps/applicationset-external-devices.yaml b/apps/applicationset-external-devices.yaml new file mode 100644 index 0000000..80bae8d --- /dev/null +++ b/apps/applicationset-external-devices.yaml @@ -0,0 +1,30 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: external-devices + namespace: argocd-ops +spec: + generators: + - list: + elements: + - env: prd + cluster: cluster-prd + template: + metadata: + name: external-devices-{{path.basename}} + spec: + project: default + source: + repoURL: https://gitea.gkdomaine.local/gkdomaine.fr/argocd.git + targetRevision: main + path: helm/external-devices/{{path.basename}} + destination: + name: '{{name}}' + namespace: 'traefik-{{path.basename}}' + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + diff --git a/docs/EXPORT-CERTIFICATS-EXTERNES.md b/docs/EXPORT-CERTIFICATS-EXTERNES.md new file mode 100644 index 0000000..131ecbe --- /dev/null +++ b/docs/EXPORT-CERTIFICATS-EXTERNES.md @@ -0,0 +1,252 @@ +# 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 new file mode 100644 index 0000000..eca8453 --- /dev/null +++ b/docs/REVERSE-PROXY-EXTERNES.md @@ -0,0 +1,471 @@ +# 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/helm/external-devices/prd/Chart.yaml b/helm/external-devices/prd/Chart.yaml new file mode 100644 index 0000000..d547ad3 --- /dev/null +++ b/helm/external-devices/prd/Chart.yaml @@ -0,0 +1,7 @@ +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/prd/README.md b/helm/external-devices/prd/README.md new file mode 100644 index 0000000..7d61916 --- /dev/null +++ b/helm/external-devices/prd/README.md @@ -0,0 +1,98 @@ +# External Devices - Reverse Proxy avec Traefik (Production) + +Ce chart Helm expose vos équipements externes (pfSense, OpenMediaVault, NAS, etc.) via Traefik en utilisant les certificats TLS générés par cert-manager. + +⚠️ **Note** : Pour le moment, seuls les services externes en **production** sont configurés. + +## Principe + +Au lieu d'exporter les certificats vers chaque équipement, Traefik agit comme reverse proxy : +- **Traefik** gère le HTTPS avec les certificats wildcard +- Les **équipements externes** restent en HTTP (interne) +- Les certificats sont **automatiquement renouvelés** par cert-manager + +## Configuration + +### 1. Modifier `values.yaml` + +Configurez vos équipements dans `values.yaml` : + +```yaml +externalDevices: + pfsense: + enabled: true + domain: "pfsense.prd.gkdomaine.fr" + ip: "192.168.1.1" # ⚠️ IP réelle de pfSense + port: 80 + tlsSecret: "wildcard-prd-tls" +``` + +### 2. Déployer via ArgoCD + +Le chart est déployé automatiquement via l'ApplicationSet `applicationset-external-devices.yaml`. + +### 3. Vérifier + +```bash +# Vérifier les services +kubectl get services -n traefik-prd | grep backend + +# Vérifier les IngressRoute +kubectl get ingressroute -n traefik-prd + +# Tester l'accès +curl -k https://pfsense.prd.gkdomaine.fr +``` + +## Ajouter un nouvel équipement + +1. Ajoutez la configuration dans `values.yaml` : + +```yaml +externalDevices: + mon-equipement: + enabled: true + domain: "equipement.prd.gkdomaine.fr" + ip: "192.168.1.100" + port: 80 + tlsSecret: "wildcard-prd-tls" + namespace: "traefik-prd" +``` + +2. Le chart génère automatiquement : + - Un Service de type `ExternalName` + - Un IngressRoute avec TLS + - Une redirection HTTP → HTTPS (si activée) + +## Authentification basique + +Pour ajouter une authentification HTTP Basic : + +```yaml +externalDevices: + pfsense: + enabled: true + domain: "pfsense.prd.gkdomaine.fr" + ip: "192.168.1.1" + port: 80 + basicAuth: + enabled: true + secretName: "pfsense-basic-auth" # Secret à créer manuellement +``` + +Créer le secret : + +```bash +# Générer le hash avec htpasswd +htpasswd -nb admin password | base64 + +# Créer le secret +kubectl create secret generic pfsense-basic-auth \ + --from-literal=users='admin:$apr1$...' \ + -n traefik-prd +``` + +## Documentation complète + +Voir `docs/REVERSE-PROXY-EXTERNES.md` pour plus de détails. + diff --git a/helm/external-devices/prd/templates/ingressroutes.yaml b/helm/external-devices/prd/templates/ingressroutes.yaml new file mode 100644 index 0000000..de9502d --- /dev/null +++ b/helm/external-devices/prd/templates/ingressroutes.yaml @@ -0,0 +1,52 @@ +{{- 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/prd/templates/middlewares.yaml b/helm/external-devices/prd/templates/middlewares.yaml new file mode 100644 index 0000000..e682214 --- /dev/null +++ b/helm/external-devices/prd/templates/middlewares.yaml @@ -0,0 +1,29 @@ +{{- 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/prd/templates/services.yaml b/helm/external-devices/prd/templates/services.yaml new file mode 100644 index 0000000..939bf27 --- /dev/null +++ b/helm/external-devices/prd/templates/services.yaml @@ -0,0 +1,21 @@ +{{- range $name, $device := .Values.externalDevices }} +{{- if $device.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $name }}-backend + namespace: {{ $device.namespace | default $.Values.global.namespace }} + labels: + app: external-device + device: {{ $name }} +spec: + type: ExternalName + externalName: {{ $device.ip }} + ports: + - port: {{ $device.port }} + targetPort: {{ $device.port }} + protocol: TCP +{{- end }} +{{- end }} + diff --git a/helm/external-devices/prd/values.yaml b/helm/external-devices/prd/values.yaml new file mode 100644 index 0000000..493d766 --- /dev/null +++ b/helm/external-devices/prd/values.yaml @@ -0,0 +1,33 @@ +# Configuration pour les équipements externes exposés via Traefik (PRD) +# 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.prd.gkdomaine.fr" + ip: "10.78.20.107" # ⚠️ À configurer avec l'IP réelle d'OpenMediaVault + port: 80 + tlsSecret: "wildcard-prd-tls" + namespace: "traefik-prd" + basicAuth: + enabled: false + secretName: "omv-basic-auth" + + # Ajoutez d'autres équipements ici + # exemple: + # autre-equipement: + # enabled: true + # domain: "autre.prd.gkdomaine.fr" + # ip: "192.168.1.30" + # port: 80 + # tlsSecret: "wildcard-prd-tls" + # namespace: "traefik-prd" + +# Configuration globale +global: + namespace: "traefik-prd" + tlsSecret: "wildcard-prd-tls" + redirectHttpToHttps: true + diff --git a/scripts/export-certificate.sh b/scripts/export-certificate.sh new file mode 100644 index 0000000..1fb4823 --- /dev/null +++ b/scripts/export-certificate.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# Script pour exporter un certificat TLS depuis Kubernetes vers un format utilisable par des équipements externes + +set -e + +SECRET_NAME="${1}" +NAMESPACE="${2:-certificates-ops}" +CONTEXT="${3:-cluster-ops}" +OUTPUT_DIR="${4:-./certificates-export}" +FORMAT="${5:-pem}" # pem, pkcs12, pfx + +if [ -z "$SECRET_NAME" ]; then + echo "Usage: $0 [namespace] [context] [output-dir] [format]" + echo "" + echo "Exemples:" + echo " $0 wildcard-prd-tls certificates-ops cluster-ops ./certs pem" + echo " $0 wildcard-prd-tls certificates-ops cluster-ops ./certs pkcs12" + echo "" + echo "Formats disponibles:" + echo " - pem: Certificat et clé en format PEM (par défaut)" + echo " - pkcs12: Format PKCS12 (.p12) pour pfSense, etc." + echo " - pfx: Format PFX (identique à PKCS12)" + exit 1 +fi + +echo "=== Export du certificat TLS ===" +echo "Secret: $SECRET_NAME" +echo "Namespace: $NAMESPACE" +echo "Context: $CONTEXT" +echo "Format: $FORMAT" +echo "" + +# Créer le répertoire de sortie +mkdir -p "$OUTPUT_DIR" + +# Vérifier que le secret existe +if ! kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" &>/dev/null; then + echo "❌ Erreur: Le secret '$SECRET_NAME' n'existe pas dans '$NAMESPACE'" + exit 1 +fi + +# Extraire le certificat et la clé +echo "📥 Extraction du certificat depuis Kubernetes..." +kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" -o jsonpath='{.data.tls\.crt}' | base64 -d > "$OUTPUT_DIR/$SECRET_NAME.crt" +kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" -o jsonpath='{.data.tls\.key}' | base64 -d > "$OUTPUT_DIR/$SECRET_NAME.key" + +# Extraire la chaîne de certificats complète (certificat + CA) +kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" --context="$CONTEXT" -o jsonpath='{.data.ca\.crt}' | base64 -d > "$OUTPUT_DIR/$SECRET_NAME-ca.crt" 2>/dev/null || true + +echo "✅ Certificat et clé extraits" +echo "" + +# Convertir selon le format demandé +case "$FORMAT" in + pem) + echo "📄 Format PEM (déjà généré)" + echo " Certificat: $OUTPUT_DIR/$SECRET_NAME.crt" + echo " Clé privée: $OUTPUT_DIR/$SECRET_NAME.key" + if [ -f "$OUTPUT_DIR/$SECRET_NAME-ca.crt" ]; then + echo " CA: $OUTPUT_DIR/$SECRET_NAME-ca.crt" + fi + ;; + pkcs12|pfx) + echo "📦 Conversion en format PKCS12..." + + # Demander un mot de passe pour le fichier PKCS12 + read -sp "Mot de passe pour le fichier PKCS12 (laissez vide pour aucun): " PASSWORD + echo "" + + # Créer le fichier PKCS12 + if [ -z "$PASSWORD" ]; then + openssl pkcs12 -export \ + -out "$OUTPUT_DIR/$SECRET_NAME.p12" \ + -inkey "$OUTPUT_DIR/$SECRET_NAME.key" \ + -in "$OUTPUT_DIR/$SECRET_NAME.crt" \ + -name "$SECRET_NAME" \ + -passout pass: + else + openssl pkcs12 -export \ + -out "$OUTPUT_DIR/$SECRET_NAME.p12" \ + -inkey "$OUTPUT_DIR/$SECRET_NAME.key" \ + -in "$OUTPUT_DIR/$SECRET_NAME.crt" \ + -name "$SECRET_NAME" \ + -passout pass:"$PASSWORD" + fi + + echo "✅ Fichier PKCS12 créé: $OUTPUT_DIR/$SECRET_NAME.p12" + ;; + *) + echo "❌ Format '$FORMAT' non supporté" + echo " Formats disponibles: pem, pkcs12, pfx" + exit 1 + ;; +esac + +# Afficher les informations du certificat +echo "" +echo "📋 Informations du certificat:" +openssl x509 -in "$OUTPUT_DIR/$SECRET_NAME.crt" -noout -subject -issuer -dates 2>/dev/null || echo " (openssl non disponible pour afficher les détails)" + +echo "" +echo "✅ Export terminé dans: $OUTPUT_DIR" +echo "" +echo "📝 Prochaines étapes:" +echo "" +case "$FORMAT" in + pem) + echo "Pour pfSense:" + echo " 1. Allez dans System > Certificates" + echo " 2. Cliquez sur 'Import'" + echo " 3. Importez le certificat ($SECRET_NAME.crt)" + echo " 4. Importez la clé privée ($SECRET_NAME.key)" + echo "" + echo "Pour OpenMediaVault:" + echo " 1. Allez dans System > Certificates > SSL" + echo " 2. Cliquez sur 'Import'" + echo " 3. Sélectionnez le certificat et la clé" + ;; + pkcs12|pfx) + echo "Pour pfSense:" + echo " 1. Allez dans System > Certificates" + echo " 2. Cliquez sur 'Import'" + echo " 3. Sélectionnez le fichier PKCS12 ($SECRET_NAME.p12)" + echo " 4. Entrez le mot de passe si vous en avez défini un" + ;; +esac +