Request.connection.remoteAddress Now Prefixed в:: ffff в node.js

Недавно я изменил свой маршрутизатор на один, предоставленный Google для Google Fiber (yay!), и теперь я замечаю изменение в том, что я вижу, когда проверяю request.connection.remoteAddress, когда я разрабатываю на своем локальном сервере. Раньше я это видел:

request.connection.remoteAddress; // 192.168.1.10

Теперь я вижу это:

request.connection.remoteAddress; // ::ffff:192.168.1.10
  • Кто-нибудь может объяснить, что происходит?
  • Мой сервер Node прослушивает адреса IPv6?
  • Является ли ::ffff:192.168.1.10 фактическим адресом IPv6 или является IPv4-адресом?
  • Самый простой способ узнать, является ли remoteAddress IPv6, чтобы проверить, содержит ли строка ::?
  • При сохранении адресов IPv4 в базе данных я использовал что-то вроде INET_ATON, чтобы изменить их на большие целые числа. Должен ли я отказаться от этого и просто хранить все удаленные адреса в виде строк, длина которых может составлять 45 символов (максимальная длина строки адреса IPv6).

Ответ 1

Служит ли мой сервер Node для IPv6-адресов?

Да. Ваш сервер прослушивает соединения IPv6, а флаг IPV6_V6ONLY не установлен с результатом, что соединения IPv4 обрабатываются одним и тем же сокетом. Вы можете прочитать еще об этом флаге в этом вопросе.

Возможно ли подключение IPv6 (может быть перенаправлено на ваш сервер) в этом случае не имеет значения - важно, чтобы соединения IPv4 принимались сокетом, прослушивающим соединения IPv6.

Является ли ::ffff:192.168.1.10 фактическим адресом IPv6 или является IPv4-адресом?

И. Адреса IPv6 могут вставлять адреса IPv4 - и это один из этих внедренных адресов. См. IPv4-адреса IPv6 с отображением.

Самый простой способ узнать, является ли remoteAddress IPv6, проверить, содержит ли строка ::?

В адресе IPv6 необязательно содержится ::, это скорее короткая нотация, указывающая некоторое количество нулей. ::ffff:192.168.1.10 эквивалентно 0:0:0:0:0:ffff:192.168.1.10 или 0:0:0:0:0:ffff:c0a8:010a (см. представление адреса IPv6). Поэтому, чтобы различать адреса IPv6 и IPv4, вы должны просто проверить один двоеточие - :.

При хранении адресов IPv4 в базе данных я использовал что-то вроде INET_ATON, чтобы изменить их на большие целые числа. Должен ли я отказаться от этого и просто сохранить все удаленные адреса в виде строк, длина которых может составлять 45 символов (максимальная длина адресной строки IPv6).

Адрес IPv6 - это 128-битное число, даже если вы можете сохранить его как число (например, как два BIGINT числа в MySQL), сомнительно, действительно ли этот подход имеет смысл. Единственный сценарий, который я могу придумать, где вам нужно работать с числами, - это оценка масок подсети, для всего остального строка достаточна и удобна в обращении.

Ответ 2

re: # 4, библиотека, подобная ipaddr.js, работает хорошо, например:

var ipString = request.connection.remoteAddress;
if (ipaddr.IPv4.isValid(ipString)) {
  // ipString is IPv4
} else if (ipaddr.IPv6.isValid(ipString)) {
  var ip = ipaddr.IPv6.parse(ipString);
  if (ip.isIPv4MappedAddress()) {
    // ip.toIPv4Address().toString() is IPv4
  } else {
    // ipString is IPv6
  }
} else {
  // ipString is invalid
}