最近、ルーターをGoogle Fiber for Google Fiberに提供されたものに変更しました(イェーイ!)。今、ローカルサーバーで開発中にrequest.connection.remoteAddressを調べると、表示が変わっていることに気付きました。以前、私はこれを見ていました:
request.connection.remoteAddress; // 192.168.1.10
今、私はこれを見ています:
request.connection.remoteAddress; // ::ffff:192.168.1.10
::ffff:192.168.1.10
は実際にはIPv6アドレスですか、それともIPv4アドレスですか?::
が含まれているかどうかを確認することですか?INET_ATON
のようなものを使用して、それらを大きな整数に変更していました。これを破棄して、すべてのリモートアドレスを45文字の文字列(IPv6アドレス文字列の最大長)として保存する必要があります私の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.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ビットの数字です-数字として(たとえば、MySQLで2つのBIGINT
数字として)保存できる場合でも、このアプローチが本当に意味があるかどうかは疑問です。数字を扱う必要があると思う唯一のシナリオは、サブネットマスクを評価することです。他のすべてについては、文字列で十分であり、扱いやすいです。
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
}