Compare commits

...

19 Commits

Author SHA1 Message Date
fef085efef Renombrar docker-compose.yaml a docker-compose.yml 2025-12-02 19:20:14 +01:00
ba4d444f7e Crear red proxy automáticamente desde docker-compose 2025-12-02 19:16:53 +01:00
7c0b7b62c1 Actualizar ipWhiteList a ipAllowList en documentación 2025-12-01 18:09:51 +01:00
1822c4f3fb Actualizar documentación: logs, serversTransports y referencias a config.yml 2025-12-01 18:05:43 +01:00
91e4a2f8af Añadir serversTransport 'insecure' para certificados autofirmados 2025-12-01 15:56:58 +01:00
416bfe0430 Configurar logs sin persistencia (stdout) 2025-12-01 15:45:44 +01:00
811b0ad61a Añadir configuración de logs a Traefik 2025-12-01 15:42:53 +01:00
f6e2ddd714 Actualizar referencias a config.yml en README y documentación 2025-12-01 13:21:06 +01:00
24d46bfbf3 Fix: consolidar configuración dinámica en config.yml único 2025-12-01 13:19:04 +01:00
400d41687b Consolidar en un solo archivo dynamic/config.yml 2025-12-01 13:17:22 +01:00
dec01f536c Archivos separados sin raíz http: middlewares.yml, routers.yml, services.yml 2025-12-01 13:07:06 +01:00
7575b004ab Consolidar configuración dinámica en dynamic.yml (fix: http standalone error) 2025-12-01 13:04:37 +01:00
6e7067c91f Separar middlewares.yml y routers.yml en archivos independientes 2025-12-01 12:57:34 +01:00
f3815ae8df Consolidar ejemplos de routers en middlewares.yml (fix error standalone http) 2025-12-01 12:52:09 +01:00
4e9a74850c Añadir routers.yml con ejemplos de routers/servicios estáticos 2025-12-01 11:52:42 +01:00
77666edf14 Añadir rango 172.16.0.0/12 a ip-allowlist (redes privadas clase B) 2025-12-01 11:49:25 +01:00
cf589780f9 Actualizar middleware obsoleto: ipWhiteList → ipAllowList 2025-12-01 11:48:22 +01:00
afb95f4375 Habilitar autenticación básica en dashboard: middleware auth-basic@file + documentación 2025-12-01 11:46:42 +01:00
4d754b244b Eliminar .env.example (cambio local ya realizado) 2025-12-01 11:40:16 +01:00
7 changed files with 212 additions and 83 deletions

View File

@@ -1,8 +0,0 @@
# 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

View File

