Express.js req.ip повертається :: ffff: 127.0.0.1


98

Зараз я намагаюся отримати IP-адресу запитуваного користувача. Проблема полягає в тому, що IP повертається ::ffff:127.0.0.1замість 127.0.0.1. Я спробував скористатися trusted proxyопцією (правда, не використовуючи проксі), і req.ipsце порожнє. Використання 4.x Express.js.

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

То що ти використовуєш req.ipчи req.ips?
Олександр М

req.ip, просто спробував req.ipsяк тест. Я просто не впевнений, що спричиняє префікс ::ffff:.
rockerBOO


Так це було. Windows 7 має перехідний рівень для запитів IPv4 і додає цей префікс до IP.
rockerBOO

Відповіді:


156

::ffff:- це префікс підмережі для IPv4 (32 бітових) адрес, які розміщені всередині простору IPv6 (128 біт). IPv6 розбитий на дві частини, префікс підмережі та суфікс інтерфейсу. Кожен має довжину 64 біти, або 4 групи з 4 шістнадцяткових символів.

У IPv6 вам дозволяється видаляти ведучі нулі, а потім видаляти послідовні нулі, тобто ::ffff:фактично перекладається на 0000:0000:ffff:0000, ця адреса була призначена як префікс підмережі IPv4 до IPv6, тому будь-який процесор IPv6 зрозуміє, що він працює з адресою IPv4, і обробляє її відповідно.

Найближчим часом усі IP-адреси будуть IPv6, це тому, що в адресному просторі IPv4 у нас майже не вистачає номерів (4,2 млрд., Мінус деякий простір для різних цілей).

IPv6 забезпечує набагато більший простір. "340 немільйонів має бути достатньо для всіх" - Білл Гейтс, виступаючи на IPv6.

Важливо розпочати адресувати IP-адреси за допомогою простору імен IPv6 і, отже, включити ::ffff:у свій код, оскільки в майбутньому між цими двокрапками будуть справжні шістнадцяткові дані. Якщо ви позбавите його з естетичних міркувань, ваш код зламається, коли він перемикається на мережу IPv6 або стикається з адресою IPv6.

Наразі в деяких мережах працює IPv6, і незабаром ви зіткнетеся з IPv6-адресами IPv6; зробіть стрибок зараз або ризикуйте зламати свій код у майбутньому.

TL; DR (коротка) версія питання: Все працює нормально. Не змінюйте це, це версія IPv6 адреси IPv4.

IPv6 IPv4

Якщо ви хочете зробити свій код сумісним з IPv6, все, що вам потрібно зробити, це перевірити ::ffff:префікс ... якщо він існує, видаліть його та обробіть решту як IPv4 ... якщо ::ffff:не існує, це адреса IPv6 і потребує обробки як такої. Ви можете ще раз перевірити, чи є в рядку крапки, якщо так, це IPv4.

Майте на увазі все, крім коригувань, які вам потрібно зробити для IP-адрес, ви просто записуєте IP, так? Це буде важливо для аналізатора та агрегатів журналів, які слід очікувати, ::ffff:127.0.0.1і таких у майбутньому. Якщо вам не потрібно змінити IP, просто залиште його як отриманий.


Проте перевірити наявність ::ffff:префіксу звучить досить небезпечно . Ви знаєте, IPv6 має багато позначень.
Константин Ван

1
Ні, це безпечно :) Є пропозиція, а потім - реалізація. en.wikipedia.org/wiki/ ... IETF визнав, що маршрутизатори не можуть спалити стільки циклів, що шукають IP-адреси, а також у дикій природі ніхто не зберігає нулі, оскільки це марно витрачений простір. Ідея дозволити нулі була просто ідеєю. У 2019 році, якщо ви надіслали :: ffff: у мережевому пакеті як 0000: 0000: ffff: 0000, хоча технічно справедливий для оригінальної пропозиції, він є недійсним для поточної рекомендації IETF, а також не бачиться у більшості маршрутизаторів, сумісних з IPv6.
Nick Steele

1
Тож я можу бути впевнений, що вони завжди перебувають у канонічних формах. Не знав, як ідуть справи в дикій природі. Дякую.
Константин Ван

На жаль, це поширене явище. Люди звертають увагу лише тоді, коли це необхідно. Хтось щось робить, оригінальний дизайн підтримує безліч функцій, вони роблять RFC, ніхто насправді не звертає уваги на багато частин дизайну, це стає стандартом, тоді при впровадженні люди помічають, що потрібні великі зміни :) IPv6 трохи дивний тому що називати це "канонічним" трохи дивно. Ймовірно, їм слід назвати це "1.1" або якось так, щоб люди могли швидко зрозуміти, що відбувається, але оскільки необов'язкові нулі оригінального чернетки змушують витратити в 10 разів більше обчислень у маршрутизаторах, це було просто проігноровано.
Нік Стіл,

29

Це, здається, химерність ipv6: для адрес ipv4 ipv6, здається, поєднує нотації ipv6 з нотацією ipv4.

Щоб отримати адреси ipv4 та ipv6 у простих, не змішаних позначеннях, я використовую:

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


10

У Windows 7 за замовчуванням увімкнено IPv6. Незважаючи на те, що мій сервер слухає лише на IPv4, Windows 7 надсилає ::ffff:префікс до IPv4 як частину переходу на IPv6

::ffff:0:0:0/96 - Префікс, що використовується для перекладених IPv4 адрес, які використовуються за протоколом перекладу IP / ICMP (SIIT) без громадянства.

Перехід з IPv4


8

У мене виникли проблеми зі спробою порівняти відображені адреси ipv4, і я знайшов бібліотеку ipaddr.js корисною :-)

напр

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


-2

Ви можете отримати свою Ip-адресу окремо або з вказаною родиною за допомогою розеток

     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]);  
      }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.