smart_ide/deploy/nginx/README-ia-enso.md
Nicolas Cantu c4215044f0 Re-enable nginx Bearer auth on ia.enso /ollama
**Motivations:**
- Restore gate on /ollama/; document Cursor streamFromAgentBackend note.

**Root causes:**
- N/A.

**Correctifs:**
- location /ollama/ if map + clear Authorization upstream; deploy script emits Bearer + websocket maps with retry bearer_only.

**Evolutions:**
- README Cursor subsection on streamFromAgentBackend (observed behavior); feature/services/infrastructure aligned.

**Pages affectées:**
- deploy/nginx/sites/ia.enso.4nkweb.com.conf
- deploy/nginx/deploy-ia-enso-to-proxy.sh
- deploy/nginx/README-ia-enso.md
- deploy/nginx/http-maps/ia-enso-ollama-bearer.map.conf.example
- docs/features/ia-enso-nginx-proxy-ollama-anythingllm.md
- docs/services.md
- docs/infrastructure.md
2026-03-23 07:49:06 +01:00

8.9 KiB
Raw Blame History

ia.enso.4nkweb.com — Nginx sur le proxy (192.168.1.100)

Reverse TLS vers lhôte LAN 192.168.1.164 (Ollama + AnythingLLM ; IP substituée au déploiement via __IA_ENSO_BACKEND_IP__ / IA_ENSO_BACKEND_IP).

URLs publiques complètes (HTTPS)

Service URL
AnythingLLM (interface) https://ia.enso.4nkweb.com/anythingllm/
Ollama API native (ex. liste des modèles) https://ia.enso.4nkweb.com/ollama/api/tags
Ollama API compatible OpenAI (Cursor, etc.) base URL https://ia.enso.4nkweb.com/ollama/v1 — ex. https://ia.enso.4nkweb.com/ollama/v1/models

Bearer nginx : tout /ollama/ exige Authorization: Bearer <secret> (fichier map sur le proxy). La valeur nest pas transmise à Ollama (Authorization effacé en amont). AnythingLLM sous /anythingllm/ : auth applicative uniquement.

Chemin (relatif) Backend Port LAN Protection
/ollama/ Ollama 11434 Bearer nginx
/anythingllm/ AnythingLLM 3001 Login AnythingLLM

Contexte Cursor : une URL en IP privée (ex. http://192.168.1.164:11434) peut être refusée par Cursor (ssrf_blocked). Un nom public HTTPS vers le proxy évite ce blocage si le DNS résolu depuis Internet nest pas une IP RFC1918.

Fichiers dans le dépôt : sites/ia.enso.4nkweb.com.conf, http-maps/*.example, deploy-ia-enso-to-proxy.sh. Détails darchitecture : docs/features/ia-enso-nginx-proxy-ollama-anythingllm.md.


Déploiement recommandé : script SSH

Depuis la racine du dépôt smart_ide, sur une machine avec accès SSH au bastion puis au proxy :

export IA_ENSO_OLLAMA_BEARER_TOKEN='secret-ascii-sans-guillemets-ni-backslash'
# accès LAN direct au proxy (.100), sans bastion :
# export DEPLOY_SSH_PROXY_HOST=
./deploy/nginx/deploy-ia-enso-to-proxy.sh

Si IA_ENSO_OLLAMA_BEARER_TOKEN est absent, le script génère un token hex (affichage unique) à conserver pour Cursor.

Prérequis sur le proxy

  • http { include /etc/nginx/conf.d/*.conf; ... } dans /etc/nginx/nginx.conf (sinon le script échoue avec un message explicite).
  • Certificats Lets Encrypt pour ia.enso.4nkweb.com aux chemins du fichier site (/etc/letsencrypt/live/ia.enso.4nkweb.com/fullchain.pem et privkey.pem). Sans eux, le bloc listen 443 fait échouer nginx -t : voir Bootstrap TLS ci-dessous.
  • sudo non interactif pour nginx et systemctl reload nginx.

Bootstrap TLS (première fois, nginx -t impossible)

  1. DNS : ia.enso.4nkweb.com doit résoudre vers lentrée publique qui atteint ce proxy (HTTP port 80).
  2. Sur le proxy :
sudo install -d -m 0755 /var/www/certbot
# Remplacer temporairement le vhost par HTTP seul (fichier dans le dépôt : sites/ia.enso.4nkweb.com.http-only.conf)
sudo cp /chemin/smart_ide/deploy/nginx/sites/ia.enso.4nkweb.com.http-only.conf /etc/nginx/sites-available/ia.enso.4nkweb.com.conf
sudo nginx -t && sudo systemctl reload nginx
sudo certbot certonly --webroot -w /var/www/certbot -d ia.enso.4nkweb.com --non-interactive --agree-tos --register-unsafely-without-email
  1. Déployer la config complète : ./deploy/nginx/deploy-ia-enso-to-proxy.sh (rétablit HTTPS + upstreams).

Fichiers installés par le script

Chemin sur le proxy Rôle
/etc/nginx/conf.d/ia-enso-http-maps.conf map_hash_bucket_size, map Bearer $ia_enso_ollama_authorized, et souvent map WebSocket
/etc/nginx/sites-available/ia.enso.4nkweb.com.conf server HTTP→HTTPS + HTTPS
Lien sites-enabled/ia.enso.4nkweb.com.conf Activation du vhost

Si nginx -t échoue à cause dun doublon map $http_upgrade $connection_upgrade, le script retente avec Bearer seul (sans dupliquer le map WebSocket).

Variables denvironnement du script

Variable Défaut Rôle
IA_ENSO_OLLAMA_BEARER_TOKEN généré (openssl rand -hex 32) Secret pour Authorization: Bearer …
IA_ENSO_SSH_KEY ~/.ssh/id_ed25519 Clé privée SSH
IA_ENSO_PROXY_USER ncantu Utilisateur SSH sur le proxy
IA_ENSO_PROXY_HOST 192.168.1.100 Cible SSH (IP ou hostname LAN)
DEPLOY_SSH_PROXY_HOST 4nk.myftp.biz Bastion ProxyJump ; vide = SSH direct
DEPLOY_SSH_PROXY_USER idem proxy Utilisateur sur le bastion
IA_ENSO_BACKEND_IP 192.168.1.164 Hôte Ollama + AnythingLLM (IPv4)

Bibliothèque utilisée : ia_dev/deploy/_lib/ssh.sh (BatchMode=yes).


Déploiement manuel (sans script)

1. DNS et TLS

Le DNS doit résoudre ia.enso.4nkweb.com vers lentrée publique qui atteint ce proxy.

sudo certbot certonly --webroot -w /var/www/certbot -d ia.enso.4nkweb.com

Adapter dans sites/ia.enso.4nkweb.com.conf les directives ssl_certificate / ssl_certificate_key si le répertoire live/ diffère.

2. Maps HTTP (Bearer + WebSocket)

Le script déploie ia-enso-http-maps.conf avec map_hash_bucket_size 256, le map Bearer et le map WebSocket (ou Bearer seul si doublon WebSocket ailleurs). Installation manuelle : combiner http-maps/ia-enso-ollama-bearer.map.conf.example et websocket-connection.map.conf.example dans http { } si besoin.

3. Fichier server

Le fichier dans le dépôt contient le marqueur __IA_ENSO_BACKEND_IP__. Remplacer par lIPv4 du backend (ex. 192.168.1.164) avant copie, ou utiliser :

sed "s/__IA_ENSO_BACKEND_IP__/192.168.1.164/g" deploy/nginx/sites/ia.enso.4nkweb.com.conf | sudo tee /etc/nginx/sites-available/ia.enso.4nkweb.com.conf >/dev/null

Sans sed : éditer le fichier sur le proxy pour remplacer __IA_ENSO_BACKEND_IP__ par lIPv4 réelle, puis :

sudo ln -sf /etc/nginx/sites-available/ia.enso.4nkweb.com.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Vérifications

API Ollama via le proxy

curl -sS -o /dev/null -w "%{http_code}\n" \
  -H "Authorization: Bearer <secret>" \
  https://ia.enso.4nkweb.com/ollama/v1/models

Attendu : 200 avec le bon secret ; 401 sans Authorization ou secret incorrect.

AnythingLLM

Navigateur : https://ia.enso.4nkweb.com/anythingllm/ (redirection vers /anythingllm/). Connexion avec les identifiants AnythingLLM.
Si les assets statiques échouent, vérifier la doc upstream (sous-chemin, en-têtes X-Forwarded-*).

Cursor

  • URL de base OpenAI : https://ia.enso.4nkweb.com/ollama/v1
  • Clé API : identique au secret du map nginx (sans préfixe Bearer dans le champ).

streamFromAgentBackend (comportement observé) : dans lapplication Cursor (bundle Electron), le flux Agent / chat appelle une couche interne qui ouvre un stream vers les serveurs Cursor (getAgentStreamResponse, etc.), pas un fetch direct depuis ton poste vers ton URL OpenAI override. Cursor peut donc valider une « User API key » ou des droits avant ou en parallèle de lusage de loverride. Si curl avec le Bearer vers /ollama/v1/models renvoie 200 mais Cursor affiche ERROR_BAD_USER_API_KEY, léchec reste côté client / infra Cursor : forum. Le code minifié du produit nest pas dans ce dépôt ; seuls les noms de fonctions dans la stack trace décrivent ce chemin dexécution.


Pare-feu backend

Sur 192.168.1.164, nautoriser 11434 et 3001 TCP que depuis 192.168.1.100 (proxy) si un pare-feu hôte est actif.


Rotation du secret Bearer

  1. Mettre à jour "Bearer …" dans /etc/nginx/conf.d/ia-enso-http-maps.conf (ou redéployer avec IA_ENSO_OLLAMA_BEARER_TOKEN).
  2. sudo nginx -t && sudo systemctl reload nginx.
  3. Mettre à jour la clé API dans Cursor (et tout autre client).

Dépannage

Symptôme Piste
nginx -t erreur sur connection_upgrade Doublon de map $http_upgrade $connection_upgrade : retirer lun des blocs ou laisser le déploiement « Bearer seul » du script.
could not build map_hash / map_hash_bucket_size Secret Bearer long : le fichier généré par le script inclut map_hash_bucket_size 256;.
401 sur /ollama/ Secret différent entre client et map ; en-tête Authorization absent ou mal formé.
502 / timeout Ollama ou AnythingLLM arrêtés sur le backend ; pare-feu ; mauvaise IP dans upstream (vérifier grep server /etc/nginx/sites-available/ia.enso.4nkweb.com.conf sur le proxy ; redéployer avec IA_ENSO_BACKEND_IP=192.168.1.164).
Erreur SSL / cannot load certificate Certificat absent : exécuter certbot sur le proxy pour ia.enso.4nkweb.com, ou adapter les chemins ssl_certificate dans le fichier site.
Cursor ssrf_blocked Lhôte utilisé résout encore vers une IP privée côté infrastructure Cursor ; vérifier DNS public / NAT.