Express.js req.ip está retornando :: ffff: 127.0.0.1

Actualmente estoy tratando de obtener la IP del usuario solicitado. El problema es que el IP está devolviendo ::ffff:127.0.0.1 lugar de 127.0.0.1 . Intenté usar la opción de trusted proxy (aunque no use un proxy) y los req.ips están en blanco. Usando 4.x Express.js.

 router.get('/', function(req, res, next) { console.log('ip', req.ip) res.send({}) }); 

::ffff: es un prefijo de subred para direcciones IPv4 (32 bits) que se ubican dentro de un espacio IPv6 (128 bit). IPv6 está dividido en dos partes, el prefijo de la subred y el sufijo de la interfaz. Cada uno tiene 64 bits de longitud o 4 grupos de 4 caracteres hexadecimales.

En IPv6, puede eliminar ceros a la izquierda y luego eliminar ceros consecutivos, lo que significa ::ffff: realidad se traduce a 0000:0000:ffff:0000 , esta dirección se ha designado como el prefijo de subred IPv4 a IPv6, por lo que cualquier procesador IPv6 entenderá que está trabajando con una dirección IPv4 y lo manejará en consecuencia.

En un futuro cercano, las direcciones IP serán IPv6, esto es porque casi estamos fuera de los números (4,2 mil millones, menos espacio para propósitos diversos) en el espacio de direcciones IPv4.

IPv6 permite un espacio mucho más grande. “340 undecillion es suficiente para cualquiera” – Bill Gates hablando en IPv6.

Es importante comenzar a direccionar las direcciones IP utilizando el espacio de nombres IPv6 y, por lo tanto, incluir el ::ffff: en su código porque en el futuro habrá datos hexadecimales reales entre esos dos puntos. Si se lo quita por razones estéticas, su código se romperá cuando cambie a una red IPv6 o se enfrente a una dirección IPv6.

Algunas redes actualmente están ejecutando IPv6 y pronto se enfrentarán a las direcciones IPv6 IP; dé el salto ahora o arriesgue romper su código en el futuro.

La versión TL: DR (corta) del asunto es: Todo funciona bien. No lo modifique, es la versión IPv6 de una dirección IPv4.

IPv6 IPv4

Si quiere hacer que su código sea compatible con IPv6, todo lo que tiene que hacer es verificar el prefijo ::ffff: si existe, eliminarlo y procesar el rest como IPv4 … if ::ffff: doesn ‘ existe, es una dirección IPv6 y necesita ser procesada como tal. Puede verificar dos veces si los períodos están en la cadena, de ser así, es IPv4.

Tenga en cuenta todo lo que no sean los ajustes que necesita hacer a las direcciones IP, solo está grabando la IP, ¿verdad? Será importante analizar y analizar agregados para esperar ::ffff:127.0.0.1 y otros en el futuro. A menos que necesite modificar una IP, simplemente déjela como lo que recibe.

Esto parece ser una peculiaridad de ipv6: para direcciones ipv4, ipv6 parece mezclar notación ipv6 con notación ipv4.

Para obtener ambas direcciones ipv4 e ipv6 en la notación simple, sin mezclar, estoy usando:

 var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; if (ip.substr(0, 7) == "::ffff:") { ip = ip.substr(7) } 

Windows 7 tiene IPv6 habilitado por defecto. Aunque mi servidor solo escucha IPv4, Windows 7 envía el prefijo ::ffff: al IPv4 como parte de la transición a IPv6

::ffff:0:0:0/96 – Un prefijo utilizado para direcciones traducidas por IPv4 que son utilizadas por el protocolo de traducción IP / ICMP sin estado (SIIT).

Transición desde IPv4

Estaba teniendo problemas con el bash de comparar las direcciones mapeadas de ipv4, y encontré útil la biblioteca ipaddr.js 🙂

p.ej

 _.isEqual(ipaddr.process('::ffff:127.0.0.1'), ipaddr.process('127.0.0.1')) === true 

Puede obtener su dirección Ip sola o con la familia especificada usando sockets

  var app = require('express')(); app.get("/ip", (req, res) => { console.log(req.ip) let ip = req.ip.split(':'); let ip_details = req.socket.address(); console.log(ip_details); // { address: '::ffff:127.0.0.1', family: 'IPv6', port: 3001 console.log(ip[3]);//127.0.0.1 res.json(ip[3]); }