package middlewares import ( "strings" "github.com/gofiber/fiber/v2" ) // IPDelCliente devuelve la IP pública desde la que se hizo la petición. // // c.IP() no sirve para esto en producción: detrás del proxy del hosting // devuelve la IP interna del proxy (10.x.x.x), así que ninguna IP pública // autorizada coincidía nunca y toda llave con restricción de IP daba 403. // // Sin Cloudflare se toma la ÚLTIMA entrada de X-Forwarded-For, no la primera: // con un solo proxy adelante, esa es la que escribió el proxy y no la puede // falsear quien llama. Si el cliente manda su propio X-Forwarded-For, el proxy // le agrega la IP real al final — quedarse con la primera sería creerle al que // llama. // // ponytail: esto vale mientras todo el tráfico entre por el proxy (y por // Cloudflare, si está). Quien pueda pegarle al origen directo puede falsear // ambos encabezados; si eso pasa a importar, hay que cerrar el origen a las // redes del proxy en vez de complicar esta función. func IPDelCliente(c *fiber.Ctx) string { // Cloudflare adelante: el proxy del hosting ve la IP del edge de CF, así // que la última entrada de X-Forwarded-For es 104.x.x.x y no el que llama. // CF-Connecting-IP la escribe Cloudflare con la IP real y sobrescribe la // que mande el cliente, así que cuando está es la buena. if cf := strings.TrimSpace(c.Get("CF-Connecting-IP")); cf != "" { return cf } if xff := c.Get("X-Forwarded-For"); xff != "" { partes := strings.Split(xff, ",") if ip := strings.TrimSpace(partes[len(partes)-1]); ip != "" { return ip } } if real := strings.TrimSpace(c.Get("X-Real-Ip")); real != "" { return real } return c.IP() }