web-dev-qa-db-ja.com

request.connection.remoteAddressがnode.jsの:: ffffでプレフィックスされるようになりました

最近、ルーターをGoogle Fiber for Google Fiberに提供されたものに変更しました(イェーイ!)。今、ローカルサーバーで開発中にrequest.connection.remoteAddressを調べると、表示が変わっていることに気付きました。以前、私はこれを見ていました:

request.connection.remoteAddress; // 192.168.1.10

今、私はこれを見ています:

request.connection.remoteAddress; // ::ffff:192.168.1.10
  1. 誰が何が起こっているのか説明できますか?
  2. 私のNodeサーバーはIPv6アドレスをリッスンしていますか?
  3. ::ffff:192.168.1.10は実際にはIPv6アドレスですか、それともIPv4アドレスですか?
  4. RemoteAddressがIPv6かどうかを確認する最も簡単な方法は、文字列に::が含まれているかどうかを確認することですか?
  5. データベースにIPv4アドレスを保存するときに、INET_ATONのようなものを使用して、それらを大きな整数に変更していました。これを破棄して、すべてのリモートアドレスを45文字の文字列(IPv6アドレス文字列の最大長)として保存する必要があります
29
Kirk Ouimet

私のNodeサーバーはIPv6アドレスをリッスンしていますか?

はい。サーバーはIPv6接続をリッスンしており、IPV6_V6ONLYフラグが設定されていないため、IPv4接続は同じソケットで処理されます。 この質問 で、このフラグについてもう少し読むことができます。

その場合、IPv6接続が可能かどうか(サーバーにルーティングできるかどうか)は関係ありません。重要なことは、IPv6接続をリッスンするソケットがIPv4接続を受信することです。

::ffff:192.168.1.10は実際にはIPv6アドレスですか、それともIPv4アドレスですか?

どちらも。 IPv6アドレスはIPv4アドレスを埋め込むことができます-これはこれらの埋め込みアドレスの1つです。 IPv4-mapped IPv6アドレス を参照してください。

RemoteAddressがIPv6かどうかを確認する最も簡単な方法は、文字列に::が含まれているかどうかを確認することですか?

IPv6アドレスには::が必ずしも含まれるわけではなく、ゼロの数を示す短い表記です。 ::ffff:192.168.1.100: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ビットの数字です-数字として(たとえば、MySQLで2つのBIGINT数字として)保存できる場合でも、このアプローチが本当に意味があるかどうかは疑問です。数字を扱う必要があると思う唯一のシナリオは、サブネットマスクを評価することです。他のすべてについては、文字列で十分であり、扱いやすいです。

41
Wladimir Palant

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
}
15
DuBistKomisch