# TIP — Threat Intelligence Platform > Plataforma centralizada de monitoreo e inteligencia de amenazas sobre Telegram. --- ## Tabla de Contenidos 1. [Descripción General](#descripción-general) 2. [Arquitectura del Sistema](#arquitectura-del-sistema) 3. [Microservicios](#microservicios) 4. [Flujo del Alimentador](#flujo-del-alimentador) 5. [Requisitos Previos](#requisitos-previos) 6. [Instalación y Configuración](#instalación-y-configuración) 7. [Gestión de Backups](#gestión-de-backups) 8. [Troubleshooting](#troubleshooting) --- ## Descripción General **TIP (Threat Intelligence Platform)** es una plataforma de monitoreo en tiempo real diseñada para capturar, analizar y gestionar mensajes de grupos y canales de Telegram. Mediante reglas configurables basadas en expresiones regulares, el sistema detecta patrones sospechosos, genera alertas automáticas y mantiene un registro auditable de todas las operaciones. ### Características Principales - **Monitoreo en tiempo real**: Captura automática de mensajes desde grupos y canales de Telegram - **Detección basada en reglas**: Expresiones regulares configurables para identificar patrones de interés - **Gestión de alertas**: Ciclo de vida completo — Pendiente → En Curso → Resuelta — con historial de notas - **Auditoría integral**: Registro de IP, usuario y timestamp en cada operación del sistema - **Exportación de reportes**: Generación de PDFs con trazabilidad completa al cerrar una alerta - **Estadísticas en tiempo real**: Dashboards con métricas, heatmaps y análisis de actividad - **Control de acceso por roles**: Administradores y Operadores con permisos diferenciados - **Sistema de backups**: Exportación e importación de bases de datos, configuración y sesiones de Telegram --- ## Arquitectura del Sistema TIP está compuesto por **4 microservicios** y **2 bases de datos** independientes, orquestados con Docker Compose y expuestos a través de un proxy NGINX con SSL. ``` ╔══════════════════════════════════════════════════════════════════════════════════╗ ║ INTERNET ║ ╚══════════════════════════════════════════════╦═══════════════════════════════════╝ ║ HTTPS :443 / HTTP :80 ╔════════════════╩════════════════╗ ║ NGINX Proxy ║ ║ Terminación SSL · Routing ║ ╚══════╦══════════╦═══════╦═══════╝ ║ ║ ║ ╔══════════════╝ ╔═════╝ ╔══=╩═════════════╗ ▼ ▼ ▼ ▼ ╔════════════════╗ ╔══════════════╗ ╔══════════════╗ ╔═══════════════╗ ║ Frontend ║ ║ API Feeder ║ ║ API Users ║ ║Backup Service ║ ║ Streamlit ║ ║ FastAPI ║ ║ FastAPI ║ ║ FastAPI ║ ║ Python 3.11 ║ ║ Python 3.11 ║ ║ Python 3.11 ║ ║ Python 3.11 ║ ║ :8501 ║ ║ :8000 ║ ║ :8090 ║ ║ :8099 ║ ╚═══════╦════════╝ ╚══════╦═══════╝ ╚══════╦═══════╝ ╚═══════╦═══════╝ ║ ║ ║ ║ HTTP ║ ╔════════╩══════╗ ║ ║ REST ╠ ║ Telegram ║ ║ ║ ║ ║ API (MTProto)║ ║ ║ ║ ╚═══════════════╝ ║ ║ ║ ║ ║ ╔═══════╩══════╗ ║ ╔════════╩═══════╗ ╔═══════╩══════╗ ║ /config/... ║ ╚═════════║ MariaDB :3306 ║ ║MariaDB :3307 ║ ║ (volumes) ║ ║ DB: feeder ║ ║ DB: users ║ ╚══════════════╝ ╚════════════════╝ ╚══════════════╝ ``` ### Comunicación entre Servicios | Origen | Destino | Protocolo | Propósito | |--------|---------|-----------|-----------| | Frontend | API Feeder | HTTP/REST | Alertas, mensajes, reglas, grupos, estadísticas | | Frontend | API Users | HTTP/REST | Login, gestión de usuarios | | Frontend | Backup Service | HTTP/REST | Estado y descarga de backups | | API Feeder | Telegram | MTProto (Telethon) | Captura de mensajes y adjuntos | | API Feeder | API Feeder (interno) | HTTP/REST | Persistencia de mensajes vía `api_implementations.py` | | Backup Service | MariaDB Feeder | TCP/MySQL | mysqldump para backup | | Backup Service | MariaDB Users | TCP/MySQL | mysqldump para backup | | NGINX | Todos los servicios | HTTP (reverse proxy) | Enrutamiento y terminación SSL | ### Seguridad - **JWT compartido**: Todos los microservicios validan tokens con la misma `SECRET_KEY` - **Roles**: `admin` y `operator` con controles en cada endpoint - **Rate limiting**: Registro público limitado a 5 peticiones/minuto (SlowAPI) - **HTTPS**: Terminación SSL en NGINX con soporte TLSv1.2 y TLSv1.3 --- ## Microservicios ### 1. Frontend — Streamlit **Propósito**: Interfaz de usuario para el monitoreo y gestión de la plataforma. **Lenguaje**: Python **3.11** **Ubicación**: `/frontend` | Librería | Versión | Propósito | |----------|---------|-----------| | Streamlit | ≥ 1.28.0 | Framework web reactivo | | Requests | ≥ 2.31.0 | Cliente HTTP hacia las APIs | | Pandas | ≥ 2.0.0 | Manipulación de datos en dashboards | | ReportLab | ≥ 3.6.0 | Generación de reportes PDF | | Matplotlib | ≥ 3.7.0 | Gráficos estáticos auxiliares | **Funcionalidades**: - Panel de inicio con métricas y estado del alimentador - Gestión de alertas con notas, cambio de estado y exportación PDF - Búsqueda avanzada de mensajes con filtros por texto, grupo, remitente y fecha - Descarga de adjuntos directamente desde Telegram - Exploración de remitentes con historial de mensajes - Estadísticas con gráficos de línea, barras, heatmaps y ranking de senders - Panel de administración para gestión de usuarios, auditoría y backups --- ### 2. API Feeder — FastAPI **Propósito**: Backend principal. Captura mensajes de Telegram, evalúa reglas y sirve los datos al Frontend. **Lenguaje**: Python **3.11** **Ubicación**: `/app` | Librería | Versión | Propósito | |----------|---------|-----------| | FastAPI | 0.104.1 | Framework REST asíncrono | | Uvicorn | 0.24.0 | Servidor ASGI | | Telethon | 1.28.5 | Cliente MTProto para Telegram | | SQLAlchemy | 2.0.23 | ORM | | PyMySQL | 1.1.0 | Driver MySQL/MariaDB | | Pydantic | 2.11.9 | Validación y serialización | | Alembic | 1.11.1 | Migraciones de base de datos | | python-jose | 3.3.0 | Generación y validación de JWT | | python-dotenv | 1.0.0 | Gestión de variables de entorno | | httpx | latest | Cliente HTTP asíncrono | | aiofiles | 23.2.1 | I/O asíncrono de archivos | | Requests | 2.32.5 | Cliente HTTP síncrono (integraciones internas) | **Endpoints principales**: | Grupo | Método | Ruta | Descripción | |-------|--------|------|-------------| | Messages | POST | `/messages/` | Crear mensaje + evaluar reglas | | Messages | GET | `/messages/search/` | Búsqueda con filtros | | Alerts | GET | `/alerts/` | Listar con filtros | | Alerts | POST | `/alerts/{id}/resolve` | Cerrar alerta | | Alerts | POST | `/alerts/{id}/in-progress` | Marcar en curso | | Rules | POST | `/rules/` | Crear regla (con apply_to_history) | | Groups | PATCH | `/groups/{id}/update-position` | Actualizar cursor de mensajes | | Attachments | GET | `/attachments/{id}/download` | Descargar adjunto desde Telegram | | Audit | GET | `/audit/` | Consultar logs de auditoría | | Stats | GET | `/stats/` | Métricas y estadísticas agregadas | | Manage | POST | `/manage/` | Agregar grupo/canal de Telegram | | Manage | GET | `/manage/init-session` | Iniciar autenticación Telegram | | Manage | POST | `/manage/verify-code` | Verificar código de autenticación | --- ### 3. API Users — FastAPI **Propósito**: Gestión de usuarios, autenticación y auditoría de cambios de permisos. **Lenguaje**: Python **3.11** **Ubicación**: `/usuarios` | Librería | Versión | Propósito | |----------|---------|-----------| | FastAPI | 0.104.1 | Framework REST | | Uvicorn | 0.24.0 | Servidor ASGI | | SQLAlchemy | 2.0.23 | ORM | | PyMySQL | 1.1.2 | Driver MySQL/MariaDB | | Pydantic | 2.5.0 | Validación de datos | | passlib[bcrypt] | 1.7.4 | Hash seguro de contraseñas | | bcrypt | 4.0.1 | Backend de hashing | | python-jose | 3.3.0 | JWT | | SlowAPI | latest | Rate limiting en endpoints públicos | | python-multipart | 0.0.6 | Formularios multipart | **Endpoints principales**: | Método | Ruta | Descripción | |--------|------|-------------| | POST | `/api/v1/login` | Autenticación — devuelve JWT | | GET | `/api/v1/users/` | Listar usuarios (admin) | | GET | `/api/v1/users/pending` | Usuarios pendientes de aprobación | | POST | `/api/v1/users/common` | Registro público (rate-limited) | | PUT | `/api/v1/users/{id}` | Actualizar datos | | PATCH | `/api/v1/users/{id}/role` | Cambiar rol | | POST | `/api/v1/users/{id}/activate` | Activar usuario | | GET | `/api/v1/logs/users` | Historial de modificaciones | --- ### 4. Backup Service — FastAPI **Propósito**: Centraliza la generación y verificación de backups del sistema completo. **Lenguaje**: Python **3.11** **Ubicación**: `/backup_service` | Librería | Versión | Propósito | |----------|---------|-----------| | FastAPI | 0.104.1 | Framework REST | | Uvicorn | 0.24.0 | Servidor ASGI | | python-jose | 3.3.0 | Validación JWT (mismo SECRET_KEY) | | mysqldump / mysqladmin | sistema | Dump de bases de datos (instalados en Dockerfile) | **Endpoints**: | Método | Ruta | Descripción | |--------|------|-------------| | GET | `/backup` | Genera y descarga ZIP con los componentes seleccionados | | GET | `/backup/status` | Estado de cada componente sin generar backup | | GET | `/health` | Verificación de salud del servicio | **Componentes exportables**: - `databases/` — mysqldump de las bases de datos Feeder y Users - `config/` — nginx.conf y docker-compose.yml - `ssl/` — Certificados SSL - `telegram_sessions/` — Archivos `.session` de autenticación de Telegram --- ## Flujo del Alimentador El **Feeder** (alimentador) es el núcleo de captura del sistema. Se ejecuta en un hilo de fondo independiente al inicio de la API y opera en ciclos continuos. ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ INICIO DE LA API (startup_event) │ │ └─► Lanza run_sync_scraper() en thread separado via asyncio.to_thread │ └──────────────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────┐ │ CICLO PRINCIPAL (run_sync_scraper) │ │ │ │ ┌─ INICIO DEL CICLO ──────────────────────────────────────────────────┐ │ │ │ │ │ │ │ 1. TelegramChatSingleton.get_scraper() │ │ │ │ └─► ¿Existe instancia singleton? │ │ │ │ ├─ NO → TelegramClientManager.connect() │ │ │ │ │ └─► Busca session_*.session en /telegram_sessions│ │ │ │ │ Autentica con Telethon (MTProto) │ │ │ │ └─ SÍ → Reutiliza cliente existente │ │ │ │ │ │ │ │ 2. scraper.add_chats() │ │ │ │ └─► GET /groups/ → obtiene todos los grupos activos │ │ │ │ Para cada grupo: │ │ │ │ └─► Consulta Telegram con get_entity(id) │ │ │ │ Actualiza nombre, tipo y descripción en la DB │ │ │ │ │ │ │ │ 3. scraper.feeder_loop() │ │ │ │ └─► Para cada grupo en la DB: │ │ │ │ │ │ │ │ a) set_chat_id(group_id) │ │ │ │ └─► Configura el canal objetivo en Telethon │ │ │ │ │ │ │ │ b) self.first_id = group.message_position │ │ │ │ └─► Lee el cursor del último mensaje procesado │ │ │ │ │ │ │ │ c) refresh_chat() │ │ │ │ └─► GetHistoryRequest(min_id=first_id) │ │ │ │ Descarga en lotes de 100 solo mensajes nuevos │ │ │ │ │ │ │ │ d) get_and_post_message_info() │ │ │ │ │ │ │ │ │ ├─► _preload_senders() │ │ │ │ │ └─► Para cada sender_id único: │ │ │ │ │ GET /senders/{id} → ¿existe? │ │ │ │ │ NO → get_entity(id) en Telegram │ │ │ │ │ POST /senders/ → crea el remitente │ │ │ │ │ │ │ │ │ └─► Para cada mensaje descargado: │ │ │ │ │ │ │ │ │ ├─► Extrae: id, content, date, sender_id, │ │ │ │ │ group_id, media (adjunto si existe) │ │ │ │ │ │ │ │ │ ├─► POST /messages/ (API interna) │ │ │ │ │ │ │ │ │ │ │ └─► Endpoint crea el mensaje y: │ │ │ │ │ Para cada regla activa: │ │ │ │ │ └─► re.search(regex, content) │ │ │ │ │ ¿Coincide? → crea Alert(status=open)│ │ │ │ │ │ │ │ │ └─► Si tiene adjunto → POST /attachments/ │ │ │ │ │ │ │ │ e) act_message_position(group_id, last_message_id) │ │ │ │ └─► PATCH /groups/{id}/update-position │ │ │ │ Actualiza el cursor para el próximo ciclo │ │ │ │ │ │ │ │ 4. Fin del ciclo → sleep(200 segundos) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ ⚠️ Si ocurre una excepción en cualquier punto: │ │ └─► scraper_status["last_error"] = str(e) │ │ sleep(60 segundos) │ │ El singleton mantiene el cliente → intento de reconexión │ └──────────────────────────────────────────────────────────────────────────┘ ``` ### Descarga de Adjuntos (bajo demanda) Cuando un usuario descarga un adjunto desde la UI, se sigue un flujo independiente para no interferir con el ciclo del Feeder: ``` Frontend └─► GET /attachments/{id}/download │ ├─► Obtiene metadata del adjunto (group_id, message_id) │ ├─► TelegramChatSingleton.get_tmp_scraper() │ └─► Crea un TelegramClientManager temporal │ Copia el .session file a un archivo temporal │ Lanza un thread dedicado con su propio event loop │ └─► download_attachment_to_buffer(group_id, message_id) └─► client.get_messages(group_id, ids=message_id) client.download_media(message, file=BytesIO()) Devuelve los bytes → StreamingResponse al Frontend Elimina la sesión temporal al finalizar ``` ### Configuración del Ciclo Los parámetros del ciclo se pueden ajustar directamente en `app/main.py`: ```python scraper_config = { "cicle_time": 200, # segundos entre ciclos (recomendado ≥ 200 para evitar flood) "error_delay": 60, # segundos de espera tras un error antes de reintentar } ``` --- ## Requisitos Previos ### Hardware Mínimo | Recurso | Mínimo | Recomendado | |---------|--------|-------------| | CPU | 2 núcleos | 4 núcleos | | RAM | 4 GB | 8 GB | | Almacenamiento | 20 GB | 50 GB+ | ### Software Requerido | Componente | Versión Mínima | Instalación | |-----------|----------------|-------------| | Docker | 20.10+ | https://docs.docker.com/engine/install/ | | Docker Compose | 1.29+ | Incluido en Docker Desktop | | Git | 2.20+ | https://git-scm.com/downloads | | jq (solo Linux/macOS) | 1.6+ | `sudo apt install jq` o `brew install jq` | > **Nota sobre Python**: El proyecto utiliza **Python 3.11** en todos los microservicios. La versión está declarada en cada `Dockerfile` (`FROM python:3.11-slim`). No es necesario tener Python instalado localmente; Docker lo gestiona de forma aislada. ### Credenciales Necesarias - **Telegram API ID y API Hash**: Obtener en https://my.telegram.org/apps con la cuenta que se usará para el monitoreo - **Número de teléfono** de esa cuenta (formato internacional, ej: `+5491112345678`) - Acceso a los grupos/canales de Telegram que se desean monitorear --- ## Instalación y Configuración ### Paso 1 — Clonar el Repositorio ```bash git clone https://github.com/tu-usuario/tip.git cd tip ``` ### Paso 2 — Crear el Archivo `.env` ```bash cp .env.example .env ``` Edita `.env` con tus valores reales: ```env # ── TELEGRAM ──────────────────────────────────────────────────────────── # Obtener en https://my.telegram.org/apps TELEGRAM_API_ID=123456789 TELEGRAM_API_HASH=abcdef0123456789abcdef0123456789 TELEGRAM_TELEPHONE=+5491112345678 # ── SEGURIDAD ──────────────────────────────────────────────────────────── # Clave compartida entre todos los microservicios (mínimo 20 caracteres) # Generar con: openssl rand -hex 32 SECRET_KEY=reemplazar_con_clave_secreta_minimo_32_chars # ── BASES DE DATOS ─────────────────────────────────────────────────────── DB_ROOT_PASS_FEEDER=password_feeder DB_ROOT_PASS_USERS=password_users # ── ADMIN (creado automáticamente en el primer inicio) ────────────────── ADMIN_EMAIL=admin@tudominio.com ADMIN_PASSWORD=contraseña_admin_segura ``` ### Paso 3 — Configurar `docker-compose.yml` ```bash cp docker-compose_example.yml docker-compose.yml ``` Reemplaza los valores marcados con `YOUR-*`: ```yaml # Contraseñas de bases de datos database: environment: MYSQL_ROOT_PASSWORD: password_feeder # ← cambiar database_users: environment: MYSQL_ROOT_PASSWORD: password_users # ← cambiar # URLs de conexión a las bases de datos api: environment: DATABASE_URL: mariadb+pymysql://root:password_feeder@database:3306/feeder TELEGRAM_API_ID: TU_API_ID TELEGRAM_API_HASH: TU_API_HASH TELEGRAM_TELEPHONE: TU_TELEFONO SECRET_KEY: TU_SECRET_KEY api_users: environment: DATABASE_URL: mariadb+pymysql://root:password_users@database_users:3307/users SECRET_KEY: TU_SECRET_KEY # ← debe ser la misma que api ADMIN_EMAIL: admin@tudominio.com ADMIN_PASSWORD: contraseña_admin # URLs para el backup service backup: environment: FEEDER_DATABASE_URL: mariadb+pymysql://root:password_feeder@database:3306/feeder USERS_DATABASE_URL: mariadb+pymysql://root:password_users@database_users:3307/users SECRET_KEY: TU_SECRET_KEY ``` ### Paso 4 — Configurar NGINX ```bash mkdir -p nginx/ssl cp nginx/nginx.conf_example nginx/nginx.conf ``` Edita `nginx/nginx.conf` y reemplaza `localhost` con tu dominio: ```nginx server_name tu_dominio.com; ``` Para **desarrollo local sin SSL**, comenta el bloque HTTPS y usa solo el bloque HTTP. **Para producción con Let's Encrypt**: ```bash # Instalar certbot (fuera de Docker) sudo apt install certbot # Generar certificados sudo certbot certonly --standalone -d tu_dominio.com # Copiar al directorio del proyecto sudo cp /etc/letsencrypt/live/tu_dominio.com/fullchain.pem ./nginx/ssl/ sudo cp /etc/letsencrypt/live/tu_dominio.com/privkey.pem ./nginx/ssl/ sudo chown $(whoami):$(whoami) ./nginx/ssl/* ``` ### Paso 5 — Iniciar los Contenedores ```bash # Construir imágenes e iniciar todos los servicios docker compose up -d --build # Verificar que todos estén corriendo docker compose ps ``` Resultado esperado: ``` NAME SERVICE STATUS feeder_api api running users_api api_users running frontend frontend running backup_service backup running feeder_db database running (healthy) users_db database_users running (healthy) nginx_proxy nginx running ``` ```bash # Ver logs en tiempo real docker compose logs -f api api_users ``` ### Paso 6 — Autenticar la Sesión de Telegram La primera vez (o tras reinstalación) es necesario autenticar el cliente de Telegram: 1. Accede a la UI como **admin**: https://tu_dominio.com 2. Ve a **Panel de Administración** → **Sistema** → **Alimentador** 3. Haz clic en **Iniciar Nueva Sesión** 4. Revisa el código de verificación que llegó a tu cuenta de Telegram 5. Ingrésalo en el campo correspondiente (más la contraseña 2FA si aplica) 6. El alimentador se activará automáticamente ### Paso 7 — Agregar Grupos a Monitorear 1. Ve a **Grupos y Canales** → **Agregar grupo** 2. Abre el grupo en Telegram Web (`web.telegram.org`) 3. Copia la URL completa (contiene el ID: `.../#-100XXXXXXXXX`) 4. Pégala en el campo y haz clic en **Agregar Grupo** 5. El sistema valida el acceso contra Telegram y lo registra --- ## Gestión de Backups ### Generar un Backup #### Desde la UI 1. Accede como **admin** 2. Ve a **Panel de Administración** → **Sistema** → **Backup del Sistema** 3. Selecciona los componentes a incluir 4. Haz clic en **⬇️ Generar y Descargar Backup** 5. Guarda el archivo `tip_backup_YYYYMMDD_HHMMSS.zip` en lugar seguro #### Desde la línea de comandos ```bash # Primero, obtener un token JWT (reemplazar por tus credenciales) TOKEN=$(curl -s -X POST http://localhost:8090/api/v1/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@tudominio.com","password":"tu_password"}' \ | jq -r '.access_token') # Solicitar el backup curl -X GET \ "http://localhost:8099/backup?include_db=true&include_config=true&include_ssl=true&include_sessions=true" \ -H "Authorization: Bearer $TOKEN" \ -o "tip_backup_$(date +%Y%m%d_%H%M%S).zip" ``` --- ### Restaurar un Backup > ⚠️ **ADVERTENCIA**: La restauración sobrescribe datos existentes. Asegúrate de que es lo que necesitas antes de continuar. #### Windows (PowerShell) ```powershell # 1. Coloca el archivo tip_backup_*.zip en la raíz del proyecto # 2. Abre PowerShell como Administrador y navega al directorio cd C:\ruta\al\proyecto # 3. Habilitar ejecución de scripts (si no está habilitado) Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser # 4. Ejecutar el script .\restore_backup.ps1 ``` #### Linux / macOS (Bash) ```bash # 1. Coloca el archivo tip_backup_*.zip en la raíz del proyecto # 2. Dar permisos de ejecución al script chmod +x restore_backup.sh # 3. Ejecutar el script ./restore_backup.sh ``` #### ¿Qué hace el script de restauración? ``` INICIO │ ├─ 1. Solicita confirmación al usuario │ ├─ 2. Localiza el tip_backup_*.zip más reciente en el directorio actual │ ├─ 3. Extrae el contenido en ./temp_restore/ │ ├─ 4. Lee manifest.json → identifica componentes incluidos y advertencias │ ├─ 5. Obtiene credenciales de las bases de datos desde docker-compose.yml │ ├─ 6. Por cada componente en el manifiesto: │ ├─ database:feeder → levanta feeder_db y restaura el .sql │ ├─ database:users → levanta users_db y restaura el .sql │ ├─ config:* → copia nginx.conf y/o docker-compose.yml │ ├─ ssl → copia certificados a ./nginx/ssl/ │ └─ telegram_sessions → copia .session a ./app/telegram_sessions/ │ ├─ 7. Muestra las advertencias registradas en el manifiesto │ ├─ 8. Elimina ./temp_restore/ │ └─ 9. Pregunta si desea reiniciar los contenedores (docker compose down && up) ``` #### Dependencias del Script | Dependencia | Windows | Linux/macOS | |-------------|---------|-------------| | Docker + Docker Compose | ✅ Requerido | ✅ Requerido | | jq | No requerido (usa PowerShell nativo) | ✅ `sudo apt install jq` | --- ### Buenas Prácticas de Backup - **Frecuencia**: Realiza backups diarios en producción, especialmente antes de actualizaciones - **Validación**: Prueba la restauración en un entorno de prueba periódicamente - **Almacenamiento externo**: Guarda copias en un servidor remoto o servicio de almacenamiento (S3, OneDrive, etc.) - **Encriptación**: Si el backup contiene sesiones o datos sensibles, encríptalo antes de transferirlo: ```bash # Linux/macOS openssl enc -aes-256-cbc -salt -in tip_backup_*.zip -out tip_backup_encrypted.zip # Descifrar openssl enc -d -aes-256-cbc -in tip_backup_encrypted.zip -out tip_backup_restored.zip ``` --- ## Troubleshooting ### Los contenedores no inician ```bash # Ver logs completos de todos los servicios docker compose logs # Ver logs de un servicio en particular docker compose logs api docker compose logs database # Reconstruir imágenes sin caché docker compose down docker compose up -d --build --force-recreate ``` ### Error de conexión a la base de datos ```bash # Verificar que MariaDB está aceptando conexiones docker compose exec database mysql -u root -p -e "SELECT 1;" # Verificar conectividad entre contenedores docker compose exec api ping database ``` ### El alimentador aparece como inactivo ```bash # Verificar si hay archivos de sesión de Telegram docker compose exec api ls -la /app/telegram_sessions/ # Si no hay sesión o está corrupta, eliminarla y autenticar de nuevo desde la UI docker compose exec api rm -f /app/telegram_sessions/session_* # Luego: Panel de Administración → Sistema → Iniciar Nueva Sesión ``` ### NGINX devuelve 502 Bad Gateway ```bash # Verificar que los servicios upstream estén corriendo docker compose ps # Validar la configuración de NGINX docker compose exec nginx nginx -t # Ver logs de NGINX docker compose logs nginx ``` ### Las alertas no se generan automáticamente ```bash # Verificar que existen reglas activas curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/rules/ # Verificar que el feeder está capturando mensajes docker compose logs api | grep -E "Feeding|Cycle|feeder_loop" # Verificar que no hay errores de regex en las reglas docker compose logs api | grep -i "regex\|WARN" ``` --- ## Estructura del Proyecto ``` tip/ ├── app/ # API Feeder │ ├── alembic/ # Migraciones de base de datos │ ├── integrations/ # Cliente Telegram (chats.py, api_implementations.py) │ ├── routers/ # Endpoints REST │ ├── main.py # Entry point + scraper loop │ ├── models.py # Modelos SQLAlchemy │ ├── schemas.py # Schemas Pydantic │ ├── auth.py # JWT helpers │ └── audit.py # Logger de auditoría ├── usuarios/ # API Users │ ├── main.py │ ├── models.py │ ├── schemas.py │ ├── crud.py │ ├── services.py │ └── dependencies.py ├── frontend/ # UI Streamlit │ ├── app.py │ ├── src/ │ │ ├── api.py # Cliente HTTP hacia las APIs │ │ ├── auth.py # Login / sesión │ │ └── pages/ │ │ ├── dashboard.py │ │ └── views/ # alerts, messages, rules, groups, stats, ... │ └── .streamlit/ │ ├── config.toml # Tema visual │ └── secrets.toml ├── backup_service/ # Backup Service │ ├── main.py │ ├── requirements.txt │ └── Dockerfile ├── nginx/ │ ├── nginx.conf # Configuración del proxy (generada desde el ejemplo) │ └── ssl/ # Certificados SSL (excluidos del repo) ├── Dockerfile # Imagen API Feeder ├── Dockerfile_users # Imagen API Users ├── Dockerfile_frontend # Imagen Frontend ├── docker-compose.yml # Orquestación (generado desde el ejemplo) ├── docker-compose_example.yml # Plantilla de configuración ├── entrypoint.sh # Ejecuta migraciones Alembic antes de iniciar la API ├── restore_backup.sh # Script de restauración (Linux/macOS) ├── restore_backup.ps1 # Script de restauración (Windows) ├── requirements.txt # Dependencias API Feeder ├── requirements_users.txt # Dependencias API Users ├── requirements_frontend.txt # Dependencias Frontend └── .gitignore ``` --- *Plataforma desarrollada para uso interno — Municipio de Paraná.*