
Proyecto IA Monterroso (XII): abrir MonteIA a la red del centro
Hasta hoy, MonteIA solo respondía en localhost: el único ordenador que podía hablar con ella era ROCKY. Con el filtro de entrada y el rate limiting ya puestos, tocaba la decisión de fondo: abrir el acceso a la red del centro. Y como va a estar en la misma WiFi que usa el alumnado, esta entrada no es solo un cambio de código — viene con una pieza de seguridad que ya no es opcional.
Qué vamos a hacer
Dos cosas, a la vez, porque la segunda no tiene sentido sin la primera:
- Que la API escuche en la red, no solo en el propio ordenador.
- Un código de acceso compartido: sin él, cualquier dispositivo conectado a esa WiFi —incluido el de cualquier alumno— podría usar MonteIA sin ningún control. Eso no es aceptable en un centro con menores, así que no se abre la red sin esto puesto primero.
Por qué el código de acceso no es opcional aquí
Hasta ahora MonteIA vivía solo en un ordenador: el propio riesgo de “quién puede llegar hasta la API” era básicamente cero, porque solo llegaba quien se sentaba delante de ROCKY. Eso cambia en el momento en que la API escucha en la red: todo lo que hay en esa WiFi puede, en principio, llegar a /preguntar.
Aviso honesto, para no venderlo como más de lo que es: esto es un código compartido, no una cuenta de usuario. Todo el que lo conoce entra igual — no hay usuarios distintos ni permisos distintos. No hay HTTPS todavía, así que el código viaja sin cifrar dentro de la red del centro (protegido por el cifrado de la propia WiFi frente a quien esté fuera, pero no frente a quien esté dentro con herramientas para mirar el tráfico). Es una barrera mínima razonable para un piloto controlado, no una solución de seguridad completa. Si esto crece de verdad, lo siguiente sería HTTPS y cuentas individuales — no toca hoy.
Aviso honesto número dos: qué pasa si preguntan varios a la vez
Como el plan es que lo use más gente desde el principio, hay que decirlo claramente: LM Studio en ROCKY solo puede generar una respuesta a la vez. Si dos o tres personas preguntan en el mismo momento, no se rompe nada, pero las peticiones se van poniendo en cola y cada persona espera un poco más de lo normal. El rate limiting (20 peticiones/minuto por IP) protege contra bucles y abusos, no resuelve esto — son dos problemas distintos. Para un piloto con un grupo pequeño (una clase, unos pocos profesores probando) no debería notarse mucho; si el uso crece en serio, esto se convierte en el próximo cuello de botella a resolver, probablemente con mejor hardware.
Código
Cambios en ia-monterroso-api/main.py. Import nuevo:
python
import os
from fastapi import Depends, FastAPI, Header, HTTPException, Request
Justo después de la configuración de LM Studio:
python
# --- Código de acceso (autenticación mínima) ---
#
# Tercera pieza, y la que faltaba antes de escuchar en la red del centro:
# MonteIA va a estar en la misma WiFi que usa el alumnado, así que un
# código de acceso compartido deja de ser opcional. No es autenticación de
# verdad (no hay usuarios ni contraseñas individuales, todo el que lo
# conoce entra igual), pero es la barrera mínima imprescindible para no
# tener la API abierta sin ningún control en una red donde hay menores.
#
# El código NO se escribe en este archivo: se lee de la variable de entorno
# MONTEIA_TOKEN, siguiendo la norma del proyecto de mantener separados
# configuración/secretos y código. Si no está definida, la API se niega a
# arrancar — mejor que arranque rota y avise, que arranque abierta a
# cualquiera sin que nadie se dé cuenta.
MONTEIA_TOKEN = os.environ.get("MONTEIA_TOKEN")
if not MONTEIA_TOKEN:
raise RuntimeError(
"Falta la variable de entorno MONTEIA_TOKEN (el código de acceso de "
"MonteIA). Hay que definirla antes de arrancar la API — ver la entrada "
"del blog sobre el acceso en red para cómo hacerlo en Windows."
)
def verificar_token(x_monteia_token: str = Header(None, alias="X-MonteIA-Token")):
"""Dependencia de FastAPI: comprueba que la petición trae el código de
acceso correcto en la cabecera X-MonteIA-Token. Se aplica solo a
/preguntar (la página web y /salud siguen siendo visibles sin código;
lo que se protege es el uso real de la IA, no la carga de la página)."""
if x_monteia_token != MONTEIA_TOKEN:
raise HTTPException(
status_code=401,
detail="Código de acceso incorrecto o no proporcionado.",
)
Y el endpoint se protege añadiendo la dependencia:
python
@app.post("/preguntar", dependencies=[Depends(verificar_token)])
@limiter.limit("20/minute")
def preguntar(request: Request, datos: PeticionChat):
... # sin más cambios aquí
En el frontend (dentro de PAGINA_HTML), se añade un cuadro que pide el código la primera vez y lo guarda en el navegador (en localStorage, solo como comodidad para no escribirlo cada vez — no es una medida de seguridad, es exactamente igual de accesible que cualquier otro dato guardado en ese mismo ordenador), y se manda en cada petición con la cabecera X-MonteIA-Token. Si el servidor responde con un 401 (código incorrecto o caducado), se borra el guardado y se vuelve a pedir, en vez de mostrarlo como un error normal de chat.
Instalación
1. Elegir un código de acceso. No lo elijas trivial (“1234”, el nombre del centro…). Algo como una frase de varias palabras es suficientemente robusto y fácil de compartir de palabra con el profesorado que lo vaya a usar.
2. Definir la variable de entorno en Windows, antes de arrancar la API. Con PowerShell, en la misma sesión donde se va a lanzar uvicorn:
powershell
$env:MONTEIA_TOKEN = "el-codigo-que-hayas-elegido"
(Esto solo dura para esa ventana de PowerShell; hay que repetirlo cada vez que se abra una nueva, o configurarlo como variable de entorno permanente del sistema si se prefiere no repetirlo.)
3. Arrancar la API escuchando en la red, no solo en localhost:
powershell
uvicorn main:app --host 0.0.0.0 --port 8000
4. Permitir el puerto 8000 en el Firewall de Windows, si no está ya permitido, para la red privada/del centro (no para redes públicas). Esto se hace una sola vez desde el propio Windows (Firewall de Windows Defender → Configuración avanzada → Regla de entrada nueva → Puerto → TCP 8000 → Permitir → solo para el perfil de red correspondiente).
5. Averiguar la IP de ROCKY en esa red (ipconfig en PowerShell, la “Dirección IPv4”). Desde otro dispositivo en la misma WiFi, se accede a MonteIA en http://esa-ip:8000/.
Cómo comprobarlo
- Desde ROCKY mismo, seguir pudiendo usarlo en
http://localhost:8000/como siempre. - Desde otro ordenador o móvil en la misma red, abrir
http://ip-de-rocky:8000/— debe aparecer el cuadro pidiendo el código de acceso. - Escribir el código correcto → debe funcionar exactamente igual que en local.
- Escribir un código incorrecto → debe rechazarlo y volver a pedirlo.
- (Antes de instalarlo, ya se comprobó con un cliente de pruebas que el código de acceso, el filtro de entrada y el rate limiting funcionan bien los tres juntos, sin pisarse entre ellos.)
Qué queda pendiente
Esto abre MonteIA a un piloto real dentro del centro, con las dos advertencias de arriba bien presentes: el código de acceso es una barrera mínima, no una solución de seguridad completa, y varias personas preguntando a la vez van a notar que ROCKY solo puede atender una petición del modelo cada vez. Si el piloto va bien y el uso crece, esos dos puntos son los siguientes a resolver — no antes.

Etiqueta:AIDARAC, código de acceso, fastapi, ia monterroso, MonteIA, montesteam, red local, seguridad