@@ -12,9 +12,10 @@ Traefik es un reverse proxy moderno y ligero que detecta servicios Docker autom
- 🔒 HTTPS automático con Let's Encrypt (HTTP-01)
- 🧠 Descubrimiento automático de servicios Docker
- 🧷 Redirección HTTP→HTTPS
- 🧿 Redirección HTTP→HTTPS
- 🧰 Dashboard web (seguro por dominio)
- 🧩 Middlewares: auth básica, headers de seguridad, rate limit, etc.
- 📊 Logs de acceso y errores (stdout/stderr)
## Requisitos
@@ -31,13 +32,7 @@ Internet → Traefik (80/443) → Servicios (en red proxy)
## Despliegue
### 1) Crear red `proxy`
```bash
docker network create proxy
```
### 2) Clonar y configurar
### 1) Clonar y configurar
```bash
git clone https://git.ictiberia.com/groales/traefik
@@ -49,7 +44,7 @@ touch ./letsencrypt/acme.json
chmod 600 ./letsencrypt/acme.json
```
### 3) Editar configuración
### 2) Editar configuración
**IMPORTANTE:** Antes de desplegar, edita los siguientes archivos con tus datos reales:
@@ -61,16 +56,15 @@ certificatesResolvers:
email: tu-email@tudominio.com # ← EDITA AQUÍ
```
**docker-compose.yaml:**
**docker-compose.yml:**
```yaml
labels:
- "traefik.http.routers.traefik.rule=Host(`traefik.tudominio.com`)" # ← EDITA AQUÍ
```
### 4) Desplegar
### 3) Desplegar
```bash
docker network create proxy # Si no existe
docker compose up -d
```
@@ -78,23 +72,27 @@ docker compose up -d
Este stack expone el dashboard por dominio usando TLS y el servicio interno `api@internal`.
Para proteger con autenticación básica (opcional):
**Autenticación básica habilitada:** El dashboard está protegido mediante el middleware `auth-basic@file` definido en `dynamic/config.yml`.
```yaml
labels:
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$<hash>"
```
### Configurar contraseña
Generar hash (htpasswd):
1. Genera el hash bcrypt:
```bash
# Linux/macOS
htpasswd -nb admin 'TuPassword'
# PowerShell con OpenSSL (alternativa)
# openssl passwd -apr1 TuPassword
docker run --rm httpd:alpine htpasswd -nbB admin tu_password_segura
```
2. Edita `dynamic/config.yml` (sección middlewares > auth-basic) y reemplaza el hash de ejemplo:
```yaml
auth-basic:
basicAuth:
users:
- "admin:$2y$05$tu_hash_generado_aqui"
```
3. Guarda el archivo. Traefik recargará automáticamente en ~10 segundos (no requiere reinicio).
**Usuario por defecto:** `admin` (cambia el hash según tu contraseña)
## Exponer Servicios Detrás de Traefik
Conecta tus servicios a la red `proxy` y añade labels. Ejemplo: Portainer
@@ -133,6 +131,23 @@ certificatesResolvers:
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
```
## Logs
Traefik envía logs a stdout/stderr (sin persistencia en disco):
```bash
# Ver logs en tiempo real
docker logs -f traefik
# Filtrar errores
docker logs traefik | Select-String -Pattern error
# Ver logs de acceso
docker logs traefik | Select-String -Pattern "GET|POST"
```
**Nivel de log**: INFO (configurable en `traefik.yml``log.level`)
## Troubleshooting
- Certificado no se emite:

View File

@@ -24,10 +24,10 @@ services:
- "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$$..."
# Autenticación básica (usa middleware del archivo dynamic/config.yml)
- "traefik.http.routers.traefik.middlewares=auth-basic@file"
networks:
proxy:
external: true
name: proxy
driver: bridge

View File

@@ -4,13 +4,54 @@ Este directorio contiene configuración que Traefik recarga automáticamente sin
## Archivos
- **middlewares.yml**: Middlewares reutilizables (headers seguridad, rate limit, auth, etc.)
- **config.yml**: Configuración dinámica completa (serversTransports, middlewares, routers, servicios)
**Importante:** Con `directory:` en el proveedor file, se debe usar un único archivo consolidado con la estructura `http:` como raíz.
## ServersTransports
El archivo incluye el transport `insecure` para servicios con certificados autofirmados (como Portainer):
```yaml
http:
serversTransports:
insecure:
insecureSkipVerify: true
```
**Uso en labels**:
```yaml
- "traefik.http.services.mi-servicio.loadbalancer.serversTransport=insecure@file"
```
## Autenticación Básica
El middleware `auth-basic` está **habilitado por defecto** para proteger el dashboard de Traefik.
### Configurar tu contraseña
1. Genera hash bcrypt:
```bash
docker run --rm httpd:alpine htpasswd -nbB admin tu_password
```
2. Copia el hash completo (después de `admin:`)
3. Edita `config.yml` (sección http > middlewares > auth-basic):
```yaml
auth-basic:
basicAuth:
users:
- "admin:$2y$05$HASH_GENERADO_AQUI"
```
4. Guarda → recarga automática en ~10 segundos
## Uso
### Aplicar middleware a un servicio
En el `docker-compose.yaml` de tu servicio:
En el `docker-compose.yml` de tu servicio:
```yaml
services:
@@ -29,7 +70,7 @@ services:
Puedes combinar varios:
```yaml
- "traefik.http.routers.app.middlewares=security-headers@file,rate-limit@file,ip-whitelist@file"
- "traefik.http.routers.app.middlewares=security-headers@file,rate-limit@file,ip-allowlist@file"
```
## Recarga automática
@@ -38,4 +79,5 @@ Traefik detecta cambios en este directorio y recarga sin reiniciar. Espera ~10 s
## Ejemplos adicionales
Consulta la wiki: https://git.ictiberia.com/groales/traefik/wiki/Middlewares-Seguridad
- **Routers y Servicios:** Ver ejemplos comentados en `config.yml` (secciones routers y services) para configurar rutas sin labels Docker
- **Middlewares avanzados:** Consulta la wiki: https://git.ictiberia.com/groales/traefik/wiki/Middlewares-Seguridad

116
dynamic/config.yml Normal file
View File

@@ -0,0 +1,116 @@
# ============================================
# CONFIGURACIÓN DINÁMICA DE TRAEFIK
# ============================================
# Este archivo contiene middlewares, routers y servicios
# Traefik recarga automáticamente los cambios (~10s)
http:
# ============================================
# SERVERS TRANSPORTS
# ============================================
serversTransports:
# Transport para servicios con certificados autofirmados
insecure:
insecureSkipVerify: true
# ============================================
# MIDDLEWARES
# ============================================
middlewares:
# Headers de seguridad
security-headers:
headers:
stsSeconds: 63072000
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
customResponseHeaders:
X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex"
# Rate limiting
rate-limit:
rateLimit:
average: 100
burst: 200
period: 1m
# IP Allow List (ejemplo - ajusta tus IPs)
ip-allowlist:
ipAllowList:
sourceRange:
- "127.0.0.1/32"
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
# Autenticación básica (genera hash con: docker run --rm httpd:alpine htpasswd -nbB admin tu_password)
auth-basic:
basicAuth:
users:
- "admin:$2y$05$example_hash_CHANGE_THIS" # CAMBIA ESTE HASH
# Redirect www a root
redirect-www:
redirectRegex:
regex: "^https?://www\\.(.+)"
replacement: "https://${1}"
permanent: true
# ============================================
# ROUTERS (Ejemplos comentados)
# ============================================
# routers:
# # Ejemplo: Router para aplicación web con HTTPS y middlewares
# whoami:
# rule: "Host(`whoami.tudominio.com`)"
# entryPoints:
# - websecure
# middlewares:
# - security-headers
# - rate-limit
# service: whoami-service
# tls:
# certResolver: letsencrypt
#
# # Ejemplo: Router con autenticación básica y restricción IP
# admin-panel:
# rule: "Host(`admin.tudominio.com`)"
# entryPoints:
# - websecure
# middlewares:
# - auth-basic
# - ip-allowlist
# - security-headers
# service: admin-service
# tls:
# certResolver: letsencrypt
# ============================================
# SERVICES (Ejemplos comentados)
# ============================================
# services:
# # Ejemplo: Servicio apuntando a contenedor local
# whoami-service:
# loadBalancer:
# servers:
# - url: "http://whoami:80"
#
# # Ejemplo: Servicio apuntando a servidor externo
# admin-service:
# loadBalancer:
# servers:
# - url: "http://192.168.1.100:8080"
#
# # Ejemplo: Servicio con health check
# api-service:
# loadBalancer:
# servers:
# - url: "http://api:3000"
# healthCheck:
# path: "/health"
# interval: "10s"
# timeout: "3s"

View File

@@ -1,43 +0,0 @@
http:
middlewares:
# Headers de seguridad
security-headers:
headers:
stsSeconds: 63072000
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
customResponseHeaders:
X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex"
# Rate limiting
rate-limit:
rateLimit:
average: 100
burst: 200
period: 1m
# IP Whitelist (ejemplo - ajusta tus IPs)
ip-whitelist:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "10.0.0.0/8"
- "192.168.0.0/16"
# Autenticación básica (genera hash con: htpasswd -nb usuario password)
# auth-basic:
# basicAuth:
# users:
# - "admin:$apr1$..."
# Redirect www a root
redirect-www:
redirectRegex:
regex: "^https?://www\\.(.+)"
replacement: "https://${1}"
permanent: true

View File

@@ -2,6 +2,13 @@
api:
dashboard: true
insecure: false
# Logs
log:
level: INFO # DEBUG, INFO, WARN, ERROR
accessLog: {}
# Puertos de escucha de Traefik y redirección automatica
entryPoints:
web: