From c0aa57b7d408edc9c6408141616687ec3a48d598 Mon Sep 17 00:00:00 2001 From: groales Date: Sat, 29 Nov 2025 17:34:08 +0100 Subject: [PATCH] Initial commit: Traefik v2 con Let's Encrypt y red proxy --- .env.example | 8 +++ .gitignore | 17 +++++ README.md | 152 ++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 32 ++++++++++ traefik.yml | 31 +++++++++ 5 files changed, 240 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docker-compose.yaml create mode 100644 traefik.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3b1f5d3 --- /dev/null +++ b/.env.example @@ -0,0 +1,8 @@ +# Email de Let's Encrypt para notificaciones +ACME_EMAIL=admin@tudominio.com + +# Dominio para el dashboard (opcional) +TRAEFIK_DASHBOARD_DOMAIN=traefik.tudominio.com + +# Zona horaria +TZ=Europe/Madrid diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9a19f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Traefik +letsencrypt/ +acme.json + +# Logs +*.log + +# OS +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ diff --git a/README.md b/README.md new file mode 100644 index 0000000..10e260a --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +# Infraestructura: Traefik + +# Traefik v2 — Reverse Proxy con Let's Encrypt + +Este repositorio despliega **Traefik** como proxy inverso con HTTPS automático (Let's Encrypt), listo para servir como puerta de entrada a tus servicios Docker mediante la red compartida `proxy`. + +## ¿Qué es Traefik? + +Traefik es un reverse proxy moderno y ligero que detecta servicios Docker automáticamente y los expone vía HTTP/HTTPS con reglas declarativas (labels) y certificados TLS automáticos con Let's Encrypt. + +## Características + +- 🔒 HTTPS automático con Let's Encrypt (HTTP-01) +- 🧠 Descubrimiento automático de servicios Docker +- 🧷 Redirección HTTP→HTTPS +- 🧰 Dashboard web (seguro por dominio) +- 🧩 Middlewares: auth básica, headers de seguridad, rate limit, etc. + +## Requisitos + +- Docker + Docker Compose +- Red Docker externa `proxy` +- Dominio apuntando al servidor (para dashboard y certificados) +- Puertos 80 y 443 accesibles desde Internet + +## Arquitectura + +``` +Internet → Traefik (80/443) → Servicios (en red proxy) +``` + +## Despliegue + +### 1) Crear red `proxy` + +```bash +docker network create proxy +``` + +### 2) Clonar y desplegar + +```bash +git clone https://git.ictiberia.com/groales/traefik +cd traefik + +# Crear carpeta y archivo para ACME +mkdir -p letsencrypt +# Windows PowerShell +echo $null > .\letsencrypt\acme.json +# Linux/macOS +# touch ./letsencrypt/acme.json + +# Permisos (Linux) +# chmod 600 ./letsencrypt/acme.json + +# Desplegar +docker compose up -d +``` + +### 3) Configurar dominio y email + +Edita `traefik.yml` y ajusta: +- `certificatesResolvers.letsencrypt.acme.email` +- (Opcional) Cambia el dominio del dashboard en labels del contenedor (`traefik.tudominio.com`) + +Reinicia: +```bash +docker compose up -d +``` + +## Dashboard Seguro + +Este stack expone el dashboard por dominio usando TLS y el servicio interno `api@internal`. + +Para proteger con autenticación básica (opcional): + +```yaml +labels: + - "traefik.http.routers.traefik.middlewares=traefik-auth" + - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$" +``` + +Generar hash (htpasswd): +```bash +# Linux/macOS +htpasswd -nb admin 'TuPassword' + +# PowerShell con OpenSSL (alternativa) +# openssl passwd -apr1 TuPassword +``` + +## Exponer Servicios Detrás de Traefik + +Conecta tus servicios a la red `proxy` y añade labels. Ejemplo: Portainer + +```yaml +services: + portainer: + image: portainer/portainer-ce:lts + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.portainer.rule=Host(`portainer.tudominio.com`)" + - "traefik.http.routers.portainer.entrypoints=websecure" + - "traefik.http.routers.portainer.tls=true" + - "traefik.http.routers.portainer.tls.certresolver=letsencrypt" + - "traefik.http.services.portainer.loadbalancer.server.port=9443" + - "traefik.http.services.portainer.loadbalancer.server.scheme=https" + +networks: + proxy: + external: true +``` + +## Buenas Prácticas + +- Usa `exposedByDefault=false` (ya configurado) y habilita servicios con `traefik.enable=true` +- No expongas puertos directos (`ports:`) si accedes vía Traefik +- Protege el dashboard con dominio + auth o restringe por IP +- Usa Let's Encrypt staging para pruebas intensivas: + +```yaml +certificatesResolvers: + letsencrypt: + acme: + caServer: https://acme-staging-v02.api.letsencrypt.org/directory +``` + +## Troubleshooting + +- Certificado no se emite: + - Verifica DNS y apertura del puerto 80 + - Revisa logs: `docker logs traefik | Select-String -Pattern cert,acme,error` +- 404 en servicio: + - Revisa labels y que el contenedor tenga `traefik.enable=true` + - Verifica que el servicio está en la red `proxy` +- Dashboard no carga: + - Asegura que el dominio apunta al servidor + - Verifica las labels del router `traefik` + +## Documentación adicional + +Consulta la **Wiki**: https://git.ictiberia.com/groales/traefik/wiki + +- Configuración avanzada (middlewares, serversTransport, mTLS) +- Ejemplos por servicio (Jellyfin, Nextcloud, Vaultwarden) +- Seguridad (headers, rate limiting, IP whitelist) + +--- + +**Última actualización**: Noviembre 2025 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..676be4f --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,32 @@ +services: + traefik: + image: traefik:latest + container_name: traefik + restart: always + ports: + - "80:80" # HTTP + - "443:443" # HTTPS + # - "8080:8080" # Dashboard (exponer solo si lo proteges) + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./traefik.yml:/traefik.yml:ro + - ./letsencrypt:/letsencrypt + environment: + TZ: "Europe/Madrid" + networks: + - proxy + labels: + - "traefik.enable=true" + # Dashboard seguro por dominio + - "traefik.http.routers.traefik.rule=Host(`traefik.tudominio.com`)" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls=true" + - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" + - "traefik.http.routers.traefik.service=api@internal" + # Opcional: Autenticación básica + # - "traefik.http.routers.traefik.middlewares=traefik-auth" + # - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$..." + +networks: + proxy: + external: true diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 0000000..a7da0f4 --- /dev/null +++ b/traefik.yml @@ -0,0 +1,31 @@ +api: + dashboard: true + insecure: false + +entryPoints: + web: + address: ":80" + http: + redirections: + entryPoint: + to: websecure + scheme: https + websecure: + address: ":443" + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + network: proxy + file: + directory: /etc/traefik/dynamic + watch: true + +certificatesResolvers: + letsencrypt: + acme: + email: admin@tudominio.com + storage: /letsencrypt/acme.json + httpChallenge: + entryPoint: web