# Traefik + Cloudflare Tunnel - Configuración Esta guía explica cómo funciona Traefik detrás de Cloudflare Tunnel y cómo obtener las IPs reales de los visitantes. ## 🌐 Arquitectura ``` Internet → Cloudflare (SSL/DDoS) → Cloudflare Tunnel → Traefik (443) → Contenedores ``` ## 📍 IPs Reales de Visitantes ### ¿Cómo funciona? Cuando un usuario visita tu sitio: 1. **Cloudflare recibe la conexión** y conoce la IP real del visitante 2. **Cloudflare envía la IP real en headers HTTP:** - `CF-Connecting-IP`: IP real del cliente ✅ (más confiable) - `X-Forwarded-For`: Cadena de proxies - `X-Real-IP`: IP real (alternativa) 3. **Traefik lee estos headers** y los pasa a tus aplicaciones ### Configuración aplicada Ya está configurado en `traefik/traefik.yml`: ```yaml entryPoints: websecure: forwardedHeaders: trustedIPs: - "173.245.48.0/20" # Rangos de IPs de Cloudflare - "103.21.244.0/22" # ... etc (23 rangos en total) ``` Esto le dice a Traefik: **"Confía en los headers de IPs que vienen de Cloudflare"** ### ✅ Verificar que funciona 1. **Inicia Traefik:** ```bash docker compose up -d ``` 2. **Verifica los logs de acceso:** ```bash docker compose logs traefik | grep "CF-Connecting-IP" ``` 3. **Deberías ver la IP real en los logs:** ```json { "ClientAddr": "173.245.48.5:12345", // IP de Cloudflare "headers": { "CF-Connecting-IP": "187.123.45.67" // ← IP REAL del visitante } } ``` ## 🔍 Leer IP real desde tus aplicaciones ### Node.js / Express ```javascript app.get('/', (req, res) => { const realIP = req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for']?.split(',')[0] || req.connection.remoteAddress; console.log('IP real del visitante:', realIP); }); ``` ### Python / Flask ```python from flask import Flask, request @app.route('/') def index(): real_ip = request.headers.get('CF-Connecting-IP') \ or request.headers.get('X-Forwarded-For', '').split(',')[0] \ or request.remote_addr print(f'IP real del visitante: {real_ip}') ``` ### Go / Gin ```go func handler(c *gin.Context) { realIP := c.GetHeader("CF-Connecting-IP") if realIP == "" { realIP = c.ClientIP() } fmt.Printf("IP real del visitante: %s\n", realIP) } ``` ### PHP ```php