Distintas formas de obtener la dirección IP en PHP (con Cloudflare, con proxy interno, sin nada etc)

Tiempo de lectura: 2 minutos

Hoy vamos a aprender cómo podemos obtener la dirección IP en PHP incluso si nuestro server está enmascarado desde Cloudflare, Nginx Proxy o si no utilizamos ningún tipo de proxy.

Desayuno - pexels

Primero vamos a crear un archivo php nuevo llamado ip_config.php

Para obtener la dirección IP usaremos la siguiente función:

<?php

function getIP(): string
{
    if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
        $ip = $_SERVER['HTTP_CF_CONNECTING_IP']; // IP real del cliente detrás de Cloudflare
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        // Puede contener múltiples IPs, tomamos la primera válida
        $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $ip = trim($ipList[0]);
    } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
    }
    return $ip;
}

Y ahora te explico cada bloque lo que hace:

HTTP_CF_CONNECTING_IP

if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
    $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}

Este encabezado lo añade Cloudflare cuando tu servidor está detrás de su red.

  • Contiene la IP real del visitante, no la del proxy de Cloudflare.
  • Es el método más fiable si usas Cloudflare.

HTTP_X_FORWARDED_FOR

elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $ip = trim($ipList[0]);
}

Usado por reverse proxies, balanceadores o CDN (no siempre Cloudflare).

  • Puede contener una lista de IPs separadas por comas.
  • La primera suele ser la del cliente original.
    Precaución: este header puede ser falsificado si no controlas el proxy.

HTTP_CLIENT_IP

elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
}

Menos común, pero algunos proxies o redes internas lo usan para indicar la IP del cliente.

REMOTE_ADDR

else {
    $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

Este es el valor por defecto, la IP del cliente que se conecta directamente al servidor.

  • Si no hay proxy de por medio, es la IP real.
  • Si hay proxy y no se configuran bien los headers, será la IP del proxy.

En resumen:

EscenarioHeader usadoFiabilidad
CloudflareHTTP_CF_CONNECTING_IPAlta
Proxy / Load BalancerHTTP_X_FORWARDED_FORMedia
Cliente directoREMOTE_ADDRAlta

Si tenemos un proxy interno como nginx proxy manager, tendremos que poner lo siguiente:

# Trust Cloudflare's IP ranges
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

# Optional: also forward the IP in headers for PHP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Deja un comentario