From c065ea704719c7677894dc091727c620206fb27f Mon Sep 17 00:00:00 2001 From: Eduardo David Paredes Vara Date: Wed, 3 Dec 2025 16:13:26 +0000 Subject: [PATCH] Adding documentation --- README.md | 368 +++++++++++++++++++++++++++++++++++++ Traefik/README.md | 312 +++++++++++++++++++++++++++++++ adguard/README.md | 367 +++++++++++++++++++++++++++++++++++++ authentik/README.md | 345 ++++++++++++++++++++++++++++++++++ gitea/README.md | 379 ++++++++++++++++++++++++++++++++++++++ n8n/README.md | 370 +++++++++++++++++++++++++++++++++++++ ruleta/README.md | 438 ++++++++++++++++++++++++++++++++++++++++++++ trilium/README.md | 382 ++++++++++++++++++++++++++++++++++++++ wireguard/README.md | 435 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 3396 insertions(+) create mode 100644 README.md create mode 100644 Traefik/README.md create mode 100644 adguard/README.md create mode 100644 authentik/README.md create mode 100644 gitea/README.md create mode 100644 n8n/README.md create mode 100644 ruleta/README.md create mode 100644 trilium/README.md create mode 100644 wireguard/README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b1ce22 --- /dev/null +++ b/README.md @@ -0,0 +1,368 @@ +# Portainer Stacks Repository + +Este repositorio contiene la configuración de Portainer y múltiples stacks de servicios Docker gestionados mediante Docker Compose. + +## 📋 Tabla de Contenidos + +- [Descripción](#descripción) +- [Arquitectura](#arquitectura) +- [Prerequisitos](#prerequisitos) +- [Instalación y Despliegue](#instalación-y-despliegue) +- [Stacks Disponibles](#stacks-disponibles) +- [Configuración](#configuración) +- [Uso](#uso) + +## 📖 Descripción + +Este proyecto proporciona una infraestructura completa de servicios containerizados utilizando: +- **Portainer** como gestor visual de contenedores Docker +- **Traefik** como reverse proxy con certificados SSL automáticos +- **Authentik** para autenticación SSO +- Múltiples servicios adicionales (Gitea, n8n, AdGuard, etc.) + +## 🏗️ Arquitectura + +La arquitectura sigue este orden de despliegue: + +1. **Portainer** (gestor de contenedores) - acceso directo por puerto 9443 +2. **Traefik** (reverse proxy) - desplegado desde Portainer +3. **Authentik** (SSO) - desplegado desde Portainer +4. **Resto de stacks** - desplegables desde Portainer + +Todos los servicios se comunican a través de la red Docker `proxy` y están protegidos por Traefik con SSL. + +> **⚠️ Importante**: Los registros DNS deben estar configurados ANTES de desplegar Traefik y Authentik para que los certificados SSL se generen correctamente. + +## ✅ Prerequisitos + +- Docker Engine (20.10+) +- Docker Compose (v2.0+) +- Dominio(s) configurado(s) apuntando a tu servidor +- Puertos 80 y 443 abiertos (o 9443 para modo directo) + +## 🚀 Instalación y Despliegue + +### Paso 1: Clonar el Repositorio + +```bash +git clone +cd Portainer_repo +``` + +### Paso 2: Crear la Red de Docker + +Todos los servicios comparten la red `proxy`: + +```bash +docker network create proxy +``` + +### Paso 3: Preparar Secretos de Portainer + +Crea el archivo de secreto para la clave de cifrado de Portainer: + +```bash +# Crear directorio para secretos +sudo mkdir -p /opt/portainer/secrets + +# Generar una clave aleatoria de 32 caracteres +openssl rand -base64 32 | sudo tee /opt/portainer/secrets/portainer + +# Asegurar permisos correctos +sudo chmod 600 /opt/portainer/secrets/portainer +``` + +### Paso 4: Desplegar Portainer (PRIMERO) + +Despliega Portainer con acceso directo por puerto 9443: + +```bash +docker compose -f docker-compose.9443.yml up -d +``` + +Verifica que Portainer esté corriendo: +```bash +docker ps | grep portainer +``` + +Accede a: `https://tu-servidor:9443` + +### Paso 5: Configuración Inicial de Portainer + +1. Accede a Portainer mediante `https://tu-servidor:9443` +2. Crea el usuario administrador (primera vez - tienes 5 minutos) +3. Selecciona el entorno Docker local +4. Completa la configuración inicial + +### Paso 6: Configurar Registros DNS + +**Antes de desplegar Traefik y Authentik**, configura los registros DNS: + +- Registro A para Traefik Dashboard (ej: `traefik.tudominio.com`) +- Registro A para Portainer UI (ej: `portainer.tudominio.com`) +- Registro A para Portainer API (ej: `portainer-api.tudominio.com`) +- Registro A para Authentik (ej: `auth.tudominio.com`) +- Cualquier otro dominio que vayas a usar + +> **⏰ Espera** a que los registros DNS se propaguen antes de continuar (puede tardar de minutos a horas). + +Verifica la propagación: +```bash +nslookup traefik.tudominio.com +nslookup portainer.tudominio.com +nslookup auth.tudominio.com +``` + +### Paso 7: Desplegar Traefik desde Portainer + +1. En Portainer, ve a **Stacks** → **Add stack** +2. Nombre: `traefik` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `Traefik/docker-compose.yml` +5. Añade el archivo de variables de entorno: `Traefik/stack.env` (o configúralas manualmente) +6. Haz clic en **Deploy the stack** + +Verifica que Traefik esté funcionando: +```bash +docker logs traefik +``` + +### Paso 8: Desplegar Authentik desde Portainer + +1. En Portainer, ve a **Stacks** → **Add stack** +2. Nombre: `authentik` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `authentik/docker-compose.yml` +5. Añade las variables de entorno necesarias +6. Haz clic en **Deploy the stack** + +#### Configuración de Authentik + +Una vez desplegado Authentik, necesitarás configurar: +- **Applications** (aplicaciones a proteger) +- **Providers** de tipo Forward Auth +- **Authorization Flow** de tipo Implicit +- **Outposts** para ejecutar los providers +- **Middleware** en Traefik + +Para instrucciones detalladas, consulta el [README de Authentik](authentik/README.md). + +### Paso 9: Configurar Variables de Entorno para Portainer UI + +Una vez Traefik y Authentik están funcionando, actualiza el archivo `.env` en la raíz del proyecto: + +```bash +nano .env +``` + +Variables principales a configurar: +- `PORTAINER_DOMAIN`: Tu dominio para Portainer UI (ej: `portainer.tudominio.com`) +- `PORTAINER_API_DOMAIN`: Tu dominio para la API de Portainer (ej: `portainer-api.tudominio.com`) +- `PORTAINER_API_IP_WHITELIST`: IPs permitidas para acceso directo a la API +- `TRAEFIK_AUTH_MIDDLEWARE`: Middleware de autenticación (ej: `authentik@docker`) + +### Paso 10: Actualizar Stack de Portainer (Opcional) + +Si deseas acceder a Portainer mediante dominio con SSL (en lugar del puerto 9443): + +1. En Portainer, ve a **Stacks** → **Add stack** +2. Nombre: `portainer` +3. Selecciona **Upload** y sube el archivo `docker-compose.yml` de la raíz +4. O usa **Repository** apuntando a la raíz del repositorio +5. Añade las variables de entorno del archivo `.env` +6. Haz clic en **Deploy the stack** + +> **Nota**: Esto reemplazará el despliegue inicial por puerto 9443 con acceso mediante dominio. + +### Paso 11: Desplegar Otros Stacks desde Portainer + +Una vez la infraestructura base está funcionando, puedes desplegar el resto de stacks: + +#### Método 1: Desde la UI de Portainer (Recomendado) + +1. Ve a **Stacks** → **Add stack** +2. Selecciona **Repository** +3. Configura el repositorio Git: + - URL: `` + - Reference: `main` (o tu rama) + - Compose path: `/docker-compose.yml` +4. Añade variables de entorno si es necesario +5. Haz clic en **Deploy the stack** + +#### Método 2: Desde línea de comandos + +```bash +# Ejemplo: Desplegar Authentik +cd authentik +docker compose up -d +cd .. + +# Ejemplo: Desplegar Gitea +cd gitea +docker compose up -d +cd .. +``` + +## 📦 Stacks Disponibles + +| Stack | Descripción | Carpeta | Documentación | +|-------|-------------|---------|---------------| +| **Traefik** | Reverse proxy con SSL automático | `Traefik/` | [README](Traefik/README.md) | +| **Portainer** | Gestor visual de Docker | Raíz (docker-compose.yml) | - | +| **Authentik** | Sistema de autenticación SSO (Forward Auth) | `authentik/` | [README](authentik/README.md) | +| **Gitea** | Servidor Git autoalojado con Actions | `gitea/` | [README](gitea/README.md) | +| **n8n** | Plataforma de automatización de workflows | `n8n/` | [README](n8n/README.md) | +| **AdGuard** | Bloqueador de anuncios DNS con DoT | `adguard/` | [README](adguard/README.md) | +| **Trilium** | Aplicación de notas jerárquicas | `trilium/` | [README](trilium/README.md) | +| **Wireguard** | VPN rápida y segura | `wireguard/` | [README](wireguard/README.md) | +| **Ruleta** | Aplicación Next.js personalizada | `ruleta/` | [README](ruleta/README.md) | + +> **📖 Nota**: Cada stack tiene su propio README con instrucciones detalladas de configuración, uso y troubleshooting. + +## ⚙️ Configuración + +### Archivo .env Principal + +El archivo `.env` en la raíz contiene las configuraciones globales: + +```env +# Imagen de Portainer +PORTAINER_IMAGE=portainer/portainer-ce:latest + +# Rutas de almacenamiento +PORTAINER_SECRET_PATH=/opt/portainer/secrets/portainer +PORTAINER_DATA_PATH=/opt/portainer/data + +# Configuración de red y proxy +TRAEFIK_DOCKER_NETWORK=proxy +TRAEFIK_ENTRYPOINT_SECURE=websecure +TRAEFIK_CERTRESOLVER=letsencrypt + +# Dominios +PORTAINER_DOMAIN=portainer.example.com +PORTAINER_API_DOMAIN=portainer-api.example.com + +# Seguridad +PORTAINER_API_IP_WHITELIST=10.8.0.0/24,172.18.0.1/32 +TRAEFIK_AUTH_MIDDLEWARE=authentik@docker +``` + +### Configuraciones por Stack + +Cada stack puede tener su propio archivo `stack.env` o `.env` en su carpeta correspondiente. + +## 🎯 Uso + +### Ver Logs de Portainer + +```bash +docker logs -f portainer +``` + +### Ver Estado de Todos los Contenedores + +```bash +docker ps -a +``` + +### Actualizar Portainer + +```bash +docker compose pull +docker compose up -d +``` + +### Reiniciar un Stack + +Desde Portainer UI o: +```bash +cd +docker compose restart +``` + +### Eliminar un Stack + +```bash +cd +docker compose down +# Para eliminar también volúmenes: +docker compose down -v +``` + +## 🔒 Seguridad + +### Acceso a Portainer UI + +- **Protegido por SSO**: La UI principal está protegida mediante Authentik (configurable con `TRAEFIK_AUTH_MIDDLEWARE`) +- **Dominio**: Accesible solo mediante el dominio configurado con SSL + +### Acceso a API de Portainer + +- **Whitelist IP**: La API está restringida a IPs específicas (VPN, localhost) +- **Dominio separado**: Usa un dominio diferente sin SSO para apps móviles +- **SSL**: Todo el tráfico está cifrado + +### Base de Datos Cifrada + +Portainer utiliza una clave de cifrado para proteger su base de datos, montada en: +- `/run/secrets/portainer` +- `/run/portainer/portainer` + +## 🛠️ Troubleshooting + +### Portainer no arranca + +1. Verifica que la red `proxy` existe: `docker network ls | grep proxy` +2. Revisa los logs: `docker logs portainer` +3. Verifica que el archivo de secreto existe y tiene permisos correctos +4. Verifica que el puerto 9443 no esté ocupado: `sudo netstat -tulpn | grep 9443` + +### No puedo acceder mediante dominio + +1. Verifica que el dominio apunta a tu servidor: `nslookup tudominio.com` +2. Verifica que los registros DNS están propagados +3. Verifica que Traefik esté corriendo: `docker ps | grep traefik` +4. Verifica la configuración de Traefik: `docker logs traefik` +5. Revisa las labels de Traefik en el docker-compose.yml +6. Verifica que los puertos 80 y 443 estén abiertos: `sudo netstat -tulpn | grep -E ':(80|443)'` +7. Como respaldo, siempre puedes acceder por `https://tu-servidor:9443` + +### Error de permisos con volúmenes (SELinux) + +Si usas SELinux, los volúmenes ya tienen la opción `:Z` configurada. Si persisten problemas: + +```bash +sudo chcon -Rt svirt_sandbox_file_t /opt/portainer/data +``` + +### Authentik no protege los servicios + +1. Verifica que el outpost esté corriendo y en estado **Healthy** +2. Revisa que las aplicaciones y providers estén correctamente configurados +3. Verifica que el authorization flow sea de tipo **Implicit** +4. Comprueba que el middleware de Traefik esté correctamente referenciado en las labels +5. Revisa los logs de Authentik: `docker logs authentik-server` +6. Verifica la conectividad entre Traefik y Authentik en la red `proxy` + +## 📝 Notas Adicionales + +- **Orden de despliegue**: Siempre desplegar Portainer (9443) → Traefik → Authentik → Resto de stacks +- **Registros DNS**: Configurar ANTES de desplegar Traefik para que Let's Encrypt funcione correctamente +- **Puerto 9443**: Mantén el acceso por puerto 9443 como respaldo en caso de problemas con Traefik +- **Backups**: Considera hacer backup regular de `/opt/portainer/data` y el archivo de secretos +- **Actualizaciones**: Actualiza las imágenes regularmente desde Portainer UI +- **Monitoreo**: Usa Portainer para monitorear recursos y logs de todos los contenedores + +## 📄 Licencia + +Consulta el archivo LICENSE en este repositorio. + +## 🤝 Contribuciones + +Las contribuciones son bienvenidas. Por favor, abre un issue o pull request para sugerencias o mejoras. diff --git a/Traefik/README.md b/Traefik/README.md new file mode 100644 index 0000000..5114649 --- /dev/null +++ b/Traefik/README.md @@ -0,0 +1,312 @@ +# Traefik - Reverse Proxy + +Traefik es un reverse proxy moderno que gestiona automáticamente certificados SSL con Let's Encrypt y enruta el tráfico a tus servicios. + +## 📋 Descripción + +Este stack despliega Traefik configurado para: +- Redirección automática HTTP → HTTPS +- Certificados SSL automáticos con Let's Encrypt +- Integración con Docker para descubrimiento automático de servicios +- Dashboard web para monitoreo +- Soporte para configuración dinámica mediante archivos + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Crear la red `proxy` + ```bash + docker network create proxy + ``` + +2. **Registros DNS**: Configurar los registros A para todos tus dominios apuntando a tu servidor + +3. **Directorios**: Crear los directorios necesarios + ```bash + sudo mkdir -p /opt/traefik/dynamic + sudo mkdir -p /opt/traefik/letsencrypt + ``` + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `traefik` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `Traefik/docker-compose.yml` +5. Carga el archivo de variables de entorno: `Traefik/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno + +Edita el archivo `stack.env`: + +```env +# Imagen de Traefik +TRAEFIK_IMAGE=traefik:v3.2 + +# Red Docker +TRAEFIK_DOCKER_NETWORK=proxy + +# Puertos +TRAEFIK_HTTP_PORT=80 +TRAEFIK_HTTPS_PORT=443 + +# Let's Encrypt +TRAEFIK_ACME_EMAIL=tu-email@ejemplo.com +TRAEFIK_ACME_STORAGE=/letsencrypt/acme.json + +# Nivel de log (DEBUG, INFO, WARN, ERROR) +TRAEFIK_LOG_LEVEL=INFO + +# Directorios +TRAEFIK_DYNAMIC_DIR=/opt/traefik/dynamic +TRAEFIK_LETSENCRYPT_DIR=/opt/traefik/letsencrypt +``` + +> **⚠️ Importante**: Cambia `TRAEFIK_ACME_EMAIL` con tu email real. + +## ⚙️ Configuración + +### Características Principales + +- **Redirección automática**: Todo el tráfico HTTP (puerto 80) se redirige automáticamente a HTTPS (puerto 443) +- **Let's Encrypt**: Certificados SSL automáticos mediante HTTP Challenge +- **Docker Provider**: Detecta automáticamente servicios Docker con labels de Traefik +- **File Provider**: Permite configuración dinámica mediante archivos en `/opt/traefik/dynamic` + +### Configuración Dinámica + +Puedes añadir configuraciones adicionales en `/opt/traefik/dynamic/`. Ejemplo: + +**Archivo: `/opt/traefik/dynamic/middlewares.yml`** + +```yaml +http: + middlewares: + # Middleware de seguridad + security-headers: + headers: + stsSeconds: 31536000 + stsIncludeSubdomains: true + stsPreload: true + contentTypeNosniff: true + frameDeny: true + + # Middleware de compresión + compression: + compress: {} + + # Rate limiting + rate-limit: + rateLimit: + average: 100 + burst: 50 +``` + +### Acceso al Dashboard + +El dashboard está deshabilitado por defecto (`api.insecure=false`). Para habilitarlo de forma segura: + +**Opción 1: Mediante Traefik con Authentik** + +Añade las siguientes labels al servicio de Traefik: + +```yaml +labels: + traefik.http.routers.dashboard.rule: "Host(`traefik.tudominio.com`)" + traefik.http.routers.dashboard.entrypoints: "websecure" + traefik.http.routers.dashboard.tls.certresolver: "letsencrypt" + traefik.http.routers.dashboard.service: "api@internal" + traefik.http.routers.dashboard.middlewares: "authentik@docker" +``` + +**Opción 2: Acceso local (inseguro - solo desarrollo)** + +Cambia en el `docker-compose.yml`: +```yaml +- "--api.insecure=true" +``` + +Luego expón el puerto: +```yaml +ports: + - "8080:8080" +``` + +Accede a: `http://tu-servidor:8080/dashboard/` + +## 🔧 Uso con Servicios + +### Ejemplo: Proteger un servicio con Traefik + +En el `docker-compose.yml` de tu servicio: + +```yaml +services: + mi-servicio: + image: mi-imagen:latest + networks: + - proxy + labels: + # Habilitar Traefik + traefik.enable: "true" + traefik.docker.network: "proxy" + + # Router + traefik.http.routers.mi-servicio.rule: "Host(`miservicio.tudominio.com`)" + traefik.http.routers.mi-servicio.entrypoints: "websecure" + traefik.http.routers.mi-servicio.tls.certresolver: "letsencrypt" + + # Service (puerto interno del contenedor) + traefik.http.services.mi-servicio.loadbalancer.server.port: "80" + + # Middleware (opcional) + traefik.http.routers.mi-servicio.middlewares: "authentik@docker" + +networks: + proxy: + external: true +``` + +### Ejemplo: Servicio con múltiples rutas + +```yaml +labels: + # UI protegida con SSO + traefik.http.routers.app-ui.rule: "Host(`app.tudominio.com`)" + traefik.http.routers.app-ui.entrypoints: "websecure" + traefik.http.routers.app-ui.tls.certresolver: "letsencrypt" + traefik.http.routers.app-ui.middlewares: "authentik@docker" + traefik.http.routers.app-ui.priority: "10" + + # API pública sin protección + traefik.http.routers.app-api.rule: "Host(`app.tudominio.com`) && PathPrefix(`/api`)" + traefik.http.routers.app-api.entrypoints: "websecure" + traefik.http.routers.app-api.tls.certresolver: "letsencrypt" + traefik.http.routers.app-api.priority: "20" +``` + +> **Nota**: Mayor `priority` = mayor prioridad. Las rutas más específicas deben tener mayor prioridad. + +## 🛠️ Troubleshooting + +### Los certificados SSL no se generan + +1. Verifica que los registros DNS están configurados correctamente: + ```bash + nslookup tudominio.com + ``` + +2. Verifica que los puertos 80 y 443 están abiertos: + ```bash + sudo netstat -tulpn | grep -E ':(80|443)' + ``` + +3. Revisa los logs de Traefik: + ```bash + docker logs traefik + ``` + +4. Verifica el archivo de almacenamiento ACME: + ```bash + ls -lh /opt/traefik/letsencrypt/acme.json + # Debe tener permisos 600 + sudo chmod 600 /opt/traefik/letsencrypt/acme.json + ``` + +5. Comprueba los límites de Let's Encrypt: + - Let's Encrypt tiene límite de 5 certificados duplicados por semana + - Usa staging para pruebas: `--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory` + +### Un servicio no es accesible + +1. Verifica que el servicio está en la red `proxy`: + ```bash + docker network inspect proxy + ``` + +2. Revisa las labels de Traefik en el servicio: + ```bash + docker inspect nombre-servicio | grep -A 20 Labels + ``` + +3. Verifica los logs de Traefik: + ```bash + docker logs traefik | grep nombre-servicio + ``` + +4. Comprueba que `traefik.enable: "true"` está configurado + +### Error "Gateway Timeout" o "Bad Gateway" + +1. Verifica que el puerto del servicio es correcto: + ```yaml + traefik.http.services.mi-servicio.loadbalancer.server.port: "PUERTO_CORRECTO" + ``` + +2. Verifica que el servicio está corriendo: + ```bash + docker ps | grep mi-servicio + ``` + +3. Comprueba la conectividad desde Traefik al servicio: + ```bash + docker exec traefik ping nombre-servicio + ``` + +### Dashboard no accesible + +1. Si habilitaste `api.insecure=true`, accede a: `http://IP:8080/dashboard/` +2. Si usas dominio, verifica las labels y que el DNS está configurado +3. Revisa los logs: `docker logs traefik` + +## 📚 Recursos Adicionales + +- [Documentación oficial de Traefik](https://doc.traefik.io/traefik/) +- [Traefik con Docker](https://doc.traefik.io/traefik/providers/docker/) +- [Let's Encrypt con Traefik](https://doc.traefik.io/traefik/https/acme/) +- [Middlewares de Traefik](https://doc.traefik.io/traefik/middlewares/overview/) + +## 🔒 Seguridad + +- **Dashboard**: Protege siempre el dashboard con autenticación (Authentik, BasicAuth, etc.) +- **Logs**: Considera cambiar el nivel de log a `WARN` o `ERROR` en producción +- **Rate Limiting**: Implementa rate limiting en servicios públicos +- **Headers de seguridad**: Usa middlewares para añadir headers de seguridad + +## 💾 Backups + +Realiza backups regulares de: +- `/opt/traefik/letsencrypt/acme.json` (certificados SSL) +- `/opt/traefik/dynamic/` (configuración dinámica) + +```bash +# Backup +sudo tar -czf traefik-backup-$(date +%Y%m%d).tar.gz /opt/traefik/ + +# Restaurar +sudo tar -xzf traefik-backup-YYYYMMDD.tar.gz -C / +``` + +## 🔄 Actualizaciones + +Para actualizar Traefik: + +1. En Portainer, ve al stack de Traefik +2. Edita el archivo `stack.env` y cambia la versión: + ```env + TRAEFIK_IMAGE=traefik:v3.3 + ``` +3. Haz clic en **Update the stack** +4. O desde línea de comandos: + ```bash + cd Traefik + docker compose pull + docker compose up -d + ``` + +> **⚠️ Nota**: Revisa el [changelog de Traefik](https://github.com/traefik/traefik/releases) antes de actualizar versiones mayores. diff --git a/adguard/README.md b/adguard/README.md new file mode 100644 index 0000000..cd6ec81 --- /dev/null +++ b/adguard/README.md @@ -0,0 +1,367 @@ +# AdGuard Home - Bloqueador de Anuncios DNS + +AdGuard Home es un servidor DNS que bloquea anuncios y rastreadores a nivel de red. + +## 📋 Descripción + +Este stack despliega AdGuard Home con: +- Bloqueo de anuncios y rastreadores +- DNS-over-TLS (DoT) para privacidad +- Panel web protegido con Authentik +- Integración con Traefik para HTTPS +- Configuración persistente + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registro DNS**: Configura el registro A para tu dominio AdGuard +3. **IP Fija**: AdGuard necesita una IP fija en la red Docker +4. **Certificados DoT**: Necesitarás certificados SSL para DoT + +### Configurar IP Fija en la Red Proxy + +Primero, verifica el rango de IPs de la red `proxy`: + +```bash +docker network inspect proxy | grep Subnet +``` + +Luego, elige una IP fija dentro del rango (ej: `172.18.0.10`). + +### Generar Certificados para DoT + +```bash +# Crear directorio para certificados +sudo mkdir -p /opt/adguard/certs + +# Copiar certificados de Let's Encrypt (después de que Traefik los genere) +sudo cp /opt/traefik/letsencrypt/certificates/adguard.tudominio.com.crt /opt/adguard/certs/adguard.crt +sudo cp /opt/traefik/letsencrypt/certificates/adguard.tudominio.com.key /opt/adguard/certs/adguard.key + +# O genera certificados autofirmados para pruebas +openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /opt/adguard/certs/adguard.key \ + -out /opt/adguard/certs/adguard.crt \ + -subj "/CN=adguard.tudominio.com" +``` + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `adguard` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `adguard/docker-compose.yml` +5. Carga el archivo de variables de entorno: `adguard/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno + +Edita el archivo `stack.env`: + +```env +# Imagen +ADGUARD_IMAGE=adguard/adguardhome:latest + +# Dominio +ADGUARD_DOMAIN=adguard.tudominio.com + +# IP fija en la red proxy +ADGUARD_IPV4=172.18.0.10 + +# Puerto DoT (DNS-over-TLS) +ADGUARD_DOT_PORT=853 + +# Puerto HTTP del panel (interno) +ADGUARD_HTTP_PORT=80 + +# Rutas +ADGUARD_WORK_PATH=/opt/adguard/work +ADGUARD_CONF_PATH=/opt/adguard/conf +ADGUARD_CERT_CRT_PATH=/opt/adguard/certs/adguard.crt +ADGUARD_CERT_KEY_PATH=/opt/adguard/certs/adguard.key + +# Traefik +TRAEFIK_DOCKER_NETWORK=proxy +TRAEFIK_ENTRYPOINT_SECURE=websecure +TRAEFIK_CERTRESOLVER=letsencrypt +TRAEFIK_AUTH_MIDDLEWARE=authentik@docker +``` + +## ⚙️ Configuración Post-Instalación + +### 1. Configuración Inicial + +La primera vez que accedas a `https://adguard.tudominio.com`, se iniciará el asistente: + +1. **Puerto de escucha**: Deja 3000 (se cambiará automáticamente a 80) +2. **Usuario y contraseña**: Crea las credenciales de administrador +3. **Interfaces de red**: Escucha en todas las interfaces +4. **DNS upstream**: Configura servidores DNS (ej: `1.1.1.1`, `8.8.8.8`) + +> **Nota**: Si el panel escucha en puerto 3000, actualiza `ADGUARD_HTTP_PORT=3000` en el `stack.env` temporalmente. + +### 2. Configurar DNS-over-TLS (DoT) + +1. En el panel de AdGuard, ve a **Settings** → **Encryption settings** +2. Habilita **DNS-over-TLS** +3. Configura: + - **Server name**: `adguard.tudominio.com` + - **Certificate**: `/certs/adguard.crt` + - **Private key**: `/certs/adguard.key` +4. **Puerto**: 853 +5. Haz clic en **Save** + +### 3. Configurar Listas de Filtros + +AdGuard viene con listas por defecto, pero puedes añadir más: + +1. Ve a **Filters** → **DNS blocklists** +2. Añade listas populares: + - **Steven Black's Hosts**: Bloquea malware y anuncios + - **OISD**: Lista curada de dominios maliciosos + - **Hagezi**: Listas agresivas de bloqueo +3. Haz clic en **Add blocklist** y pega la URL + +Ejemplos: +``` +https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts +https://big.oisd.nl/ +https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/domains/pro.txt +``` + +### 4. Configurar DNS Upstream + +Para mejor privacidad, usa DNS cifrados: + +1. Ve a **Settings** → **DNS settings** +2. En **Upstream DNS servers**, añade: + ``` + https://dns.cloudflare.com/dns-query + https://dns.google/dns-query + tls://1.1.1.1 + tls://8.8.8.8 + ``` +3. En **Bootstrap DNS servers** (para resolver los DNS cifrados): + ``` + 1.1.1.1 + 8.8.8.8 + ``` + +## 📱 Configurar Clientes + +### Android - DNS Privado (DoT) + +1. Ve a **Ajustes** → **Conexiones** → **Más ajustes de conexión** +2. Selecciona **DNS privado** +3. Elige **Nombre del host del proveedor de DNS privado** +4. Introduce: `adguard.tudominio.com` +5. Guarda + +> Todo el tráfico DNS de tu móvil pasará por AdGuard, incluso fuera de casa. + +### iOS - DNS-over-HTTPS + +1. Descarga un perfil de configuración DoH +2. O usa apps como **AdGuard** o **DNSCloak** + +### Windows + +#### Opción 1: Cambiar DNS del Sistema + +1. Panel de Control → Redes → Propiedades del adaptador +2. IPv4 → Propiedades +3. DNS preferido: `IP-de-tu-servidor` +4. DNS alternativo: `8.8.8.8` + +#### Opción 2: DNS-over-HTTPS (Windows 11) + +1. Ajustes → Red e Internet → Ethernet/Wi-Fi +2. Editar DNS +3. Añade servidor DNS-over-HTTPS: `https://adguard.tudominio.com/dns-query` + +### Linux + +Edita `/etc/resolv.conf`: + +```bash +nameserver IP-de-tu-servidor +nameserver 8.8.8.8 +``` + +O con systemd-resolved: + +```bash +sudo nano /etc/systemd/resolved.conf +``` + +```ini +[Resolve] +DNS=IP-de-tu-servidor +FallbackDNS=8.8.8.8 +``` + +```bash +sudo systemctl restart systemd-resolved +``` + +### Router + +Configura AdGuard como DNS primario en tu router: +1. Accede al panel de tu router +2. Ve a configuración DHCP/DNS +3. DNS primario: `IP-de-tu-servidor` +4. DNS secundario: `8.8.8.8` + +> **Ventaja**: Todos los dispositivos de tu red usarán AdGuard automáticamente. + +## 🔧 Configuración Avanzada + +### Listas Blancas (Whitelist) + +Para permitir dominios bloqueados por error: + +1. Ve a **Filters** → **Custom filtering rules** +2. Añade reglas: + ``` + @@||ejemplo-permitido.com^ + @@||*.ejemplo.com^ + ``` + +### Bloquear Dominios Específicos + +``` +||dominio-bloqueado.com^ +||ads.ejemplo.com^ +``` + +### Reglas de Reescritura DNS + +Para resolver dominios internos: + +1. Ve a **Filters** → **DNS rewrites** +2. Añade entradas: + - **Domain**: `home.local` + - **Answer**: `192.168.1.10` + +### Clientes Personalizados + +Para aplicar configuraciones diferentes por cliente: + +1. Ve a **Settings** → **Client settings** +2. Añade cliente por IP o ID +3. Configura filtros específicos, upstream DNS, etc. + +### Estadísticas y Logs + +- **Dashboard**: Ve estadísticas de consultas, clientes, dominios bloqueados +- **Query log**: Revisa todas las consultas DNS en tiempo real +- **Filtros por cliente**: Ve qué dispositivos hacen más consultas + +## 🛠️ Troubleshooting + +### No puedo acceder al panel web + +1. Verifica que AdGuard está corriendo: + ```bash + docker ps | grep adguard + ``` + +2. Verifica los logs: + ```bash + docker logs adguardhome + ``` + +3. Si el panel está en puerto 3000, cambia `ADGUARD_HTTP_PORT=3000` temporalmente + +### DNS no resuelve dominios + +1. Verifica que AdGuard está escuchando: + ```bash + docker exec adguardhome netstat -tulpn + ``` + +2. Prueba DNS desde el servidor: + ```bash + nslookup google.com 172.18.0.10 + ``` + +3. Verifica que los upstream DNS están configurados + +### DoT no funciona en Android + +1. Verifica que el puerto 853 está abierto: + ```bash + sudo netstat -tulpn | grep 853 + ``` + +2. Verifica los certificados en AdGuard: + - Settings → Encryption → Verifica que están cargados correctamente + +3. Prueba DoT desde el servidor: + ```bash + kdig -d @adguard.tudominio.com +tls google.com + ``` + +### Algunos sitios no cargan + +1. Ve a **Query log** en AdGuard +2. Busca el dominio bloqueado +3. Añádelo a la whitelist si es necesario + +### IP fija causa conflictos + +Si la IP configurada está en uso: + +1. Elige otra IP del rango de la red `proxy` +2. Actualiza `ADGUARD_IPV4` en `stack.env` +3. Actualiza el stack + +## 📚 Recursos Adicionales + +- [Documentación oficial de AdGuard Home](https://github.com/AdguardTeam/AdGuardHome/wiki) +- [Listas de filtros](https://filterlists.com/) +- [Comparativa con Pi-hole](https://github.com/AdguardTeam/AdGuardHome#comparison) + +## 🔒 Seguridad + +- **Panel web**: Siempre protegido con Authentik (SSO) +- **DoT**: Cifra las consultas DNS entre cliente y servidor +- **Upstream DNS**: Usa DNS cifrados (DoH/DoT) para privacidad total +- **Logs**: Revisa regularmente los logs para detectar anomalías +- **Actualizaciones**: Mantén AdGuard actualizado + +## 💾 Backups + +```bash +# Backup de configuración +sudo tar -czf adguard-backup-$(date +%Y%m%d).tar.gz /opt/adguard/ + +# Restaurar +sudo tar -xzf adguard-backup-YYYYMMDD.tar.gz -C / +``` + +## 🔄 Actualizaciones + +1. Haz backup de la configuración +2. Actualiza en `stack.env`: + ```env + ADGUARD_IMAGE=adguard/adguardhome:latest + ``` +3. Actualiza el stack en Portainer +4. Verifica los logs y el panel web + +## 📊 Estadísticas + +AdGuard ofrece estadísticas detalladas: +- **Consultas bloqueadas**: Porcentaje y cantidad +- **Top clientes**: Dispositivos que más consultas hacen +- **Top dominios**: Sitios más visitados +- **Top dominios bloqueados**: Anuncios y rastreadores más frecuentes +- **Upstream DNS**: Rendimiento de los servidores DNS configurados + +Accede a estas estadísticas en el Dashboard de AdGuard. diff --git a/authentik/README.md b/authentik/README.md new file mode 100644 index 0000000..589bad5 --- /dev/null +++ b/authentik/README.md @@ -0,0 +1,345 @@ +# Authentik - Sistema de Autenticación SSO + +Authentik es un sistema de autenticación y autorización de código abierto que proporciona Single Sign-On (SSO) para tus aplicaciones. + +## 📋 Descripción + +Este stack despliega Authentik configurado para funcionar con Traefik mediante **Forward Authentication**, protegiendo tus servicios con autenticación centralizada. + +## 🚀 Despliegue + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `authentik` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `authentik/docker-compose.yml` +5. Carga el archivo de variables de entorno: `authentik/stack.env` +6. O añade manualmente las variables de entorno necesarias +7. Haz clic en **Deploy the stack** + +### Variables de Entorno Importantes + +Edita el archivo `stack.env` con tus valores: + +```env +# Secretos (genera valores aleatorios seguros) +AUTHENTIK_SECRET_KEY=tu-clave-secreta-aleatoria +AUTHENTIK_POSTGRESQL_PASSWORD=tu-password-db-aleatorio + +# Dominio de Authentik +AUTHENTIK_DOMAIN=auth.tudominio.com + +# Email y SMTP (opcional pero recomendado) +AUTHENTIK_EMAIL__HOST=smtp.tudominio.com +AUTHENTIK_EMAIL__PORT=587 +AUTHENTIK_EMAIL__USERNAME=noreply@tudominio.com +AUTHENTIK_EMAIL__PASSWORD=tu-password-email +AUTHENTIK_EMAIL__FROM=noreply@tudominio.com +``` + +## ⚙️ Configuración Post-Instalación + +Una vez desplegado Authentik, accede a su interfaz web en `https://auth.tudominio.com` y completa la configuración inicial. + +### 1. Acceso Inicial + +- Usuario por defecto: `akadmin` +- Contraseña: La que configures en el primer acceso +- Cambia la contraseña inmediatamente + +### 2. Crear Applications (Aplicaciones) + +Para cada servicio que quieras proteger (ej: Portainer, Traefik Dashboard, Gitea, etc.): + +1. Ve a **Applications** → **Create** +2. Completa el formulario: + - **Name**: `Portainer` (nombre descriptivo) + - **Slug**: `portainer` (identificador único en minúsculas) + - **Provider**: (lo crearás en el siguiente paso - déjalo vacío por ahora) + - **Policy engine mode**: `any` (permite acceso si alguna política coincide) + - **UI settings**: Configura el icono y apariencia (opcional) +3. Haz clic en **Create** + +### 3. Crear Providers de tipo Forward Auth + +Los providers conectan tus aplicaciones con Authentik. Para Forward Auth con Traefik: + +1. Ve a **Applications** → Tu aplicación → **Provider** → **Create** +2. Selecciona tipo: **Proxy Provider** +3. Completa el formulario: + - **Name**: `Portainer Provider` + - **Authorization flow**: Selecciona `default-provider-authorization-implicit-consent` (créalo si no existe - ver paso 4) + - **Type**: **Forward auth (single application)** + - **External host**: `https://portainer.tudominio.com` (URL completa de tu servicio) + - **Internal host**: `http://portainer:9000` (opcional - URL interna si Authentik debe hacer reverse proxy) + - **Internal host SSL validation**: Desactivado (si usas HTTP interno) +4. **Advanced settings**: + - **Token validity**: `hours=24` (duración de la sesión) + - **Cookie domain**: `.tudominio.com` (permite SSO entre subdominios) +5. Haz clic en **Create** +6. Vuelve a la aplicación y selecciona el provider que acabas de crear + +### 4. Crear Authorization Flow (Implicit) + +El authorization flow de tipo **implicit** permite autorización sin pantalla de consentimiento explícita: + +#### Opción A: Usar el flow por defecto + +Authentik suele incluir un flow llamado `default-provider-authorization-implicit-consent`. Si existe, úsalo directamente en tus providers. + +#### Opción B: Crear un flow personalizado + +Si necesitas crear uno nuevo: + +1. Ve a **Flows & Stages** → **Flows** → **Create** +2. Completa el formulario: + - **Name**: `Authorization Flow Implicit` + - **Title**: `Redirecting to application` + - **Slug**: `default-provider-authorization-implicit-consent` + - **Designation**: **Authorization** + - **Authentication**: `Require authentication` (el usuario debe estar autenticado) + - **Behavior settings**: + - **Layout**: `content_left` o el que prefieras +3. Haz clic en **Create** + +#### Añadir Stages al Flow + +1. Abre el flow que acabas de crear +2. Ve a la pestaña **Stage Bindings** +3. Añade el stage de consentimiento (opcional): + - Haz clic en **Bind existing stage** + - Selecciona `default-provider-authorization-consent` (o crea uno nuevo) + - **Order**: 10 + - **Evaluate on plan**: Activado + - **Re-evaluate policies**: Activado + +> **Nota**: Para implicit consent, puedes crear un flow sin stages de consentimiento, lo que permite autorización automática. + +#### Crear Stage de Consent (si no existe) + +Si necesitas crear el stage de consentimiento: + +1. Ve a **Flows & Stages** → **Stages** → **Create** +2. Tipo: **Consent Stage** +3. Completa: + - **Name**: `default-provider-authorization-consent` + - **Mode**: `always_require` o `hidden` (para implicit) + - **Consent expire in**: `weeks=4` (duración del consentimiento) +4. Haz clic en **Create** + +### 5. Configurar Outpost + +Los **outposts** son los componentes que ejecutan los providers y procesan las peticiones de autenticación: + +1. Ve a **Outposts** → **Outposts** → **Create** +2. Completa el formulario: + - **Name**: `authentik-embedded-outpost` (o el nombre que prefieras) + - **Type**: **Proxy** + - **Integration**: Déjalo vacío (el outpost embedded usa la integración por defecto) +3. **Applications**: Selecciona todas las aplicaciones que creaste (Portainer, Traefik, etc.) +4. **Configuration**: + ```yaml + authentik_host: https://auth.tudominio.com + authentik_host_insecure: false + log_level: info + object_naming_template: ak-outpost-%(name)s + docker_network: proxy + docker_labels: + traefik.enable: "true" + ``` +5. Haz clic en **Create** + +#### Verificar Estado del Outpost + +1. Ve a **Outposts** → **Outposts** +2. Verifica que tu outpost aparece en estado **Healthy** (saludable) +3. Si aparece como **Unhealthy**: + - Verifica los logs: `docker logs authentik-worker` + - Asegúrate de que el contenedor puede comunicarse con el servidor de Authentik + - Verifica la red Docker `proxy` + +### 6. Configurar Middleware en Traefik + +Para que Traefik use Authentik como forward auth, necesitas configurar el middleware. + +#### Opción A: Middleware en el stack de Authentik + +Añade las siguientes labels al servicio `authentik-server` en el `docker-compose.yml`: + +```yaml +labels: + # Middleware de Forward Auth + traefik.http.middlewares.authentik.forwardauth.address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik" + traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: "true" + traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: "X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid" +``` + +#### Opción B: Middleware en archivo de configuración de Traefik + +En el archivo de configuración dinámica de Traefik (`dynamic.yml`): + +```yaml +http: + middlewares: + authentik: + forwardAuth: + address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik" + trustForwardHeader: true + authResponseHeaders: + - "X-authentik-username" + - "X-authentik-groups" + - "X-authentik-email" + - "X-authentik-name" + - "X-authentik-uid" +``` + +### 7. Proteger Servicios con Authentik + +Una vez configurado el middleware, añade la label a los servicios que quieras proteger: + +```yaml +labels: + traefik.http.routers.portainer.middlewares: "authentik@docker" +``` + +O si definiste el middleware en archivo: + +```yaml +labels: + traefik.http.routers.portainer.middlewares: "authentik@file" +``` + +## 🔐 Gestión de Usuarios y Grupos + +### Crear Usuarios + +1. Ve a **Directory** → **Users** → **Create** +2. Completa los datos del usuario +3. Asigna grupos si es necesario +4. Haz clic en **Create** + +### Crear Grupos + +1. Ve a **Directory** → **Groups** → **Create** +2. Nombre del grupo (ej: `admins`, `users`) +3. Añade usuarios al grupo +4. Haz clic en **Create** + +### Crear Políticas de Acceso + +Para controlar quién puede acceder a cada aplicación: + +1. Ve a **Applications** → Tu aplicación → **Policy / Group / User Bindings** +2. Haz clic en **Bind existing policy/group/user** +3. Selecciona un grupo (ej: `admins`) +4. **Order**: 0 (menor número = mayor prioridad) +5. Haz clic en **Create** + +## 🔧 Configuración Avanzada + +### Configurar Múltiples Dominios (SSO entre subdominios) + +En la configuración del provider: +- **Cookie domain**: `.tudominio.com` (con el punto inicial) +- Esto permite que la sesión se comparta entre todos los subdominios + +### Configurar Email (SMTP) + +Para notificaciones y recuperación de contraseñas: + +1. Ve a **System** → **Settings** → **Email** +2. Configura los parámetros SMTP (o usa las variables de entorno en `stack.env`) + +### Configurar Autenticación de Dos Factores (2FA) + +1. Ve a **Flows & Stages** → **Stages** +2. Crea stages de tipo **Authenticator Validation Stage** (TOTP, WebAuthn, etc.) +3. Añade estos stages a tu authentication flow + +### Integración con Proveedores Externos (OAuth, SAML) + +1. Ve a **System** → **Providers** → **Create** +2. Selecciona el tipo (OAuth2, SAML, etc.) +3. Configura según el proveedor externo (Google, GitHub, etc.) + +## 🛠️ Troubleshooting + +### El outpost aparece como Unhealthy + +```bash +# Ver logs del worker +docker logs authentik-worker + +# Ver logs del servidor +docker logs authentik-server + +# Verificar conectividad de red +docker exec authentik-server ping authentik-postgresql +docker exec authentik-server ping authentik-redis +``` + +### Los servicios no están protegidos + +1. Verifica que el middleware de Traefik esté correctamente configurado +2. Comprueba que las labels en el servicio están correctas +3. Verifica los logs de Traefik: `docker logs traefik` +4. Asegúrate de que el provider está asociado a la aplicación +5. Verifica que el outpost esté en estado **Healthy** + +### Error "Invalid redirect_uri" + +1. Verifica que el **External host** en el provider coincide exactamente con la URL del servicio +2. Asegúrate de incluir el protocolo (`https://`) +3. No incluyas barras finales + +### Sesiones no persisten / Se desconecta constantemente + +1. Verifica que el **Cookie domain** esté configurado correctamente (`.tudominio.com`) +2. Comprueba que Redis esté funcionando: `docker logs authentik-redis` +3. Aumenta el **Token validity** en el provider + +### No puedo acceder al panel de Authentik + +1. Accede directamente por IP: `http://IP-servidor:9000` +2. Verifica los logs: `docker logs authentik-server` +3. Comprueba que el dominio DNS está configurado correctamente +4. Verifica que Traefik está redirigiendo correctamente + +## 📚 Recursos Adicionales + +- [Documentación oficial de Authentik](https://goauthentik.io/docs/) +- [Authentik con Traefik](https://goauthentik.io/docs/providers/proxy/forward_auth) +- [Configuración de Flows](https://goauthentik.io/docs/flow/) +- [Configuración de Outposts](https://goauthentik.io/docs/outposts/) + +## 🔒 Seguridad + +- **Cambia inmediatamente** el password por defecto de `akadmin` +- Genera valores **aleatorios** para `AUTHENTIK_SECRET_KEY` y `AUTHENTIK_POSTGRESQL_PASSWORD` +- Habilita **2FA** para usuarios administradores +- Realiza **backups regulares** de la base de datos PostgreSQL +- Mantén Authentik **actualizado** a la última versión + +## 💾 Backups + +Para hacer backup de la configuración de Authentik: + +```bash +# Backup de la base de datos PostgreSQL +docker exec authentik-postgresql pg_dump -U authentik authentik > authentik_backup.sql + +# Backup de Redis (sesiones) +docker exec authentik-redis redis-cli --rdb /data/dump.rdb +``` + +## 🔄 Actualizaciones + +1. En Portainer, ve a tu stack de Authentik +2. Haz clic en **Editor** +3. Actualiza las versiones de las imágenes si es necesario +4. Haz clic en **Update the stack** +5. O ejecuta: `docker compose pull && docker compose up -d` diff --git a/gitea/README.md b/gitea/README.md new file mode 100644 index 0000000..2967bf1 --- /dev/null +++ b/gitea/README.md @@ -0,0 +1,379 @@ +# Gitea - Servidor Git Autoalojado + +Gitea es un servidor Git ligero y autoalojado, similar a GitHub o GitLab. + +## 📋 Descripción + +Este stack despliega Gitea con: +- Base de datos PostgreSQL +- Servidor SSH para operaciones Git +- Gitea Actions (CI/CD similar a GitHub Actions) +- Act Runner para ejecutar pipelines +- Integración con Traefik y Authentik + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registro DNS**: Configura el registro A para tu dominio Gitea +3. **Puerto SSH**: El puerto SSH debe estar disponible (por defecto 222) + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `gitea` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `gitea/docker-compose.yml` +5. Carga el archivo de variables de entorno: `gitea/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno Importantes + +Edita el archivo `stack.env`: + +```env +# Imágenes +GITEA_IMAGE=gitea/gitea:latest +GITEA_POSTGRES_IMAGE=postgres:16 +GITEA_RUNNER_IMAGE=gitea/act_runner:latest + +# Base de datos +GITEA_DB_PASSWORD=tu-password-seguro-aleatorio + +# Dominios +GITEA_DOMAIN=git.tudominio.com +GITEA_ROOT_URL=https://git.tudominio.com + +# SSH +GITEA_SSH_DOMAIN=git.tudominio.com +GITEA_SSH_PORT=222 + +# Gitea Actions Runner +GITEA_RUNNER_REGISTRATION_TOKEN=tu-token-de-registro +``` + +## ⚙️ Configuración Post-Instalación + +### 1. Primer Acceso + +1. Accede a `https://git.tudominio.com` +2. Completa la configuración inicial: + - Base de datos: Ya está configurada (PostgreSQL) + - Configuración del servidor: Usa los valores predefinidos + - **Importante**: Crea la cuenta de administrador en este paso +3. Haz clic en **Install Gitea** + +### 2. Configurar Gitea Actions + +Para habilitar CI/CD con Gitea Actions: + +#### Paso 1: Generar Token de Registro + +1. Accede a Gitea como administrador +2. Ve a **Site Administration** → **Actions** → **Runners** +3. Haz clic en **Create new Runner** +4. Copia el **Registration Token** + +#### Paso 2: Actualizar el Stack + +1. Edita el archivo `stack.env` +2. Añade el token: + ```env + GITEA_RUNNER_REGISTRATION_TOKEN=tu-token-copiado + ``` +3. Actualiza el stack en Portainer + +#### Paso 3: Verificar el Runner + +1. En Gitea, ve a **Site Administration** → **Actions** → **Runners** +2. Deberías ver el runner registrado y activo +3. Nombre del runner: `act-runner-docker` (o el configurado en `GITEA_RUNNER_NAME`) + +### 3. Configurar SSH + +Para usar Git con SSH: + +```bash +# Clonar repositorio con SSH +git clone ssh://git@git.tudominio.com:222/usuario/repositorio.git + +# O configurar SSH en ~/.ssh/config +Host git.tudominio.com + HostName git.tudominio.com + Port 222 + User git + IdentityFile ~/.ssh/id_ed25519 +``` + +### 4. Integración con Authentik (SSO) + +Este stack tiene una configuración especial para Authentik: + +#### Rutas Protegidas + +- `/user/login` - Página de login (protegida con SSO) +- `/explore` - Explorar repositorios públicos (protegida) +- `/TheHomelessSherlock` - Perfil de usuario específico (protegido) + +#### Rutas Públicas + +- Repositorios públicos accesibles sin autenticación +- API Git (clone, pull, push) funciona sin SSO + +#### Configurar OAuth con Authentik + +1. En Authentik, crea una aplicación para Gitea: + - Tipo: **OAuth2/OpenID Provider** + - Client type: **Confidential** + - Redirect URIs: `https://git.tudominio.com/user/oauth2/authentik/callback` + +2. En Gitea, ve a **Site Administration** → **Authentication Sources** → **Add Authentication Source** +3. Tipo: **OAuth2** +4. Configura: + - Provider: **OpenID Connect** + - Client ID: (de Authentik) + - Client Secret: (de Authentik) + - OpenID Connect Auto Discovery URL: `https://auth.tudominio.com/application/o/gitea/.well-known/openid-configuration` + +5. Actualiza las variables en `stack.env`: + ```env + GITEA_ENABLE_OPENID_SIGNIN=true + GITEA_ENABLE_OPENID_SIGNUP=true + GITEA_DISABLE_LOGIN_FORM=false # Mantén false para permitir login local también + ``` + +## 🔧 Configuración Avanzada + +### Personalización de la UI + +Las siguientes opciones están preconfiguradas: + +- **Tema por defecto**: Oscuro (`gitea-dark`) +- **Registro deshabilitado**: Solo administradores pueden crear usuarios (o usar SSO) +- **Visibilidad por defecto**: Privada +- **Requiere login para ver**: Activado + +Para cambiar estas opciones, edita `stack.env` y actualiza el stack. + +### Limitar Acceso por Organización + +```env +GITEA_DEFAULT_ALLOW_CREATE_ORGANIZATION=false +GITEA_DEFAULT_ORG_VISIBILITY=private +``` + +### Notificaciones por Email + +Añade al archivo `stack.env`: + +```env +GITEA__mailer__ENABLED=true +GITEA__mailer__FROM=gitea@tudominio.com +GITEA__mailer__PROTOCOL=smtp +GITEA__mailer__SMTP_ADDR=smtp.tudominio.com +GITEA__mailer__SMTP_PORT=587 +GITEA__mailer__USER=gitea@tudominio.com +GITEA__mailer__PASSWD=tu-password-smtp +``` + +### Configurar Webhooks + +Gitea soporta webhooks para integración con otros servicios: + +1. Ve a tu repositorio → **Settings** → **Webhooks** +2. Añade un webhook con la URL de destino +3. Selecciona los eventos que quieres recibir + +### Ejemplo de Workflow con Gitea Actions + +Crea `.gitea/workflows/build.yml` en tu repositorio: + +```yaml +name: Build and Test +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Build + run: npm run build + + - name: Test + run: npm test +``` + +## 🛠️ Troubleshooting + +### No puedo hacer push/pull por SSH + +1. Verifica que el puerto SSH está abierto: + ```bash + telnet git.tudominio.com 222 + ``` + +2. Verifica tu clave SSH: + ```bash + ssh -T git@git.tudominio.com -p 222 + ``` + +3. Añade tu clave SSH en Gitea: + - Ve a **Settings** → **SSH / GPG Keys** → **Add Key** + +### El runner de Actions no se registra + +1. Verifica los logs: + ```bash + docker logs gitea-act-runner + ``` + +2. Verifica que el token es correcto en `stack.env` + +3. Regenera el token en Gitea si es necesario + +4. Asegúrate de que el runner puede comunicarse con Gitea: + ```bash + docker exec gitea-act-runner ping gitea + ``` + +### Error de permisos con volúmenes + +Si usas SELinux, los volúmenes ya tienen `:Z`: + +```bash +# Si persisten problemas +sudo chcon -Rt svirt_sandbox_file_t /opt/gitea/data +sudo chcon -Rt svirt_sandbox_file_t /opt/gitea/postgres +``` + +### OAuth con Authentik no funciona + +1. Verifica que la Redirect URI en Authentik es exacta +2. Comprueba que el Discovery URL es accesible desde el contenedor: + ```bash + docker exec gitea curl https://auth.tudominio.com/application/o/gitea/.well-known/openid-configuration + ``` +3. Revisa los logs de Gitea: `docker logs gitea` + +### La base de datos no inicia + +1. Verifica los logs de PostgreSQL: + ```bash + docker logs gitea-postgres + ``` + +2. Verifica los permisos del directorio de datos: + ```bash + ls -lh /opt/gitea/postgres + ``` + +3. Si necesitas reiniciar desde cero: + ```bash + docker compose down + sudo rm -rf /opt/gitea/postgres/* + docker compose up -d + ``` + +## 📚 Recursos Adicionales + +- [Documentación oficial de Gitea](https://docs.gitea.io/) +- [Gitea Actions](https://docs.gitea.io/en-us/usage/actions/overview/) +- [Act Runner](https://gitea.com/gitea/act_runner) +- [Migrar desde GitHub/GitLab](https://docs.gitea.io/en-us/usage/migrations/) + +## 🔒 Seguridad + +- **SSH**: Usa claves SSH en lugar de passwords para Git +- **2FA**: Habilita autenticación de dos factores en tu cuenta +- **Tokens**: Usa tokens de acceso con permisos limitados para CI/CD +- **Webhooks**: Verifica siempre las firmas de webhooks +- **Backups**: Realiza backups regulares de la base de datos y repositorios + +## 💾 Backups + +### Backup de la Base de Datos + +```bash +# Backup completo +docker exec gitea-postgres pg_dump -U gitea gitea > gitea_backup_$(date +%Y%m%d).sql + +# Restaurar +cat gitea_backup_YYYYMMDD.sql | docker exec -i gitea-postgres psql -U gitea gitea +``` + +### Backup de Repositorios y Datos + +```bash +# Backup completo de datos +sudo tar -czf gitea-data-backup-$(date +%Y%m%d).tar.gz /opt/gitea/data + +# Restaurar +sudo tar -xzf gitea-data-backup-YYYYMMDD.tar.gz -C / +``` + +### Backup Automático + +Considera usar el comando nativo de Gitea: + +```bash +docker exec -u git gitea gitea dump -c /data/gitea/conf/app.ini +``` + +Esto crea un archivo `gitea-dump-*.zip` con todo lo necesario para restaurar. + +## 🔄 Actualizaciones + +1. **Backup primero**: Siempre haz backup antes de actualizar +2. Actualiza la versión en `stack.env`: + ```env + GITEA_IMAGE=gitea/gitea:1.21.0 + ``` +3. Actualiza el stack en Portainer +4. Verifica los logs: `docker logs gitea` +5. Prueba que todo funciona correctamente + +## 📊 Monitoreo + +### Ver Estadísticas + +- Accede a **Site Administration** → **Dashboard** +- Revisa usuarios, repositorios, organizaciones, etc. + +### Logs + +```bash +# Logs de Gitea +docker logs -f gitea + +# Logs de PostgreSQL +docker logs -f gitea-postgres + +# Logs del Runner +docker logs -f gitea-act-runner +``` + +### Métricas + +Gitea soporta exportación de métricas para Prometheus: + +1. Habilita métricas en `stack.env`: + ```env + GITEA__metrics__ENABLED=true + GITEA__metrics__TOKEN=tu-token-secreto + ``` + +2. Las métricas estarán disponibles en: `https://git.tudominio.com/metrics?token=tu-token-secreto` diff --git a/n8n/README.md b/n8n/README.md new file mode 100644 index 0000000..8740c06 --- /dev/null +++ b/n8n/README.md @@ -0,0 +1,370 @@ +# n8n - Plataforma de Automatización + +n8n es una plataforma de automatización de código abierto que permite conectar diferentes servicios y crear flujos de trabajo (workflows). + +## 📋 Descripción + +Este stack despliega n8n con: +- Base de datos PostgreSQL para persistencia +- Integración con Traefik para acceso HTTPS +- Webhooks públicos sin autenticación +- UI protegida con Authentik (SSO) +- Cifrado de credenciales + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registro DNS**: Configura el registro A para tu dominio n8n +3. **Clave de cifrado**: Genera una clave segura para cifrar credenciales + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `n8n` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `n8n/docker-compose.yml` +5. Carga el archivo de variables de entorno: `n8n/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno Importantes + +Edita el archivo `stack.env`: + +```env +# Base de datos PostgreSQL +POSTGRES_PASSWORD=tu-password-seguro-aleatorio +N8N_DB_PASSWORD=tu-password-seguro-aleatorio + +# Dominio y URLs +N8N_DOMAIN=n8n.tudominio.com +N8N_HOST=n8n.tudominio.com +N8N_WEBHOOK_URL=https://n8n.tudominio.com/ + +# Cifrado de credenciales (IMPORTANTE: genera una clave única y guárdala) +N8N_ENCRYPTION_KEY=tu-clave-de-cifrado-aleatoria-muy-larga + +# Zona horaria +N8N_TIMEZONE=Europe/Madrid +``` + +> **⚠️ CRÍTICO**: La `N8N_ENCRYPTION_KEY` es **fundamental**. Si la pierdes, perderás acceso a todas las credenciales guardadas. Haz backup de esta clave. + +### Generar Clave de Cifrado + +```bash +openssl rand -hex 32 +``` + +## ⚙️ Configuración Post-Instalación + +### 1. Primer Acceso + +1. Accede a `https://n8n.tudominio.com` +2. Si Authentik está configurado, serás redirigido al login de SSO +3. Completa la configuración inicial de n8n: + - Email del propietario + - Nombre de la instancia (opcional) + - Preferencias de uso + +### 2. Crear tu Primer Workflow + +1. Haz clic en **Create new workflow** +2. Añade un nodo trigger (ej: **Webhook**, **Schedule**, **Manual**) +3. Añade nodos de acción (ej: **HTTP Request**, **Gmail**, **Slack**) +4. Conecta los nodos +5. Haz clic en **Execute workflow** para probar +6. Activa el workflow + +### 3. Configurar Credenciales + +Para servicios externos (Gmail, Slack, etc.): + +1. Haz clic en un nodo que requiera credenciales +2. Haz clic en **Create New Credential** +3. Completa los datos de autenticación +4. Las credenciales se cifran automáticamente con `N8N_ENCRYPTION_KEY` + +## 🔧 Uso de Webhooks + +### Webhooks Públicos + +Los webhooks NO están protegidos por Authentik, permitiendo que servicios externos los activen: + +- URL de producción: `https://n8n.tudominio.com/webhook/tu-id-webhook` +- URL de test: `https://n8n.tudominio.com/webhook-test/tu-id-webhook` + +### Ejemplo de Webhook + +1. Crea un workflow con un nodo **Webhook** +2. Configura: + - **HTTP Method**: `POST` (o el que necesites) + - **Path**: `mi-webhook` (se generará automáticamente) +3. Activa el workflow +4. Copia la URL del webhook +5. Pruébalo: + ```bash + curl -X POST https://n8n.tudominio.com/webhook/mi-webhook \ + -H "Content-Type: application/json" \ + -d '{"mensaje": "Hola desde webhook"}' + ``` + +### Webhook con Autenticación + +Para proteger webhooks, añade autenticación en el propio workflow: + +1. Añade un nodo **IF** después del webhook +2. Verifica un token o firma en los headers: + ```javascript + {{ $node["Webhook"].json.headers.authorization }} === "Bearer mi-token-secreto" + ``` + +## 🔧 Configuración Avanzada + +### Variables de Entorno + +n8n soporta muchas variables de entorno. Algunas útiles: + +```env +# Ejecución +N8N_DEFAULT_BINARY_DATA_MODE=filesystem +EXECUTIONS_DATA_SAVE_ON_ERROR=all +EXECUTIONS_DATA_SAVE_ON_SUCCESS=all +EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true + +# Timeout +EXECUTIONS_TIMEOUT=300 +EXECUTIONS_TIMEOUT_MAX=3600 + +# Comunidad +N8N_TEMPLATES_ENABLED=true +N8N_TEMPLATES_HOST=https://api.n8n.io/api/ + +# Logs +N8N_LOG_LEVEL=info +N8N_LOG_OUTPUT=console +``` + +### Integración con Servicios Externos + +#### Gmail +1. Crea credenciales OAuth2 en Google Cloud Console +2. En n8n, añade credencial de tipo **Gmail OAuth2** +3. Completa Client ID y Client Secret +4. Autoriza la aplicación + +#### Slack +1. Crea una Slack App en api.slack.com +2. Añade permisos necesarios (chat:write, etc.) +3. En n8n, añade credencial de tipo **Slack OAuth2** +4. Autoriza la aplicación + +#### Webhooks de GitHub +1. En tu repositorio de GitHub, ve a **Settings** → **Webhooks** +2. Añade webhook URL: `https://n8n.tudominio.com/webhook/github` +3. Selecciona eventos (push, pull request, etc.) +4. En n8n, procesa los eventos con nodos **IF** y **Switch** + +### Programar Ejecuciones + +Usa el nodo **Schedule Trigger**: + +``` +# Cada hora +0 * * * * + +# Cada día a las 9:00 +0 9 * * * + +# Cada lunes a las 8:30 +30 8 * * 1 + +# Cada 5 minutos +*/5 * * * * +``` + +## 🛠️ Troubleshooting + +### No puedo acceder a n8n + +1. Verifica que el DNS apunta correctamente: + ```bash + nslookup n8n.tudominio.com + ``` + +2. Verifica los logs: + ```bash + docker logs n8n + ``` + +3. Verifica Traefik: + ```bash + docker logs traefik | grep n8n + ``` + +### Los webhooks no funcionan + +1. Verifica que la URL del webhook es correcta +2. Asegúrate de que el workflow está **activado** +3. Revisa los logs de ejecución en n8n +4. Verifica que la configuración de Traefik permite webhooks sin autenticación +5. Prueba con curl: + ```bash + curl -v https://n8n.tudominio.com/webhook/test + ``` + +### Error al guardar credenciales + +1. Verifica que `N8N_ENCRYPTION_KEY` está configurada +2. No cambies nunca esta clave después del primer uso +3. Revisa los logs: `docker logs n8n` + +### La base de datos no conecta + +1. Verifica que PostgreSQL está corriendo: + ```bash + docker ps | grep n8n-pg + ``` + +2. Verifica los logs de PostgreSQL: + ```bash + docker logs n8n-pg + ``` + +3. Verifica las credenciales en `stack.env` + +### Workflows se ejecutan lentamente + +1. Aumenta los recursos del contenedor +2. Verifica el timeout en variables de entorno +3. Optimiza el workflow (divide en workflows más pequeños) +4. Revisa los logs de ejecución + +### Error "Execution timed out" + +Aumenta el timeout en `stack.env`: + +```env +EXECUTIONS_TIMEOUT=600 +EXECUTIONS_TIMEOUT_MAX=7200 +``` + +## 📚 Recursos Adicionales + +- [Documentación oficial de n8n](https://docs.n8n.io/) +- [Workflows de ejemplo](https://n8n.io/workflows/) +- [Integrations](https://n8n.io/integrations/) +- [Forum de la comunidad](https://community.n8n.io/) + +## 🎯 Casos de Uso + +### Automatización de GitHub +- Notificar en Slack cuando hay un nuevo PR +- Ejecutar tests automáticos +- Crear issues desde emails + +### Backup Automático +- Backup de bases de datos a Google Drive +- Notificaciones de éxito/error +- Programar backups diarios + +### Monitoreo +- Verificar disponibilidad de sitios web +- Alertas por email/Slack si un servicio está caído +- Recopilar métricas y enviar a InfluxDB + +### Integración con CRM +- Sincronizar contactos entre sistemas +- Automatizar seguimiento de leads +- Generar reportes automáticos + +### Procesamiento de Datos +- Extraer datos de APIs +- Transformar y limpiar datos +- Cargar en bases de datos + +## 🔒 Seguridad + +- **Credenciales**: Todas las credenciales se cifran con `N8N_ENCRYPTION_KEY` +- **Webhooks**: Implementa autenticación personalizada en webhooks sensibles +- **UI**: Protegida con Authentik (SSO) +- **Backups**: Haz backup de la clave de cifrado y la base de datos +- **Variables**: No expongas secrets en los workflows; usa credenciales + +## 💾 Backups + +### Backup de la Base de Datos + +```bash +# Backup +docker exec n8n-pg pg_dump -U n8n n8n > n8n_backup_$(date +%Y%m%d).sql + +# Restaurar +cat n8n_backup_YYYYMMDD.sql | docker exec -i n8n-pg psql -U n8n n8n +``` + +### Backup de la Clave de Cifrado + +Guarda `N8N_ENCRYPTION_KEY` en un lugar seguro: + +```bash +# Extraer del stack.env +grep N8N_ENCRYPTION_KEY stack.env > encryption_key_backup.txt + +# Guardar en un gestor de contraseñas o vault +``` + +### Backup de Workflows + +n8n guarda workflows en la base de datos, por lo que el backup de PostgreSQL incluye los workflows. + +También puedes exportar workflows manualmente: +1. En n8n, abre un workflow +2. Haz clic en los 3 puntos → **Download** +3. Guarda el archivo JSON + +## 🔄 Actualizaciones + +1. Haz **backup** de la base de datos y la clave de cifrado +2. Actualiza en `stack.env`: + ```env + N8N_IMAGE=n8nio/n8n:latest + ``` +3. Actualiza el stack en Portainer +4. Verifica los logs: `docker logs n8n` +5. Prueba algunos workflows críticos + +> **Nota**: n8n se actualiza frecuentemente. Revisa las [release notes](https://github.com/n8n-io/n8n/releases) antes de actualizar. + +## 📊 Monitoreo + +### Ver Ejecuciones + +En n8n: +1. Ve a **Executions** +2. Filtra por estado (éxito, error, corriendo) +3. Revisa logs detallados de cada ejecución + +### Logs del Contenedor + +```bash +# Logs en tiempo real +docker logs -f n8n + +# Últimas 100 líneas +docker logs --tail 100 n8n + +# Logs con timestamps +docker logs -t n8n +``` + +### Métricas + +n8n no tiene métricas Prometheus por defecto, pero puedes: +1. Crear un workflow que publique métricas +2. Usar el nodo HTTP Request para enviar a un collector +3. Monitorear logs con herramientas como Loki/Grafana diff --git a/ruleta/README.md b/ruleta/README.md new file mode 100644 index 0000000..9424271 --- /dev/null +++ b/ruleta/README.md @@ -0,0 +1,438 @@ +# Ruleta - Aplicación Next.js + +Aplicación web personalizada construida con Next.js. + +## 📋 Descripción + +Este stack despliega una aplicación Next.js con: +- Dos rutas de acceso: subdominio y path +- Integración con Traefik para HTTPS +- Soporte para múltiples dominios +- Configuración opcional de Authentik (SSO) + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registros DNS**: Configura los registros A para tus dominios +3. **Imagen Docker**: La aplicación debe estar construida como imagen Docker + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `ruleta` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `ruleta/docker-compose.yml` +5. Carga el archivo de variables de entorno: `ruleta/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno + +Edita el archivo `stack.env`: + +```env +# Imagen de la aplicación (construida previamente) +RULETA_IMAGE=tu-usuario/ruleta:latest + +# Entorno de Node.js +RULETA_NODE_ENV=production +RULETA_NEXT_TELEMETRY_DISABLED=1 + +# Puerto interno de Next.js +RULETA_APP_PORT=3000 + +# Dominios +# Opción 1: Subdominio dedicado +RULETA_SUBDOMAIN=ruleta.tudominio.com + +# Opción 2: Path en dominio principal +RULETA_MAIN_DOMAIN=tudominio.com + +# Traefik +TRAEFIK_DOCKER_NETWORK=proxy +TRAEFIK_ENTRYPOINT_SECURE=websecure +TRAEFIK_CERTRESOLVER=letsencrypt + +# Si usas Supabase, descomenta y configura: +# NEXT_PUBLIC_SUPABASE_URL=https://tu-proyecto.supabase.co +# NEXT_PUBLIC_SUPABASE_ANON_KEY=tu-clave-publica +# SUPABASE_SERVICE_ROLE_KEY=tu-clave-privada +``` + +## ⚙️ Rutas de Acceso + +Esta aplicación tiene dos formas de acceso configuradas: + +### 1. Subdominio Dedicado + +Accede mediante: `https://ruleta.tudominio.com` + +- URL completa del subdominio +- Next.js recibe las peticiones en el path raíz `/` +- No requiere configuración especial en Next.js + +### 2. Path en Dominio Principal + +Accede mediante: `https://tudominio.com/ruleta` + +- Path dentro del dominio principal +- Traefik elimina el prefijo `/ruleta` antes de enviar a Next.js +- Next.js recibe las peticiones como si estuvieran en `/` + +> **Nota**: Puedes usar ambas rutas simultáneamente o deshabilitar una editando el `docker-compose.yml`. + +## 🔧 Configuración de Next.js + +### Configurar basePath (si usas path) + +Si quieres que Next.js sea consciente del path `/ruleta`, edita `next.config.js`: + +```javascript +/** @type {import('next').NextConfig} */ +const nextConfig = { + basePath: '/ruleta', + assetPrefix: '/ruleta', + // ... otras opciones +} + +module.exports = nextConfig +``` + +> **Nota**: Con la configuración actual (middleware de stripprefix en Traefik), esto NO es necesario. Traefik se encarga de eliminar el prefijo. + +### Variables de Entorno en Next.js + +Para exponer variables al cliente (navegador): + +```javascript +// next.config.js +module.exports = { + env: { + CUSTOM_VAR: process.env.CUSTOM_VAR, + }, + // o usa NEXT_PUBLIC_ prefix +} +``` + +En `stack.env`: +```env +NEXT_PUBLIC_API_URL=https://api.tudominio.com +CUSTOM_VAR=valor-personalizado +``` + +## 🔒 Proteger con Authentik (Opcional) + +Por defecto, la aplicación NO está protegida con SSO. Para protegerla: + +### Opción 1: Proteger Todo + +Edita el `docker-compose.yml` y descomenta: + +```yaml +labels: + # Para subdominio + traefik.http.routers.ruleta-sub.middlewares: "authentik@docker" + + # Para path (requiere cadena de middlewares) + traefik.http.routers.ruleta-path.middlewares: "authentik@docker,ruleta-strip@docker" +``` + +### Opción 2: Proteger Solo Ciertas Rutas + +Crea routers adicionales en Traefik: + +```yaml +# Router para rutas públicas +traefik.http.routers.ruleta-public.rule: "Host(`ruleta.tudominio.com`) && PathPrefix(`/api`, `/public`)" +traefik.http.routers.ruleta-public.priority: "20" + +# Router para rutas protegidas +traefik.http.routers.ruleta-private.rule: "Host(`ruleta.tudominio.com`) && PathPrefix(`/admin`)" +traefik.http.routers.ruleta-private.middlewares: "authentik@docker" +traefik.http.routers.ruleta-private.priority: "30" +``` + +## 🏗️ Construir la Imagen Docker + +### Dockerfile de Ejemplo + +```dockerfile +# Build stage +FROM node:20-alpine AS builder + +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# Production stage +FROM node:20-alpine AS runner + +WORKDIR /app +ENV NODE_ENV=production + +# Copiar archivos necesarios +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static + +EXPOSE 3000 +CMD ["node", "server.js"] +``` + +### next.config.js para Standalone + +```javascript +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'standalone', + // ... otras opciones +} + +module.exports = nextConfig +``` + +### Construir y Publicar + +```bash +# Construir +docker build -t tu-usuario/ruleta:latest . + +# Probar localmente +docker run -p 3000:3000 tu-usuario/ruleta:latest + +# Publicar en Docker Hub +docker push tu-usuario/ruleta:latest + +# O publicar en GitHub Container Registry +docker tag tu-usuario/ruleta:latest ghcr.io/tu-usuario/ruleta:latest +docker push ghcr.io/tu-usuario/ruleta:latest +``` + +## 🔧 Configuración Avanzada + +### Integración con Supabase + +Si tu aplicación usa Supabase: + +1. Crea un proyecto en [supabase.com](https://supabase.com) +2. Obtén las credenciales: + - **URL del proyecto**: Settings → API → Project URL + - **Anon key**: Settings → API → anon public + - **Service role key**: Settings → API → service_role (secreto) + +3. Añade a `stack.env`: + ```env + NEXT_PUBLIC_SUPABASE_URL=https://tu-proyecto.supabase.co + NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbG... + SUPABASE_SERVICE_ROLE_KEY=eyJhbG... + ``` + +4. En tu código Next.js: + ```javascript + import { createClient } from '@supabase/supabase-js' + + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY + ) + ``` + +### Variables de Entorno Sensibles + +Para secrets (API keys, tokens): + +1. No las incluyas en `stack.env` si el repositorio es público +2. Configúralas manualmente en Portainer: + - Edita el stack + - Ve a la pestaña **Environment variables** + - Añade variables adicionales + +3. O usa Docker secrets: + ```yaml + services: + app: + secrets: + - api_key + + secrets: + api_key: + external: true + ``` + +### Volúmenes para Datos Persistentes + +Si necesitas persistir datos (uploads, cache): + +```yaml +services: + app: + volumes: + - ${RULETA_DATA_PATH}:/app/data:Z + - ${RULETA_UPLOADS_PATH}:/app/public/uploads:Z +``` + +Añade a `stack.env`: +```env +RULETA_DATA_PATH=/opt/ruleta/data +RULETA_UPLOADS_PATH=/opt/ruleta/uploads +``` + +## 🛠️ Troubleshooting + +### La aplicación no inicia + +1. Verifica los logs: + ```bash + docker logs ruleta-app + ``` + +2. Verifica que la imagen existe: + ```bash + docker images | grep ruleta + ``` + +3. Verifica variables de entorno: + ```bash + docker inspect ruleta-app | grep -A 20 Env + ``` + +### No puedo acceder por dominio + +1. Verifica DNS: + ```bash + nslookup ruleta.tudominio.com + ``` + +2. Verifica Traefik: + ```bash + docker logs traefik | grep ruleta + ``` + +3. Verifica labels de Traefik: + ```bash + docker inspect ruleta-app | grep -A 30 Labels + ``` + +### Error 502 Bad Gateway + +1. Verifica que el puerto interno es correcto: + - Next.js por defecto usa puerto 3000 + - Verifica `RULETA_APP_PORT=3000` + +2. Verifica que la aplicación está escuchando: + ```bash + docker exec ruleta-app netstat -tulpn + ``` + +3. Verifica conectividad desde Traefik: + ```bash + docker exec traefik ping ruleta-app + ``` + +### Las rutas no funcionan con basePath + +Si configuraste `basePath` en Next.js: + +1. **Opción A**: Elimina el middleware `stripprefix` de Traefik +2. **Opción B**: Elimina `basePath` de Next.js (Traefik se encarga) + +### Recursos estáticos (CSS/JS) no cargan + +Verifica: +1. El `assetPrefix` en `next.config.js` (debe coincidir con basePath) +2. Los logs del navegador (F12 → Console) +3. Las rutas en el inspector de red (F12 → Network) + +### Variables de entorno no disponibles + +Recuerda: +- Solo variables con prefijo `NEXT_PUBLIC_` están disponibles en el navegador +- Variables sin prefijo solo están disponibles en el servidor (API routes, getServerSideProps) + +## 📚 Recursos Adicionales + +- [Documentación de Next.js](https://nextjs.org/docs) +- [Deploying Next.js](https://nextjs.org/docs/deployment) +- [Next.js con Docker](https://github.com/vercel/next.js/tree/canary/examples/with-docker) +- [Traefik con Next.js](https://doc.traefik.io/traefik/routing/routers/) + +## 🔄 Actualizaciones + +### Actualizar la Aplicación + +1. Construye una nueva versión de la imagen: + ```bash + docker build -t tu-usuario/ruleta:v2.0 . + docker push tu-usuario/ruleta:v2.0 + ``` + +2. Actualiza en `stack.env`: + ```env + RULETA_IMAGE=tu-usuario/ruleta:v2.0 + ``` + +3. Actualiza el stack en Portainer + +### Rolling Updates + +Para actualizaciones sin downtime, usa múltiples réplicas (requiere Docker Swarm o Kubernetes). + +### Rollback + +Si algo sale mal: + +1. Vuelve a la versión anterior en `stack.env` +2. Actualiza el stack en Portainer + +## 📊 Monitoreo + +### Logs de la Aplicación + +```bash +# Logs en tiempo real +docker logs -f ruleta-app + +# Últimas 100 líneas +docker logs --tail 100 ruleta-app + +# Logs con timestamps +docker logs -t ruleta-app +``` + +### Logs de Next.js + +Next.js registra en stdout/stderr, accesibles con `docker logs`. + +Para logs estructurados, considera usar: +- [Pino](https://github.com/pinojs/pino) +- [Winston](https://github.com/winstonjs/winston) + +### Métricas + +Para monitorear la aplicación: +1. Implementa un endpoint `/api/health` +2. Usa herramientas como Prometheus + Grafana +3. O servicios de APM como New Relic, Datadog + +## 🎯 Casos de Uso + +Este stack es ideal para: +- Aplicaciones Next.js personalizadas +- Landing pages +- Dashboards administrativos +- Aplicaciones full-stack con API routes +- JAMstack con SSR/SSG + +## 💡 Tips + +- Usa `output: 'standalone'` en Next.js para imágenes Docker más pequeñas +- Implementa caching con Redis para mejor rendimiento +- Usa ISR (Incremental Static Regeneration) para contenido dinámico +- Implementa rate limiting en API routes +- Usa CDN para assets estáticos (imágenes, CSS, JS) diff --git a/trilium/README.md b/trilium/README.md new file mode 100644 index 0000000..e64ab1e --- /dev/null +++ b/trilium/README.md @@ -0,0 +1,382 @@ +# Trilium Notes - Aplicación de Notas Jerárquicas + +Trilium Notes es una aplicación de toma de notas jerárquicas con editor WYSIWYG, soporte para scripts, y cifrado de notas. + +## 📋 Descripción + +Este stack despliega Trilium con: +- Almacenamiento persistente de notas +- Acceso mediante HTTPS con Traefik +- Sincronización entre dispositivos +- Sin protección SSO (Trilium tiene su propio sistema de autenticación) +- Headers de seguridad configurados + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registro DNS**: Configura los registros A para tus dominios Trilium + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `trilium` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `trilium/docker-compose.yml` +5. Carga el archivo de variables de entorno: `trilium/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno + +Edita el archivo `stack.env`: + +```env +# Imagen +TRILIUM_IMAGE=zadam/trilium:latest + +# Hostname (para identificación interna) +TRILIUM_HOSTNAME=trilium-server + +# Puerto HTTP interno +TRILIUM_HTTP_PORT=8080 + +# Dominios (puedes tener múltiples dominios apuntando a la misma instancia) +TRILIUM_DOMAIN_1=notes.tudominio.com +TRILIUM_DOMAIN_2=trilium.tudominio.com + +# Ruta de datos +TRILIUM_DATA_PATH=/opt/trilium/data + +# Zona horaria +TZ=Europe/Madrid + +# Traefik +TRAEFIK_DOCKER_NETWORK=proxy +TRAEFIK_ENTRYPOINT_SECURE=websecure +TRAEFIK_CERTRESOLVER=letsencrypt +``` + +## ⚙️ Configuración Post-Instalación + +### 1. Primer Acceso + +1. Accede a `https://notes.tudominio.com` +2. En el primer acceso, Trilium te pedirá crear una contraseña +3. **Guarda bien esta contraseña**: Es la contraseña maestra que protege todas tus notas + +### 2. Configuración Inicial + +Trilium te guiará por un tutorial interactivo. Explora: +- **Crear notas**: Haz clic en el botón + o usa `Ctrl+P` +- **Jerarquía**: Organiza notas en árbol jerárquico +- **Atributos**: Añade etiquetas (#tag) y relaciones +- **Scripts**: Automatiza tareas con JavaScript + +### 3. Cifrado de Notas + +Para cifrar notas sensibles: + +1. Haz clic derecho en una nota → **Note info** +2. Añade el atributo `#encrypted` +3. Trilium te pedirá una contraseña de cifrado +4. La nota se cifrará localmente + +### 4. Sincronización entre Dispositivos + +Trilium soporta sincronización servidor-cliente: + +#### Configurar Servidor (ya está hecho) + +Tu instancia de Trilium ya funciona como servidor. + +#### Configurar Cliente Desktop + +1. Descarga Trilium Desktop desde [GitHub](https://github.com/zadam/trilium/releases) +2. Instálalo en tu PC/Mac/Linux +3. En el primer inicio, selecciona **Sync from server** +4. Configura: + - **Server URL**: `https://notes.tudominio.com` + - **Username**: Crea un usuario de sincronización en el servidor + - **Password**: Password del usuario + +#### Crear Usuario de Sincronización + +1. En el servidor web, ve a **Options** → **Sync** +2. Haz clic en **Create sync user** +3. Usuario: `mi-desktop` +4. Password: (genera uno seguro) +5. Copia las credenciales para usarlas en el cliente + +## 🔧 Características Principales + +### Notas Jerárquicas + +- Organiza notas en árbol (padres e hijos) +- Múltiples padres por nota (clones) +- Drag & drop para reorganizar + +### Tipos de Notas + +- **Text**: Notas de texto con editor WYSIWYG +- **Code**: Notas de código con syntax highlighting +- **Render**: Notas que ejecutan HTML/JavaScript +- **Book**: Agrupaciones de notas +- **Relation map**: Mapas de relaciones entre notas +- **Canvas**: Notas de dibujo libre + +### Atributos y Relaciones + +``` +#etiqueta - Etiqueta simple +#etiqueta=valor - Etiqueta con valor +~relacion=@notaId - Relación a otra nota +#cssClass=mi-clase - Clase CSS personalizada +#hideChildrenOverview - Oculta hijos en overview +``` + +### Scripts + +Trilium permite automatización con JavaScript: + +1. Crea una nota de tipo **Code** (JavaScript) +2. Añade el atributo `#run=frontendStartup` o `#run=backendStartup` +3. El script se ejecutará automáticamente + +Ejemplo - Script de búsqueda personalizada: +```javascript +api.addButtonToToolbar({ + title: 'Buscar TODO', + icon: 'check', + action: () => { + const notes = api.searchForNotes('#todo !#done'); + api.showMessage(`Encontradas ${notes.length} tareas pendientes`); + } +}); +``` + +### Plantillas + +Crea plantillas para notas recurrentes: + +1. Crea una nota con la estructura deseada +2. Añade `#template` +3. Usa la plantilla: Clic derecho en padre → **Create note from template** + +### Web Clipper + +Captura contenido web directamente a Trilium: + +1. Ve a **Options** → **Web clipper** +2. Sigue las instrucciones para instalar la extensión del navegador +3. Captura páginas web con un clic + +## 🔧 Configuración Avanzada + +### Backup Automático + +Trilium hace backups automáticos diarios en `/opt/trilium/data/backup/`. + +Para configurar backups externos: + +```bash +# Script de backup +#!/bin/bash +BACKUP_DIR=/backups/trilium +DATE=$(date +%Y%m%d_%H%M%S) + +# Backup de toda la data +tar -czf $BACKUP_DIR/trilium-$DATE.tar.gz /opt/trilium/data/ + +# Mantener solo últimos 30 días +find $BACKUP_DIR -name "trilium-*.tar.gz" -mtime +30 -delete +``` + +### API + +Trilium tiene una API ETAPI para integración: + +1. Ve a **Options** → **ETAPI** +2. Crea un token de API +3. Úsalo en tus scripts: + +```bash +# Obtener nota +curl -H "Authorization: YOUR_ETAPI_TOKEN" \ + https://notes.tudominio.com/etapi/notes/noteId + +# Crear nota +curl -X POST https://notes.tudominio.com/etapi/notes \ + -H "Authorization: YOUR_ETAPI_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"noteId":"new-note","title":"Mi Nota","content":"Contenido"}' +``` + +### Temas y Estilos + +Personaliza la apariencia: + +1. Crea una nota de tipo **Code** (CSS) +2. Añade `#appTheme` +3. Escribe tu CSS personalizado: + +```css +/* Tema oscuro personalizado */ +body { + --main-background-color: #1e1e1e; + --main-text-color: #d4d4d4; +} +``` + +### Shortcuts Personalizados + +1. Ve a **Options** → **Keyboard shortcuts** +2. Personaliza o añade nuevos shortcuts + +## 🛠️ Troubleshooting + +### No puedo acceder a Trilium + +1. Verifica que está corriendo: + ```bash + docker ps | grep trilium + ``` + +2. Verifica los logs: + ```bash + docker logs trilium + ``` + +3. Verifica DNS: + ```bash + nslookup notes.tudominio.com + ``` + +### Olvidé la contraseña maestra + +Si perdiste la contraseña maestra, NO HAY forma de recuperarla. Las notas están cifradas localmente. + +**Prevención**: +- Guarda la contraseña en un gestor de contraseñas +- Haz backups regulares de `/opt/trilium/data/` +- Considera no usar cifrado para todas las notas + +### Sincronización no funciona + +1. Verifica las credenciales del usuario de sync +2. Revisa los logs del servidor: + ```bash + docker logs trilium | grep sync + ``` +3. En el cliente, ve a **Options** → **Sync** → **Check for updates** +4. Fuerza sincronización: **Options** → **Sync** → **Force full sync** + +### Notas no se guardan + +1. Verifica espacio en disco: + ```bash + df -h /opt/trilium/ + ``` + +2. Verifica permisos: + ```bash + ls -lh /opt/trilium/data/ + ``` + +3. Revisa los logs para errores + +### Performance lento + +1. Verifica el tamaño de la base de datos: + ```bash + du -sh /opt/trilium/data/document.db + ``` + +2. Considera optimizar la base de datos: + - Ve a **Options** → **Advanced** → **Anonymize database** + - Esto elimina historial antiguo + +3. Aumenta recursos del contenedor si es necesario + +## 📚 Recursos Adicionales + +- [Documentación oficial de Trilium](https://github.com/zadam/trilium/wiki) +- [Galería de plantillas](https://github.com/zadam/trilium/wiki/Gallery) +- [Scripts de ejemplo](https://github.com/zadam/trilium/wiki/Scripts) +- [Forum de la comunidad](https://github.com/zadam/trilium/discussions) + +## 🔒 Seguridad + +- **Contraseña maestra**: Protege todas tus notas +- **Cifrado opcional**: Usa `#encrypted` para notas sensibles +- **HTTPS**: Todo el tráfico está cifrado con SSL +- **Backups**: Haz backups regulares de tus notas +- **Sin SSO**: Trilium gestiona su propia autenticación (más seguro para notas personales) + +## 💾 Backups + +### Backup Manual + +```bash +# Backup completo +sudo tar -czf trilium-backup-$(date +%Y%m%d).tar.gz /opt/trilium/data/ + +# Solo base de datos +sudo cp /opt/trilium/data/document.db trilium-db-backup-$(date +%Y%m%d).db +``` + +### Restaurar + +```bash +# Detener Trilium +docker stop trilium + +# Restaurar backup +sudo tar -xzf trilium-backup-YYYYMMDD.tar.gz -C / + +# Reiniciar +docker start trilium +``` + +### Backup Automático (dentro de Trilium) + +Trilium hace backups automáticos: +- **Ubicación**: `/opt/trilium/data/backup/` +- **Frecuencia**: Diaria +- **Retención**: Configurable en **Options** → **Other** + +## 🔄 Actualizaciones + +1. Haz **backup completo** antes de actualizar +2. Actualiza en `stack.env`: + ```env + TRILIUM_IMAGE=zadam/trilium:0.63.7 + ``` +3. Actualiza el stack en Portainer +4. Verifica los logs: `docker logs trilium` +5. Accede y verifica que todo funciona + +> **Nota**: Revisa el [changelog](https://github.com/zadam/trilium/blob/master/CHANGELOG.md) antes de actualizar. + +## 📊 Uso + +### Casos de Uso + +- **Notas personales**: Diario, ideas, recordatorios +- **Base de conocimiento**: Wiki personal, documentación +- **Gestión de proyectos**: Tareas, planificación +- **Investigación**: Organización de información +- **Snippets de código**: Biblioteca de código reutilizable +- **Journaling**: Diario personal cifrado + +### Tips + +- Usa `Ctrl+P` para búsqueda rápida +- Usa `Ctrl+S` para guardar (automático) +- Usa `Alt+Up/Down` para navegar por el árbol +- Usa `Ctrl+K` para crear links internos +- Usa `#` para etiquetas en el título +- Usa backlinks para ver referencias a una nota diff --git a/wireguard/README.md b/wireguard/README.md new file mode 100644 index 0000000..aad47be --- /dev/null +++ b/wireguard/README.md @@ -0,0 +1,435 @@ +# WireGuard - VPN Rápida y Segura + +WireGuard es una VPN moderna, rápida y segura. Este stack usa `wg-easy` para gestión simplificada de clientes. + +## 📋 Descripción + +Este stack despliega WireGuard con: +- Interfaz web para gestión de clientes (wg-easy) +- Generación automática de configuraciones de clientes +- Códigos QR para configuración móvil rápida +- Panel web protegido con Authentik +- Puerto UDP para el túnel VPN + +## 🚀 Despliegue + +### Prerequisitos + +1. **Red Docker**: Asegúrate de que la red `proxy` existe +2. **Registro DNS**: Configura el registro A para tu dominio WireGuard +3. **Puerto UDP**: El puerto UDP debe estar abierto en el firewall (por defecto 51820) +4. **Kernel modules**: El servidor debe soportar WireGuard + +### Verificar Soporte WireGuard + +```bash +# Verificar módulo WireGuard +lsmod | grep wireguard + +# O intentar cargarlo +sudo modprobe wireguard + +# Si falla, instala wireguard-tools +sudo dnf install wireguard-tools # Fedora/RHEL +sudo apt install wireguard # Debian/Ubuntu +``` + +### Desde Portainer + +1. Ve a **Stacks** → **Add stack** +2. Nombre: `wireguard` +3. Selecciona **Repository** o **Git repository** +4. Configura: + - Repository URL: `` + - Repository reference: `main` + - Compose path: `wireguard/docker-compose.yml` +5. Carga el archivo de variables de entorno: `wireguard/stack.env` +6. Haz clic en **Deploy the stack** + +### Variables de Entorno + +Edita el archivo `stack.env`: + +```env +# Imagen +WG_EASY_IMAGE=ghcr.io/wg-easy/wg-easy:latest + +# Dominio o IP pública del servidor +WG_HOST=vpn.tudominio.com + +# Puerto UDP de WireGuard (debe estar abierto en el firewall) +WG_PORT=51820 +WG_UDP_PORT=51820 + +# Puerto HTTP de la UI (interno) +WG_UI_PORT=51821 + +# Credenciales iniciales para la UI +INIT_ENABLED=true +INIT_USERNAME=admin +INIT_PASSWORD=tu-password-seguro + +# Desactivar IPv6 (si el servidor no lo soporta) +DISABLE_IPV6=true + +# Rutas +WG_DATA_PATH=/opt/wireguard/data +WG_MODULES_PATH=/lib/modules + +# Dominio de la UI +WG_DOMAIN=vpn-admin.tudominio.com + +# Traefik +TRAEFIK_DOCKER_NETWORK=proxy +TRAEFIK_ENTRYPOINT_SECURE=websecure +TRAEFIK_CERTRESOLVER=letsencrypt +TRAEFIK_AUTH_MIDDLEWARE=authentik@docker +``` + +> **⚠️ Importante**: +> - Cambia `INIT_PASSWORD` por una contraseña segura +> - Usa tu dominio o IP pública en `WG_HOST` + +### Abrir Puerto UDP en el Firewall + +```bash +# Firewalld (Fedora/RHEL) +sudo firewall-cmd --permanent --add-port=51820/udp +sudo firewall-cmd --reload + +# UFW (Ubuntu/Debian) +sudo ufw allow 51820/udp + +# iptables +sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT +sudo iptables-save > /etc/iptables/rules.v4 +``` + +## ⚙️ Configuración Post-Instalación + +### 1. Acceso al Panel Web + +1. Accede a `https://vpn-admin.tudominio.com` +2. Si configuraste Authentik, serás redirigido al SSO +3. Inicia sesión con las credenciales configuradas en `INIT_USERNAME` y `INIT_PASSWORD` + +### 2. Crear Cliente VPN + +1. En el panel web, haz clic en **+ Add Client** +2. Nombre del cliente: `mi-laptop`, `mi-movil`, etc. +3. El cliente se crea automáticamente con: + - Par de claves pública/privada + - IP asignada dentro del túnel VPN + - Configuración completa + +### 3. Configurar Cliente + +#### Móvil (Android/iOS) + +1. Instala la app **WireGuard** desde Play Store o App Store +2. En el panel web, haz clic en el icono **QR** del cliente +3. Escanea el código QR con la app +4. Activa el túnel VPN + +#### Windows/Mac/Linux Desktop + +##### Opción A: Escanear QR + +1. Descarga WireGuard desde [wireguard.com](https://www.wireguard.com/install/) +2. Instala la aplicación +3. Haz clic en **Import tunnel(s) from QR code** +4. Escanea el QR del panel web con tu webcam + +##### Opción B: Descargar archivo de configuración + +1. En el panel web, haz clic en el icono **Download** del cliente +2. Guarda el archivo `.conf` +3. En WireGuard app, haz clic en **Import tunnel(s) from file** +4. Selecciona el archivo `.conf` + +##### Opción C: Configuración manual + +Copia la configuración del panel web: + +```ini +[Interface] +PrivateKey = tu_clave_privada +Address = 10.8.0.2/24 +DNS = 1.1.1.1 + +[Peer] +PublicKey = clave_publica_servidor +PresharedKey = clave_compartida +Endpoint = vpn.tudominio.com:51820 +AllowedIPs = 0.0.0.0/0, ::/0 +PersistentKeepalive = 25 +``` + +Guarda como `cliente.conf` y carga en WireGuard. + +### 4. Verificar Conexión + +Una vez activado el túnel: + +```bash +# Verificar IP pública (debe ser la de tu servidor VPN) +curl ifconfig.me + +# Ping al servidor VPN (IP interna) +ping 10.8.0.1 + +# Verificar DNS +nslookup google.com +``` + +## 🔧 Configuración Avanzada + +### Rutear Solo Tráfico Específico (Split Tunneling) + +Por defecto, WireGuard enruta TODO el tráfico (`AllowedIPs = 0.0.0.0/0`). + +Para rutear solo ciertos rangos: + +1. Descarga el archivo `.conf` del cliente +2. Edita `AllowedIPs`: + ```ini + AllowedIPs = 10.8.0.0/24, 192.168.1.0/24 + ``` +3. Importa el archivo modificado en el cliente + +Ejemplos: +- Solo red VPN: `10.8.0.0/24` +- Red VPN + red local del servidor: `10.8.0.0/24, 192.168.1.0/24` +- Todo excepto red local del cliente: `0.0.0.0/1, 128.0.0.0/1` + +### Cambiar Rango de IPs de la VPN + +Por defecto usa `10.8.0.0/24`. Para cambiar: + +1. Detén el stack +2. Edita `/opt/wireguard/data/wireguard.conf` +3. Cambia: + ```ini + [Interface] + Address = 10.9.0.1/24 + ``` +4. Actualiza también en cada cliente +5. Reinicia el stack + +### Usar DNS Personalizado + +Para que los clientes usen tu AdGuard Home: + +1. En el panel web, ve a **Settings** +2. Cambia **DNS** a la IP de tu servidor (ej: `192.168.1.10`) +3. O edita manualmente en cada archivo `.conf`: + ```ini + DNS = IP-de-tu-AdGuard + ``` + +### Limitar Ancho de Banda + +No soportado directamente por wg-easy, pero puedes usar `tc` en el servidor: + +```bash +# Limitar a 10 Mbps +sudo tc qdisc add dev wg0 root tbf rate 10mbit burst 32kbit latency 400ms +``` + +### Configurar Post-Up/Post-Down Scripts + +Para ejecutar scripts al iniciar/detener el túnel: + +Edita `/opt/wireguard/data/wireguard.conf`: + +```ini +[Interface] +PostUp = iptables -A FORWARD -i wg0 -j ACCEPT +PostDown = iptables -D FORWARD -i wg0 -j ACCEPT +``` + +## 🛠️ Troubleshooting + +### No puedo conectar al VPN + +1. Verifica que el puerto UDP está abierto: + ```bash + sudo netstat -tulpn | grep 51820 + nc -zuv vpn.tudominio.com 51820 + ``` + +2. Verifica que WireGuard está corriendo: + ```bash + docker logs wg-easy + ``` + +3. Verifica que el módulo WireGuard está cargado: + ```bash + lsmod | grep wireguard + ``` + +4. Verifica la configuración del cliente (especialmente `Endpoint`) + +### Conecta pero no hay Internet + +1. Verifica que el forwarding está habilitado en el servidor: + ```bash + cat /proc/sys/net/ipv4/ip_forward # Debe ser 1 + ``` + +2. Verifica las reglas de iptables: + ```bash + sudo iptables -L -v -n + ``` + +3. Verifica la configuración de NAT en wg-easy + +### Panel web no accesible + +1. Verifica que está corriendo: + ```bash + docker ps | grep wg-easy + ``` + +2. Verifica los logs: + ```bash + docker logs wg-easy + ``` + +3. Verifica Traefik: + ```bash + docker logs traefik | grep wg + ``` + +### Error "Cannot find device wg0" + +El módulo WireGuard no está cargado: + +```bash +# Intentar cargar +sudo modprobe wireguard + +# Si falla, instalar +sudo dnf install wireguard-tools # Fedora/RHEL +sudo apt install wireguard # Debian/Ubuntu +``` + +### Clientes se desconectan frecuentemente + +1. Aumenta `PersistentKeepalive` en la configuración del cliente: + ```ini + PersistentKeepalive = 25 + ``` + +2. Verifica el MTU (puede ser muy alto para tu red): + ```ini + MTU = 1280 + ``` + +### IPv6 causa problemas + +Desactiva IPv6 en `stack.env`: + +```env +DISABLE_IPV6=true +``` + +Y reinicia el stack. + +## 📚 Recursos Adicionales + +- [Documentación oficial de WireGuard](https://www.wireguard.com/) +- [wg-easy en GitHub](https://github.com/wg-easy/wg-easy) +- [Guía de WireGuard](https://www.wireguard.com/quickstart/) + +## 🔒 Seguridad + +- **Cifrado**: WireGuard usa criptografía moderna (ChaCha20, Curve25519) +- **Panel web**: Protegido con Authentik (SSO) +- **Claves**: Cada cliente tiene su par de claves único +- **PresharedKey**: Capa adicional de seguridad cuántica +- **Firewall**: Solo el puerto UDP de WireGuard debe estar abierto + +### Best Practices + +1. **Cambia la contraseña** del panel web +2. **Usa Authentik** para proteger el panel +3. **Limita IPs** si solo necesitas acceso desde ciertos rangos +4. **Revoca clientes** cuando ya no los uses +5. **Haz backups** de `/opt/wireguard/data/` + +## 💾 Backups + +```bash +# Backup de configuraciones +sudo tar -czf wireguard-backup-$(date +%Y%m%d).tar.gz /opt/wireguard/data/ + +# Restaurar +sudo tar -xzf wireguard-backup-YYYYMMDD.tar.gz -C / +docker restart wg-easy +``` + +> **Importante**: Guarda los backups de forma segura. Contienen las claves privadas. + +## 🔄 Actualizaciones + +1. Haz backup de `/opt/wireguard/data/` +2. Actualiza en `stack.env`: + ```env + WG_EASY_IMAGE=ghcr.io/wg-easy/wg-easy:latest + ``` +3. Actualiza el stack en Portainer +4. Verifica que los clientes siguen conectando + +## 📊 Monitoreo + +### Ver Clientes Conectados + +En el panel web, verás: +- Clientes activos (verde) +- Última conexión +- Transferencia de datos +- IP asignada + +### Ver Stats del Túnel + +```bash +# Desde el servidor +docker exec wg-easy wg show + +# Ver configuración +docker exec wg-easy cat /etc/wireguard/wg0.conf + +# Ver logs +docker logs -f wg-easy +``` + +## 🎯 Casos de Uso + +### Acceso Remoto Seguro + +Accede a tu red doméstica desde cualquier lugar: +- Administra servidores +- Accede a servicios internos +- Usa impresoras de red + +### Protección en Redes Públicas + +Usa WireGuard en WiFi públicas para: +- Cifrar todo el tráfico +- Evitar ataques Man-in-the-Middle +- Proteger tus datos + +### Bypass de Restricciones Geográficas + +Usa la IP de tu servidor para: +- Acceder a contenido local +- Evitar censura +- Mantener tu IP original + +### Combinar con AdGuard + +Configura los clientes VPN para usar tu AdGuard Home: +- Bloqueo de anuncios en móvil +- Protección contra rastreadores +- DNS filtrado incluso fuera de casa