Por qué LiteLLM es la capa que falta en las pilas de IA autoalojadas
Ollama es excelente para ejecutar modelos en local. Open WebUI lo viste con una interfaz de chat. Pero en cuanto empieza a construir aplicaciones —y no solo a conversar— necesita un intermediario: un proxy que normalice la superficie de API, siga los costes por proyecto y le permita cambiar de modelo sin tocar el código de la aplicación. Ese es precisamente el papel de LiteLLM. Se interpone entre su aplicación y cualquier backend LLM, exponiendo un único endpoint compatible con OpenAI. Su código no cambia, tanto si dirige las peticiones a Llama 3.1 en Ollama como a Claude 3.5 Haiku o a GPT-4o.
Lo que LiteLLM le aporta desde el primer momento
- API unificada y compatible con OpenAI: funciona con todos los SDK, bibliotecas y herramientas que apuntan a la API de OpenAI.
- Más de 100 integraciones de proveedores: Ollama, Anthropic, OpenAI, Azure OpenAI, Mistral, Cohere, Bedrock y muchos otros.
- Claves de API virtuales con límites de gasto y de tasa por clave: reparta claves entre los equipos y ponga topes a los costes mensuales.
- Panel integrado en /ui con análisis del gasto en tiempo real, desglose por modelo y registros de las peticiones.
- Reparto de carga y conmutación automática entre varios endpoints de proveedores o réplicas de modelos.
- Licencia Apache 2.0: sin telemetría, sin envío de información al exterior, totalmente compatible con entornos air-gap cuando se asocia a Ollama.
Requisitos
Al menos 1 GB de RAM y Ubuntu 22.04. Docker y el plugin Compose instalados. El puerto 4000 abierto, o un reverse proxy Caddy/Nginx para el HTTPS. Eso es todo: LiteLLM es en sí mismo un proxy Python que reclama unos 256 MB; PostgreSQL absorbe la mayor parte del presupuesto de RAM restante. Para equipos que generan tráfico concurrente, 2 GB resultan más cómodos.
Desplegar LiteLLM en un VPS
Aprovisionar el VPS
Contrate un VPS Start (2 vCPU, 4 GB, Ubuntu 22.04): LiteLLM se conforma con 1 GB y el plan más pequeño del catálogo sirve el doble. Conéctese por SSH e instale Docker:
curl -fsSL https://get.docker.com | sh. El plugin Compose viene incluido.Generar los secretos
Ejecute
openssl rand -hex 32para generar LITELLM_MASTER_KEY: es la que desbloquea el panel y todos los endpoints de API de administración. Cree/opt/litellm/.envcon:LITELLM_MASTER_KEY,UI_USERNAME,UI_PASSWORD,DB_NAME=litellm,DB_USER=litellm,DB_PASSWORD=<strong-password>.Redactar docker-compose.yml
Cree
/opt/litellm/docker-compose.ymlcon dos servicios:db(postgres:16-alpine, variables de entorno procedentes del .env, volumen litellm_db) ylitellm(imagen ghcr.io/berriai/litellm fijada a una versión explícita y a su resumen@sha256:, nunca amain-latest—véase «Cadena de suministro» más abajo—, puerto 4000:4000, depends_on db, DATABASE_URL + LITELLM_MASTER_KEY + UI_USERNAME + UI_PASSWORD, volumen litellm_config:/app/data). Ejecutedocker compose up -d.Abrir el panel
Vaya a
http://<vps-ip>:4000/uiy conéctese con sus UI_USERNAME / UI_PASSWORD. Llegará al panel de LiteLLM. Entre en Models para añadir su primer proveedor. Para una instancia de Ollama local en el mismo VPS, defina el nombre del modelo comoollama/llama3.1y la API base comohttp://host.docker.internal:11434. Para Anthropic, pegue su clave de API y añadaanthropic/claude-3-5-haiku-20241022.Probar la pasarela
Desde su puesto de trabajo, pruebe:
curl http://<vps-ip>:4000/v1/chat/completions -H "Authorization: Bearer <LITELLM_MASTER_KEY>" -H 'Content-Type: application/json' -d '{"model": "ollama/llama3.1", "messages": [{"role": "user", "content": "Hello"}]}'. Debería recibir una respuesta en streaming, encaminada por LiteLLM hacia su Ollama.Repartir claves de API entre los equipos
En el panel, dentro de API Keys, haga clic en New Key. Póngale una descripción (por ejemplo «frontend-team»), defina
max_budget: 50(USD/mes) y untpm_limitopcional. Comparta esa clave con el equipo: apuntará su SDK de OpenAI ahttp://<vps-ip>:4000y usará esa clave. El gasto se sigue por clave en el panel.Añadir el HTTPS con Caddy
Instale Caddy:
apt install -y caddy. Edite/etc/caddy/Caddyfile:llm.su-dominio.com { reverse_proxy localhost:4000 }. Recargue:systemctl reload caddy. Cierre el puerto 4000 en su firewall: todo el tráfico pasa ya por el 443 con TLS automático.Conectarse por primera vez
Abra la interfaz de administración en /ui: LiteLLM muestra un formulario de usuario y contraseña. Introduzca admin y la contraseña facilitada, y después cree sus claves virtuales desde el panel.
Cadena de suministro: fijar, verificar y rotar las claves
Una pasarela de LLM guarda las claves de todos sus proveedores, que es justo lo que busca un ladrón de credenciales. El hilo de aviso abierto en el repositorio de LiteLLM (issue 47826) afirma que las ruedas de la versión 1.107.0 publicadas en PyPI incluían tres archivos ajenos al proyecto, cook.pth, cook.py y sitecustomize.py, depositados en la raíz de site-packages: un ladrón de credenciales y un cargador de ejecución de código, lanzados en cada arranque de Python. PyPI puso esa versión en cuarentena. Los mantenedores indican haber retirado las imágenes Docker maliciosas, y su informe del incidente describe un secuestro de su canal de publicación mediante tokens de desarrolladores. El informe inicial decía no haber inspeccionado las imágenes; una actualización posterior del mismo hilo encontró los tres archivos en la imagen principal que revisó y recomienda tratar todas las imágenes de esa versión como comprometidas. Esta guía no puede saber qué descargó usted en una fecha dada: las cuatro comprobaciones siguientes lo determinan en su propio servidor.
Saber qué se ejecuta de verdad en su servidor
Leer el resumen de la imagen
Una etiqueta como
main-latestno dice nada de lo que se ejecuta. Ejecutedocker compose imagesy luegodocker image inspect --format '{{index .RepoDigests 0}}' ghcr.io/berriai/litellm:main-latest(sustitúyala por la referencia de su archivo compose). Anote elsha256:obtenido y compárelo con el de una versión cuya procedencia haya verificado.Buscar los archivos citados, sin lanzar Python
En un entorno sospechoso, cada arranque de Python vuelve a ejecutar el código malicioso,
pipincluido. Busque con una herramienta que no lo lance:docker compose exec litellm find / -name 'cook.pth' -o -name 'cook.py' -o -name 'sitecustomize.py' -o -name 'litellm-1.107.0.dist-info' 2>/dev/null(si la imagen incluyefind). Unsitecustomize.pyaislado en otra parte del sistema puede ser legítimo; lo que debe alarmar es uncook.ptha su lado ensite-packages, o una carpetalitellm-1.107.0.dist-info. Encontrar esos archivos confirma la exposición; no encontrar nada no prueba que el entorno esté limpio.Leer la versión instalada
Cuando nada resulte sospechoso,
pip show litellm(en el entorno virtual de una instalación directa) odocker compose exec litellm pip show litellmindica la versión. Si es la 1.107.0, o si duda de una imagen descargada en aquel periodo, pase de inmediato a la rotación de claves más abajo.Buscar rastros de ejecución
El informe menciona un bloqueo
/tmp/remote_code_loader.lock, un procesopythonhuérfano cuyo directorio actual es/, y un archivo testigo/tmp/.pc_once_*escrito solo tras un envío logrado. Su ausencia no prueba nada: un contenedor recreado borra/tmp. Úselo como indicio, no como veredicto.
Fijar por resumen en lugar de por etiqueta
Una etiqueta es un puntero que el editor puede mover; el resumen @sha256: designa unos bytes concretos. En su docker-compose.yml, escriba image: ghcr.io/berriai/litellm:<versión>@sha256:<resumen> con una versión explícita publicada antes del incidente o verificada desde entonces, nunca latest, main-latest ni main-stable. Los mantenedores recomiendan fijar una versión explícita, y el hilo de la issue aconseja el resumen. Tenga presente el límite: un resumen prueba que siempre descarga los mismos bytes, no quién los construyó. Las imágenes de la 1.107.0 habrían podido fijarse sin ninguna alerta. Fijar congela, pues, una decisión que usted ha tomado; no sustituye el hecho de tomarla.
Actualizar sin sorpresas
- Lea las notas de la versión y el estado del hilo de seguridad antes de cambiar de versión, en lugar de dejar que
docker compose pullsiga una etiqueta. - Obtenga el nuevo resumen desde una máquina de pruebas, arranque la pasarela sin claves reales, compruebe su comportamiento y solo entonces lleve el resumen a producción.
- Cuando el editor publique atestaciones de procedencia, verifíquelas: indican de dónde viene una imagen, algo que un simple resumen no dice.
- Conserve el resumen anterior en su repositorio de configuración: volver atrás pasa a ser un cambio de una línea.
- Tras cualquier alerta de seguridad, reconstruya contenedores y entornos virtuales desde cero en lugar de limpiar sobre el sitio.
Si la 1.107.0 llegó a ejecutarse: rotar todas las claves
Según el informe, si esa versión arrancó en un servidor con salida a Internet, hay que suponer que el envío tuvo éxito. El código descrito lee las variables de entorno de los procesos legibles y, cuando DATABASE_URL está definida, extrae las tablas donde la pasarela guarda las credenciales y los modelos de sus proveedores, es decir, todas las claves de origen que posee. La rotación abarca, por tanto, cada secreto que el servidor podía alcanzar, no solo la clave maestra. Revoque primero en el proveedor, genere después la clave de reemplazo y revise el consumo del último mes para detectar un uso que no reconozca.
Qué hay que renovar
- Todas las claves de proveedores guardadas en la pasarela: Anthropic, OpenAI, Azure, Mistral, Bedrock y cada una de las demás.
LITELLM_MASTER_KEYy todas las claves virtuales entregadas a los equipos.- La contraseña de la base de datos (
DB_PASSWORDy elDATABASE_URLque la incluye), así comoUI_PASSWORD. - Cualquier secreto presente en el entorno de un proceso del servidor: tokens de API, contraseñas de servicios vecinos, archivos
.env. - Las claves SSH, tokens de Git y credenciales de nube accesibles desde el VPS, si el servidor llevaba alguna.
- Tras la rotación, reconstruya el VPS o, como mínimo, los contenedores desde una imagen verificada: copiar secretos nuevos en un servidor comprometido los expone de nuevo.
Vigilar las salidas de red
El informe describe un envío a www.litellm.dev, un dominio que no es el del proyecto, y una lectura cada hora de un repositorio de GitHub de terceros usado como buzón de nuevas instrucciones. Los propios mantenedores consideran que la restricción que cuenta es la de nivel de red, porque el código malicioso ignora la configuración de la aplicación. En un VPS, deniegue el tráfico saliente por defecto y autorice solo los puntos de acceso de sus proveedores; si su cortafuegos filtra por dirección y no por nombre, coloque un proxy de salida con lista de permitidos. Si no, registre las resoluciones DNS del servidor y alerte ante cualquier nombre que la pasarela no tenga motivo para llamar.
Asocie LiteLLM a Ollama en el mismo VPS para obtener una pila de IA totalmente aislada (air-gap). Ollama se encarga de la inferencia de los modelos; LiteLLM añade la capa de pasarela: encaminamiento, limitación de tasa y seguimiento del consumo. Para las cargas de trabajo sensibles en materia de confidencialidad (jurídico, finanzas, sanidad), esto significa que ningún dato sale de su infraestructura.
La documentación oficial
Para la configuración avanzada y las opciones propias de la herramienta, consulte la documentación oficial de LiteLLM. Esta guía cubre la puesta en línea en un VPS; la documentación del editor sigue siendo la referencia para los ajustes finos, las actualizaciones mayores y los casos de uso específicos.