- Traefik externalTrafficPolicy: Local → IP client réelle (fin du SNAT kube-proxy) - middleware ratelimit par IP (100/min, burst 200) sur les 6 routes publiques - middleware security-headers (HSTS, nosniff, X-Frame SAMEORIGIN, Referrer-Policy) - TLSOption globale : plancher TLS 1.2 + ciphers modernes - Guacamole REMOTE_IP_VALVE → ban anti-bruteforce par IP (fin du piège n°5) - nftables : fermeture des ports Internet legacy 9080/9081 (HTTP clair redondant) - allowCrossNamespace pour mutualiser les middlewares depuis infra - docs : section Durcissement (public-domain.md) + CAA OVH + pièges à jour Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
8.6 KiB
Domaine public + HTTPS — funklab.online
Exposition des applications du cluster sur Internet via un domaine public
(funklab.online, OVH) avec routage par sous-domaine et TLS Let's Encrypt.
Une seule redirection Freebox (80+443) pour toutes les apps.
Architecture
Internet ─▶ grafana.funklab.online ─┐ DNS OVH : *.funklab.online → 82.67.223.17
chat.funklab.online │
auth.funklab.online │
▼
[ Freebox ] 80 + 443 → funk-s01
▼
s01 (DNAT nftables + rate-limit) → Traefik (VIP .200)
▼
Traefik : route par Host + cert Let's Encrypt (HTTP-01) → l'app
- Split-horizon : dnsmasq résout
*.funklab.online → Traefik (192.168.10.200)en interne → le LAN utilise les mêmes URLs sans sortir sur Internet. - Ports historiques
9080/9081fermés côté Internet (durcissement 2026-07-07) : l'accès direct HTTP clair à Authentik/Guacamole n'existe plus depuis le WAN — tout passe par le domaine en HTTPS. Les VIPs.201/.202restent joignables en LAN. (Penser à retirer aussi les redirections Freebox9080/9081.)
Prérequis (une fois, côté fournisseurs)
- OVH — zone DNS
funklab.online: enregistrementA, sous-domaine*(wildcard), cible82.67.223.17. (Propagation quelques minutes à ~1 h.) - Freebox : redirections
80/tcpet443/tcp→funk-s01.
Vérifier la résolution : dig +short grafana.funklab.online → doit rendre 82.67.223.17.
Déploiement
1. Traefik — Let's Encrypt (hors ArgoCD, helm)
Config versionnée : k8s/infra/traefik/values.yaml. Toujours pinner la version du
chart (sinon helm upgrade tire la dernière → risque de casse de l'ingress cluster) :
helm repo update traefik
helm upgrade traefik traefik/traefik -n infra --version 40.1.0 \
-f k8s/infra/traefik/values.yaml
kubectl -n infra rollout status deploy/traefik
Rollback immédiat si l'ingress tombe : helm rollback traefik -n infra.
2. Redirection HTTP→HTTPS (scopée funklab.online)
kubectl apply -f k8s/infra/traefik/redirect.yaml
⚠️ Pas de redirection globale : les services internes
*.lab.localresteraient cassés (Let's Encrypt ne certifie pas.lab.local).
3. Réseau (Ansible)
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags gateway,dnsmasq
gateway: DNAT80/443 → Traefik+ rate-limitdnsmasq:*.funklab.online → Traefik(variablepublic_domain)
4. Exposer une app en HTTPS
Ajouter/adapter une IngressRoute sur l'entrypoint websecure avec le certResolver :
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata: { name: grafana-public, namespace: monitoring }
spec:
entryPoints: [websecure]
routes:
- match: Host(`grafana.funklab.online`)
kind: Rule
services:
- name: kube-prometheus-stack-grafana
port: 80
tls:
certResolver: letsencrypt # ← émission auto du cert à la 1re visite
Le certificat est émis automatiquement au premier accès (challenge HTTP-01 sur le port 80).
Apps exposées (état 2026-07-07)
Toutes en HTTPS (cert Let's Encrypt par sous-domaine), accessibles depuis le hub
Authentik (https://auth.funklab.online) et directement par leur URL.
| App | URL publique | Auth | Redirect URI OIDC (Authentik) |
|---|---|---|---|
| Portail consoles (Guacamole) | portail.funklab.online |
SSO OIDC | https://portail.funklab.online/ |
| Grafana | grafana.funklab.online |
SSO OIDC (lab-admins→Admin, sinon Viewer) | https://grafana.funklab.online/login/generic_oauth |
| Open WebUI | openwebui.funklab.online |
SSO OIDC | https://openwebui.funklab.online/oauth/oidc/callback |
| Argo CD | argocd.funklab.online |
SSO OIDC (lab-admins→admin) | https://argocd.funklab.online/auth/callback |
| n8n | n8n.funklab.online |
login natif (SSO = Enterprise, indispo en communautaire) | — |
- Chaque app OIDC : provider Authentik Confidential, client secret archivé au vault
(
vault_<app>_oauth_client_secret/vault_argocd_oidc_client_secret) et dans un secret k8s.token_url/discovery joignent Authentik server-side via hairpin (vérifié : un pod atteintauth.funklab.online). - Non exposés (volontaire) : Prometheus, Alertmanager, SearXNG — pas de login propre, nécessiteraient un Proxy Provider (forward-auth) avant toute exposition Internet.
Manifests : k8s/apps/*/ingress-public.yaml, k8s/infra/monitoring/ingressroute-public.yaml,
k8s/argocd-bootstrap/ingressroute-public.yaml. Config OIDC : Grafana/ArgoCD dans leurs
values.yaml helm, Guacamole/Open WebUI dans leur deployment.yaml.
Intégration auth — comment ajouter une app
| Type d'app | Mode | Étapes |
|---|---|---|
| App avec OIDC natif (Grafana, Open WebUI, ArgoCD…) | OIDC | provider Confidential + app (slug) dans Authentik, config OIDC côté app avec l'URL publique, IngressRoute websecure |
| App sans login (Prometheus…) | Proxy Provider | outpost Authentik + middleware forward-auth Traefik (non déployé à ce jour) |
| App avec login propre non-OIDC (n8n…) | route seule | IngressRoute websecure + tuile-lien Authentik (comptes gérés dans l'app) |
Détail de l'ajout d'une app au hub : admin/k8s/auth-portal-admin.md.
Durcissement (edge) — état 2026-07-07
Couche de sécurité appliquée à toutes les routes funklab.online. Manifests :
k8s/infra/traefik/{values.yaml,middlewares.yaml,tls-options.yaml} (Traefik hors
ArgoCD → kubectl apply + helm upgrade).
| Mesure | Où | Effet |
|---|---|---|
| IP client réelle | service.spec.externalTrafficPolicy: Local (values.yaml) |
Traefik voit l'IP source réelle (sinon SNAT kube-proxy → IP d'un nœud). Prérequis du rate-limit par IP et du ban Guacamole par IP. |
| Rate-limit par IP | Middleware ratelimit (infra) sur chaque route |
~100 req/min soutenu, burst 200, par IP client. Anti-scan/bruteforce volumétrique. |
| En-têtes sécurité | Middleware security-headers (infra) |
HSTS 1 an+subdomains, nosniff, X-Frame-Options: SAMEORIGIN, Referrer-Policy. |
| TLS ≥ 1.2 | TLSOption globale default/default |
Plancher TLS 1.2 + ciphers modernes (TLS 1.3 auto). |
| Ban Guacamole par IP | REMOTE_IP_VALVE_ENABLED (deployment guacamole) |
Le ban 5-échecs vise l'IP réelle, plus tout le monde (fin du piège n°5). |
| Ports 9080/9081 fermés (WAN) | rôle gateway (nftables) |
Supprime le chemin HTTP clair direct vers Authentik/Guacamole. |
Les middlewares du namespace
infrasont référencés cross-namespace →providers.kubernetesCRD.allowCrossNamespace: truerequis (values.yaml).
Cross-check DNS (à faire côté OVH) : ajouter un enregistrement CAA pour restreindre l'émission de certificats à Let's Encrypt uniquement :
funklab.online. CAA 0 issue "letsencrypt.org"
funklab.online. CAA 0 iodef "mailto:aliyesilkaya93@gmail.com"
Application (Traefik est hors ArgoCD) :
helm upgrade traefik traefik/traefik -n infra --version 40.1.0 \
-f k8s/infra/traefik/values.yaml # externalTrafficPolicy + allowCrossNamespace
kubectl apply -f k8s/infra/traefik/middlewares.yaml
kubectl apply -f k8s/infra/traefik/tls-options.yaml
kubectl apply -f k8s/argocd-bootstrap/ingressroute-public.yaml # ArgoCD non auto-sync
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags gateway # ports legacy
Les IngressRoutes des apps ai/auth/monitoring sont synchronisées par ArgoCD (merge main).
Vérifier :
curl -sI https://auth.funklab.online | grep -i 'strict-transport\|x-frame'
nmap --script ssl-enum-ciphers -p 443 auth.funklab.online | grep -i tlsv1
Pistes suivantes (non faites) : MFA/TOTP Authentik (protège tout le hub), CrowdSec bouncer Traefik (réputation IP), restreindre ArgoCD au LAN+VPN (IPAllowList).
Pièges
- Cert bloqué en « TRAEFIK DEFAULT CERT » : DNS pas encore propagé ou Freebox
80non redirigé → le challenge HTTP-01 échoue. Vérifierdig+ la redirection. Logs :kubectl -n infra logs deploy/traefik | grep -i acme. - Rate-limit Let's Encrypt (5 certs identiques/semaine) : ne pas boucler les
redéploiements ;
acme.jsonest persistant (PVC nfs) pour éviter la ré-émission. helm upgradesans--version→ tire la dernière chart : toujours pinner.- redirect_uri OIDC : chaque provider Authentik doit lister l'URL publique
https://<app>.funklab.online/...(en plus des URLs internes si conservées).