web-dev-qa-db-ja.com

PHP $ _SERVER ['REMOTE_ADDR']はIPv6を示しています

PHPサーバーがIPv4を使用しているにもかかわらず、IPv6のような値を提供している$ _SERVER ['REMOTE_ADDR']の問題に直面しています。

誰かが私がこの問題を解決するのを手伝ってくれますか?.

9
Brijesh

その後、サーバーはIPv6ソケットで接続を受け入れます。一部のオペレーティングシステムは、IPv6ソケットでIPv4とIPv6の両方を実行できます。その場合、IPv6アドレスは::ffff:192.0.2.123または::ffff:c000:027bのようになります。これは同じアドレスですが、16進数で記述されています。

2a00:8640:1::224:36ff:feef:1d89のようなIPv6アドレスが表示されている場合、Webサーバーは実際にis IPv6経由で到達可能です:-)

とにかく、すべてを正規の形式に戻すには、次のようなものを使用できます。

// Known prefix
$v4mapped_prefix_hex = '00000000000000000000ffff';
$v4mapped_prefix_bin = pack("H*", $v4mapped_prefix_hex);

// Or more readable when using PHP >= 5.4
# $v4mapped_prefix_bin = hex2bin($v4mapped_prefix_hex); 

// Parse
$addr = $_SERVER['REMOTE_ADDR'];
$addr_bin = inet_pton($addr);
if( $addr_bin === FALSE ) {
  // Unparsable? How did they connect?!?
  die('Invalid IP address');
}

// Check prefix
if( substr($addr_bin, 0, strlen($v4mapped_prefix_bin)) == $v4mapped_prefix_bin) {
  // Strip prefix
  $addr_bin = substr($addr_bin, strlen($v4mapped_prefix_bin));
}

// Convert back to printable address in canonical form
$addr = inet_ntop($addr_bin);

このコードを使用して、次のいずれかを入力した場合:

::ffff:192.000.002.123
::ffff:192.0.2.123
0000:0000:0000:0000:0000:ffff:c000:027b
::ffff:c000:027b
::ffff:c000:27b
192.000.002.123
192.0.2.123

常に正規のIPv4アドレス192.0.2.123を出力として取得します。

そしてもちろん、IPv6アドレスは正規のIPv6アドレスとして返されます:2a00:8640:0001:0000:0224:36ff:feef:1d892a00:8640:1::224:36ff:feef:1d89などになります。

24
Sander Steffann