Express.js req.ip is returning ::ffff:127.0.0.1

node.jsExpress

node.js Problem Overview


I am currently trying to get the IP of the requested user. The problem is the IP is returning ::ffff:127.0.0.1 instead of 127.0.0.1. I tried using trusted proxy option (though not using a proxy) and the req.ips is blank. Using 4.x Express.js.

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

node.js Solutions


Solution 1 - node.js

::ffff: is a subnet prefix for IPv4 (32 bit) addresses that are placed inside an IPv6 (128 bit) space. IPv6 is broken into two parts, the subnet prefix, and the interface suffix. Each one is 64 bits long, or, 4 groups of 4 hexadecimal characters.

In IPv6, you are allowed to remove leading zeros, and then remove consecutive zeros, meaning ::ffff: actually translates to 0000:0000:ffff:0000, this address has been designated as the IPv4 to IPv6 subnet prefix, so any IPv6 processor will understand it's working with an IPv4 address and handle it accordingly.

In the near future, IP addresses will all be IPv6, this is because we are nearly out of numbers (4.2 billion, minus some space for misc. purposes) in the IPv4 address space.

> IPv6 allows for a much larger space. "340 undecillion ought to be > enough for anyone" - Bill Gates speaking on IPv6.

It is important to start addressing IP addresses using the IPv6 namespace and therefore include the ::ffff: in your code because in the future there will be real hexadecimal data between those colons. If you strip it off for aesthetic reasons, your code will break when it switches to an IPv6 network or it's confronted with an IPv6 address.

Some networks are currently running IPv6 and you will soon be confronted with IPv6 IP addresses; make the leap now or risk breaking your code in the future.

The TL;DR (short) version of the matter is: Everything is working fine. Don't change it, it's the IPv6 version of an IPv4 address.

IPv4 IPv6

If you want to make your code compatible with IPv6, all you have to do is check for the ::ffff: prefix... if it exists, remove it and process the remainder as IPv4... if ::ffff: doesn't exist, it's an IPv6 address and needs to be processed as such. You can double-check by seeing if periods are in the string, if so, it's IPv4.

Keep in mind for everything but adjustments you need to make to IP addresses, you're just recording the IP, right? It's going to be important to the parser and log aggregates to expect ::ffff:127.0.0.1 and such in the future. Unless you need to alter an IP, just leave it as what you receive.

Solution 2 - node.js

This seems to be a quirk of ipv6: for ipv4 addresses, ipv6 seems to mix ipv6 notation with ipv4 notation.

In order to get both ipv4 and ipv6 addresses in the simple, unmixed notation, I am using:

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

Solution 3 - node.js

If you just need IPv4, you could force the node server to listen using IPv4.

For an express app edit /bin/www:

change

server.listen(port);

to

server.listen(port, '0.0.0.0');

This worked for me at least.

https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback

Solution 4 - node.js

Windows 7 has IPv6 enabled by default. Even though my server listens on IPv4 only, Windows 7 sends the ::ffff: prefix to the IPv4 as part of the transition to IPv6

> ::ffff:0:0:0/96 — A prefix used for IPv4-translated addresses which are used by the Stateless IP/ICMP Translation (SIIT) protocol.

Transition from IPv4

Solution 5 - node.js

I was having issues with the trying to compare ipv4 mapped addresses, and found the ipaddr.js library helpful :-)

eg

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

Solution 6 - node.js

Try this to get exact ip address by removing subnetting,

    let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    ip = ip.toString().replace('::ffff:', '');

Solution 7 - node.js

var ip = req.ip.split(':').pop();

Solution 8 - node.js

You can Get your Ip address alone or with The specified family using 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]);  
      }
                    
                
        
                

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrockerBOOView Question on Stackoverflow
Solution 1 - node.jsNick SteeleView Answer on Stackoverflow
Solution 2 - node.jsannebView Answer on Stackoverflow
Solution 3 - node.jsYour Friend KenView Answer on Stackoverflow
Solution 4 - node.jsrockerBOOView Answer on Stackoverflow
Solution 5 - node.jsBryceView Answer on Stackoverflow
Solution 6 - node.jsMAREESKANNNAN RAJENDRANView Answer on Stackoverflow
Solution 7 - node.jsMateo MarinView Answer on Stackoverflow
Solution 8 - node.jsmuthukumar selvarajView Answer on Stackoverflow