2012-04-25 23 views
5

Tengo muchos proyectos con funcionalidades que dependen de las direcciones IP proporcionadas por $_SERVER['REMOTE_ADDR], $_SERVER['HTTP_X_FORWARDED_FOR'] y $_SERVER['CLIENT_IP'].

Las direcciones IPV4 son fáciles de combinar, ya que siempre las recibimos en el mismo formato: 4 números enteros sin los 0 principales, separados por un punto ..

Considerando que las direcciones IPV6 se pueden comprimir. Ej: FF01: 0: 0: 0: 0: 0: 0: 101 -> FF01 :: 101

He estado investigando este problema pero no he encontrado nada relevante, entonces estoy pidiendo tu experiencia . ¿Es $_SERVER['REMOTE_ADDR] usando un estándar? ¿Es seguro suponer que siempre se recibirá comprimido o sin comprimir?

¿O debería comprimir toda mi cadena IPV6 antes de intentar probarlas?

Nota:

Tu lugar ideal para manejar direcciones IPv6 como cadenas en lugar de estructura binaria, para mejorar la legibilidad de las bases de datos de código/Fuente y permitir fácil adaptación rango de IP.

+0

No he trabajado con IPv6, pero tengo la impresión de que debe 'inet_pton()' cualquier dirección que desee manipular. –

+0

@ ÁlvaroG.Vicario Gracias por el comentario, definitivamente investigaré esta función. Pero me gustaría mantener la notación de cuerdas si es posible. – Tchoupi

Respuesta

5

Si primero usa inet_pton() y luego lo convierte de nuevo en una cadena con inet_ntop(), debe tener una representación de cadena consistente. No confío en que la entrada sea coherente ...

+1

Lo probé y parece dar un resultado consistente. Esto podría ser exactamente lo que estoy buscando. Voy a probarlo en un proyecto de la vida real para ver si podría funcionar. – Tchoupi

+0

He probado, funciona perfectamente. Y es bastante simple. ¡Gracias! – Tchoupi

+1

@Sander [inet_pton()] (http://php.net/manual/en/function.inet-pton.php) y [inet_ntop()] (http://php.net/manual/en/function. inet-ntop.php) ... ¿puedes poner estos enlaces en tu respuesta? –

1

El formato recomendado para la dirección IPv6 está en RFC 5952.

Sin embargo, no puede confiar en que todas las direcciones estén en ese formato, y el formato de cadena es particularmente malo para las comparaciones de rango. Leer el RFC le dará una idea de cuántas maneras es posible representar legalmente la misma dirección IPv6.

Realmente debe analizar la dirección (usando inet_pton como se menciona en otro lugar) y realizar comparaciones de rango en el campo de 128 bits resultante.

En la mayoría de los casos, solo le interesarán los 64 bits más significativos, que se ajusta muy bien a un long en la mayoría de las arquitecturas.

1

El CGI spec es claro que cualquier dirección IPv6 compatible con RFC es válida:

4.1.8. REMOTE_ADDR 

    The REMOTE_ADDR variable MUST be set to the network address of the 
    client sending the request to the server. 

     REMOTE_ADDR = hostnumber 
     hostnumber = ipv4-address | ipv6-address 
     ipv4-address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit 
     ipv6-address = hexpart [ ":" ipv4-address ] 
     hexpart  = hexseq | ([ hexseq ] "::" [ hexseq ]) 
     hexseq  = 1*4hex *(":" 1*4hex) 

    The format of an IPv6 address is described in RFC 3513 [15]. 

Un programador cuerdo valida todas las entradas. Por lo tanto, debe tratar cualquier variable de entorno como entrada contaminada y validar/transformar. Los encabezados proporcionados por un cliente, como X-Forward-For et al. SIEMPRE deben tratarse con sospecha.

¿Y qué hay de expandir las direcciones IPv6?

Esta pregunta tiene been asked before y there are several solutions incluyendo a PEAR one

Espero que esto ayude!

+0

Gracias!Por supuesto, primero validaré que es una IP válida. En realidad, estoy usando las funciones provistas en http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php para almacenar IPV4 e IPV6 en una base de datos. La solución PEAR parece buena, sin duda la probaré. – Tchoupi

+0

incluso dado que la función Pera, intentar hacer rangos de rango en un IPv6 en formato de cadena (incluso totalmente expandido) será muy difícil, particularmente si el rango no cae en un límite de nybble (es decir, a/62) – Alnitak

+0

@Alnitak Bueno punto. Mis rangos de IP se pueden reducir a un límite de mordisco, por lo que un simple 'strpos' debería ser el truco, suponiendo que tengo una entrada consistente. – Tchoupi

Cuestiones relacionadas