# Configuration HAProxy pour n8n Pilot ## Architecture ``` Android App → HTTPS → HAProxy (443) → HTTP → n8n (5678) ↓ Validation X-App-Token Rate limiting TLS termination ``` HAProxy agit comme reverse proxy devant n8n. Il : 1. Termine TLS (certificat Let's Encrypt ou autosigné) 2. Valide le header `X-App-Token` (token secret partagé) 3. Applique du rate limiting pour protéger l'API 4. Forward les requêtes vers n8n en HTTP interne --- ## Configuration HAProxy complète ```haproxy #--------------------------------------------------------------------- # global : paramètres du processus HAProxy #--------------------------------------------------------------------- global log /dev/log local0 log /dev/log local1 notice maxconn 2000 daemon #--------------------------------------------------------------------- # defaults : valeurs par défaut pour tous les frontends/backends #--------------------------------------------------------------------- defaults log global mode http option httplog option dontlognull timeout connect 5s timeout client 30s timeout server 30s # Timeout plus long pour les webhooks n8n qui peuvent prendre du temps timeout tunnel 3600s #--------------------------------------------------------------------- # frontend : point d'entrée HTTPS sur le port 443 #--------------------------------------------------------------------- frontend n8n_pilot_frontend bind *:443 ssl crt /etc/ssl/n8n/fullchain.pem alpn h2,http/1.1 # Sécurité TLS : désactiver les versions obsolètes ssl-min-ver TLSv1.2 # Headers de sécurité injectés sur toutes les réponses http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" http-response set-header X-Content-Type-Options "nosniff" http-response set-header X-Frame-Options "DENY" # ACL : vérification du X-App-Token # La valeur doit correspondre exactement au token configuré dans l'app acl valid_app_token req.hdr(X-App-Token) -m str "VOTRE_TOKEN_ICI" # Refuser les requêtes sans token valide avec 403 http-request deny deny_status 403 if !valid_app_token # Rate limiting : max 60 requêtes par minute par IP # Protège contre les scripts de scan et les abus stick-table type ip size 100k expire 60s store http_req_rate(60s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 60 } # Redirection HTTP → HTTPS (optionnel si port 80 ouvert) # redirect scheme https if !{ ssl_fc } default_backend n8n_backend #--------------------------------------------------------------------- # backend : instance n8n locale #--------------------------------------------------------------------- backend n8n_backend balance roundrobin # Supprimer le X-App-Token avant de forwarder à n8n (ne doit pas atteindre n8n) http-request del-header X-App-Token # Health check : n8n répond sur /healthz option httpchk GET /healthz http-check expect status 200 server n8n_local 127.0.0.1:5678 check inter 10s fall 3 rise 2 ``` --- ## Rotation du X-App-Token Le token doit être tourné régulièrement (recommandé : tous les 90 jours minimum). ### Procédure de rotation sans downtime 1. **Générer un nouveau token** : ```bash openssl rand -hex 32 # Exemple : a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1 ``` 2. **Phase de transition — accepter les deux tokens** : ```haproxy # Accepter l'ancien ET le nouveau pendant la transition acl valid_app_token req.hdr(X-App-Token) -m str "ANCIEN_TOKEN" acl valid_app_token_new req.hdr(X-App-Token) -m str "NOUVEAU_TOKEN" http-request deny deny_status 403 if !valid_app_token !valid_app_token_new ``` 3. **Mettre à jour l'app** sur tous les appareils (Paramètres > Token HAProxy > Sauvegarder) 4. **Retirer l'ancien token** de HAProxy une fois tous les appareils mis à jour : ```haproxy acl valid_app_token req.hdr(X-App-Token) -m str "NOUVEAU_TOKEN" http-request deny deny_status 403 if !valid_app_token ``` 5. **Recharger HAProxy** sans coupure : ```bash haproxy -f /etc/haproxy/haproxy.cfg -c # Valider la config systemctl reload haproxy # Rechargement gracieux ``` --- ## Troubleshooting ### Erreur 403 Forbidden **Cause** : `X-App-Token` absent ou incorrect. **Diagnostic** : ```bash # Tester manuellement avec curl curl -v -H "X-App-Token: VOTRE_TOKEN" https://n8n.votre-domaine.com/api/v1/workflows ``` **Solutions** : - Vérifier que le token dans l'app (Paramètres) correspond exactement à la config HAProxy - Contrôler les espaces ou caractères invisibles dans le token - Vérifier les logs HAProxy : `journalctl -u haproxy -f` --- ### Erreur 429 Too Many Requests **Cause** : rate limit dépassé (> 60 req/min). **Solutions** : - Augmenter l'intervalle de polling dans l'app (Paramètres > Intervalle) - Ajuster la limite dans HAProxy si l'usage légitime est plus élevé - Vérifier qu'aucun processus tiers ne spam l'endpoint --- ### Timeout / connexion refusée **Cause** : n8n inaccessible sur le port 5678, ou HAProxy mal configuré. **Diagnostic** : ```bash # Vérifier que n8n tourne curl http://127.0.0.1:5678/healthz # Vérifier le statut HAProxy systemctl status haproxy haproxy -f /etc/haproxy/haproxy.cfg -c # Logs HAProxy en temps réel journalctl -u haproxy -f ``` --- ### Certificat TLS expiré ```bash # Renouveler avec Certbot certbot renew --quiet # Recharger HAProxy pour prendre en compte le nouveau certificat systemctl reload haproxy ``` Automatiser le renouvellement : ```bash # Ajouter dans crontab (root) 0 3 * * 1 certbot renew --quiet && systemctl reload haproxy ```