que paso?

This commit is contained in:
2025-10-05 04:01:15 -06:00
parent 72719e75b0
commit 84a03ab386
11 changed files with 1565 additions and 0 deletions

291
CLOUDFLARE.md Normal file
View File

@@ -0,0 +1,291 @@
# 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
<?php
$real_ip = $_SERVER['HTTP_CF_CONNECTING_IP']
?? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]
?? $_SERVER['REMOTE_ADDR'];
echo "IP real del visitante: $real_ip";
```
### Nginx (dentro de contenedor)
Si tienes nginx dentro de un contenedor detrás de Traefik:
```nginx
server {
location / {
# Traefik ya pasó los headers, solo léelos
set $real_ip $http_cf_connecting_ip;
# O usa el módulo real_ip
real_ip_header CF-Connecting-IP;
# Loguea la IP real
access_log /var/log/nginx/access.log combined;
}
}
```
## 🛡️ Seguridad
### ¿Por qué confiar solo en IPs de Cloudflare?
La configuración `trustedIPs` es crucial para **evitar IP spoofing**:
❌ **Sin trustedIPs:**
```
Atacante envía: X-Forwarded-For: 1.1.1.1
Traefik cree que la IP real es 1.1.1.1 (FALSO)
```
✅ **Con trustedIPs (configurado):**
```
Si la petición viene de 192.168.1.1 (no es IP de Cloudflare):
→ Traefik IGNORA el header X-Forwarded-For
→ Usa la IP de conexión real
Si viene de 173.245.48.5 (IP de Cloudflare):
→ Traefik CONFÍA en CF-Connecting-IP ✅
```
### Actualizar rangos de IPs de Cloudflare
Cloudflare publica sus IPs oficiales:
```bash
# IPv4
curl https://www.cloudflare.com/ips-v4
# IPv6
curl https://www.cloudflare.com/ips-v6
```
Si Cloudflare agrega nuevos rangos, actualiza `traefik/traefik.yml`.
## 🔐 SSL/TLS con Cloudflare
### Opciones de SSL en Cloudflare
En el dashboard de Cloudflare → SSL/TLS, tienes 3 opciones:
1. **Flexible** (❌ No recomendado)
- Cloudflare ↔ Cliente: HTTPS ✅
- Cloudflare ↔ Traefik: HTTP ❌
- Vulnerable a ataques man-in-the-middle
2. **Full** (⚠️ Aceptable)
- Cloudflare ↔ Cliente: HTTPS ✅
- Cloudflare ↔ Traefik: HTTPS ✅ (autofirmado OK)
- Más seguro
3. **Full (Strict)** (✅ Recomendado)
- Cloudflare ↔ Cliente: HTTPS ✅
- Cloudflare ↔ Traefik: HTTPS con certificado válido ✅
- Máxima seguridad
### Tu configuración actual
Con Cloudflare Tunnel apuntando a puerto **443**:
- Cloudflare → Tunnel → Traefik:443 (HTTPS)
- Traefik puede usar:
- **Certificados Let's Encrypt** (ya configurado en `traefik.yml`)
- O certificados autofirmados para el túnel
**Recomendación**: Usar **Full** o **Full (Strict)** en Cloudflare.
## 📊 Monitoreo de IPs
### Ver IPs en logs de Traefik
```bash
# Ver logs en tiempo real con IPs
docker compose logs -f traefik
# Filtrar solo IPs de Cloudflare
docker compose logs traefik | grep "CF-Connecting-IP"
# Ver estadísticas de IPs únicas
docker exec traefik cat /var/log/traefik/access.log | \
jq -r '.headers["CF-Connecting-IP"]' | \
sort | uniq -c | sort -rn
```
### Dashboard de Traefik
El dashboard muestra:
- ❌ IP de Cloudflare (173.245.x.x) en "Client Address"
- ✅ IP real disponible en logs JSON
## 🧪 Prueba rápida
Después de iniciar Traefik:
```bash
# 1. Simular petición desde "fuera" (pasando por Cloudflare)
curl -H "CF-Connecting-IP: 187.123.45.67" \
-H "Host: whoami.nucleoriofrio.com" \
http://localhost
# 2. Ver los logs y buscar la IP
docker compose logs traefik | tail -20
```
## ❓ FAQ
### ¿Necesito certificados SSL si uso Cloudflare?
**Para el tunnel NO** (Cloudflare maneja SSL público), **pero sí es recomendable** para:
- Seguridad adicional Cloudflare ↔ Traefik
- Servicios internos
- Modo Full (Strict) de Cloudflare
### ¿Puedo bloquear acceso directo al puerto 443?
**SÍ, deberías hacerlo**:
```bash
# Firewall: permitir solo Cloudflare IPs en 443
sudo ufw allow from 173.245.48.0/20 to any port 443
sudo ufw allow from 103.21.244.0/22 to any port 443
# ... agregar todos los rangos
# O usar iptables
sudo iptables -A INPUT -p tcp --dport 443 -s 173.245.48.0/20 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j DROP
```
Esto asegura que **solo Cloudflare** pueda llegar a Traefik.
### ¿Qué pasa si la IP en logs es de Cloudflare?
Verifica:
1. **Headers en logs:** `grep "CF-Connecting-IP" access.log`
2. **trustedIPs configurado:** Revisa `traefik.yml`
3. **Cloudflare enviando headers:** Verifica en Cloudflare dashboard
### ¿Los rangos de IP de Cloudflare cambian?
Sí, ocasionalmente. Verifica periódicamente:
```bash
curl https://www.cloudflare.com/ips-v4
```
Y actualiza `traefik.yml` si hay cambios.
## 📚 Referencias
- [Cloudflare IP Ranges](https://www.cloudflare.com/ips/)
- [Traefik ForwardedHeaders](https://doc.traefik.io/traefik/routing/entrypoints/#forwarded-headers)
- [Cloudflare Headers](https://developers.cloudflare.com/fundamentals/reference/http-request-headers/)
---
**Última actualización**: Octubre 2025
**Rangos de IP Cloudflare verificados**: Octubre 2025