Compare commits

..

17 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
6 changed files with 175 additions and 64 deletions

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,7 +72,7 @@ docker compose up -d
Este stack expone el dashboard por dominio usando TLS y el servicio interno `api@internal`.
**Autenticación básica habilitada:** El dashboard está protegido mediante el middleware `auth-basic@file` definido en `dynamic/middlewares.yml`.
**Autenticación básica habilitada:** El dashboard está protegido mediante el middleware `auth-basic@file` definido en `dynamic/config.yml`.
### Configurar contraseña
@@ -87,7 +81,7 @@ Este stack expone el dashboard por dominio usando TLS y el servicio interno `api
docker run --rm httpd:alpine htpasswd -nbB admin tu_password_segura
```
2. Edita `dynamic/middlewares.yml` línea 35 y reemplaza el hash de ejemplo:
2. Edita `dynamic/config.yml` (sección middlewares > auth-basic) y reemplaza el hash de ejemplo:
```yaml
auth-basic:
basicAuth:
@@ -137,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,9 +24,10 @@ services:
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
# Autenticación básica (usa middleware del archivo dynamic/middlewares.yml)
# 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,7 +4,25 @@ 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
@@ -19,7 +37,7 @@ docker run --rm httpd:alpine htpasswd -nbB admin tu_password
2. Copia el hash completo (después de `admin:`)
3. Edita `middlewares.yml` línea 35:
3. Edita `config.yml` (sección http > middlewares > auth-basic):
```yaml
auth-basic:
basicAuth:
@@ -33,7 +51,7 @@ auth-basic:
### Aplicar middleware a un servicio
En el `docker-compose.yaml` de tu servicio:
En el `docker-compose.yml` de tu servicio:
```yaml
services:
@@ -52,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
@@ -61,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: 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

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: