smart_ide/deploy/nginx/README-ia-enso.md
Nicolas Cantu c13ce79696 Remove nginx Bearer auth from ia.enso /ollama by default
**Motivations:**
- Simplify Cursor/custom clients; Bearer caused confusion with Cursor user API key.

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

**Correctifs:**
- Drop if map check and Authorization stripping on /ollama/; deploy script no longer emits Bearer map.

**Evolutions:**
- Optional Bearer documented in http-maps example; README/services/feature/infrastructure updated; proxy redeployed.

**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:45:35 +01:00

158 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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` |
**Sécurité :** `/ollama/` na **pas** de garde Bearer nginx par défaut : toute personne qui peut joindre lURL peut utiliser lAPI Ollama. Restreindre par **pare-feu** (IP du proxy uniquement vers `.164`) ou réintroduire un `map` Bearer (voir `http-maps/ia-enso-ollama-bearer.map.conf.example`). AnythingLLM sous `/anythingllm/` reste derrière son **login applicatif**.
| Chemin (relatif) | Backend | Port LAN | Protection |
|------------------|---------|----------|------------|
| `/ollama/` | Ollama | `11434` | Aucune auth nginx (Ollama sans clé par défaut) |
| `/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](../../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 :
```bash
# accès LAN direct au proxy (.100), sans bastion (variable vide = pas de ProxyJump) :
# export DEPLOY_SSH_PROXY_HOST=
./deploy/nginx/deploy-ia-enso-to-proxy.sh
```
### 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 :
```bash
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
```
3. 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` WebSocket `$connection_upgrade` (ou fichier stub si doublon ailleurs) |
| `/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 un **stub** commenté à la place du `map`.
### Variables denvironnement du script
| Variable | Défaut | Rôle |
|----------|--------|------|
| `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.
```bash
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 (WebSocket ; Bearer optionnel)
**WebSocket (AnythingLLM)** : si `$connection_upgrade` nexiste pas déjà dans linstance, inclure `http-maps/websocket-connection.map.conf.example` dans `http { }` ou utiliser le fichier `ia-enso-http-maps.conf` déployé par le script.
**Bearer sur `/ollama/` (optionnel)** : pour réactiver une garde nginx, ajouter le `map` de `http-maps/ia-enso-ollama-bearer.map.conf.example` et dans `location /ollama/` un `if ($ia_enso_ollama_authorized = 0) { return 401; }` (+ `map_hash_bucket_size 256` si secret long). Ne pas commiter le secret.
### 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 :
```bash
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 :
```bash
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
```bash
curl -sS -o /dev/null -w "%{http_code}\n" https://ia.enso.4nkweb.com/ollama/v1/models
curl -sS -o /dev/null -w "%{http_code}\n" https://ia.enso.4nkweb.com/ollama/api/tags
```
Attendu : **200** sans en-tête `Authorization` (config par défaut sans Bearer nginx).
### 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 : laisser vide ou valeur factice si Cursor lexige (plus de Bearer nginx sur `/ollama/` par défaut).
Si **`curl`** vers `/ollama/v1/models` renvoie **200** mais Cursor affiche **`ERROR_BAD_USER_API_KEY`**, léchec vient **du client Cursor** (validation / infra Cursor), pas du proxy : [forum](https://forum.cursor.com/t/unauthorized-user-api-key-with-custom-openai-api-key-url/132572).
---
## 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.
---
## 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 stub du script. |
| `could not build map_hash` / `map_hash_bucket_size` | Uniquement si tu réactives un `map` Bearer avec un secret très long ; ajouter `map_hash_bucket_size 256;` dans `http { }`. |
| `401` sur `/ollama/` | Bearer nginx réactivé manuellement : aligner client et `map`, ou désactiver la garde. |
| `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. |