У меня много проектов с функциями, основанными на IP-адресах, предоставляемых $_SERVER['REMOTE_ADDR]
, $_SERVER['HTTP_X_FORWARDED_FOR']
и $_SERVER['CLIENT_IP']
.
Адреса IPV4 легко сопоставляются, поскольку мы всегда получаем их в одном формате: 4 целых числа без ведущих 0, разделенных точкой .
,
В то время как адреса IPV6 могут быть сжаты. Пример: FF01: 0: 0: 0: 0: 0: 0: 101 -> FF01 :: 101
Я изучал этот вопрос, но не нашел ничего подходящего, поэтому я прошу вашего опыта. Является ли $_SERVER['REMOTE_ADDR]
стандартом? Можно ли предположить, что он всегда будет принят как сжатый или несжатый?
Или мне нужно сжать всю строку IPV6, прежде чем пытаться проверить их?
Заметка:
В идеале я хотел бы обрабатывать адреса IPV6 как строки, а не двоичную структуру, чтобы улучшить читаемость в Базах данных / Исходный код и упростить сопоставление диапазона IP.
Если вы inet_pton()
используете inet_pton()
, а затем преобразуете его обратно в строку с помощью inet_ntop()
вы должны иметь последовательное строковое представление. Я бы не стал полагаться на вход, чтобы быть последовательным …
Рекомендуемый формат для IPv6-адреса указан в RFC 5952 .
Однако вы не можете полагаться на все адреса, находящиеся в этом формате, и формат строки особенно неприятен для сравнения диапазонов. Чтение RFC даст вам некоторое представление о том, сколько способов можно юридически представить один и тот же адрес IPv6.
Вы действительно должны проанализировать адрес (используя inet_pton
как упоминалось в другом месте), и выполнить сравнение диапазона в полученном 128-битном поле.
Чаще всего вы будете заботиться только об 64 наиболее значимых битах, которые хорошо вписываются в большинство архитектур.
Спецификация CGI ясно, что любой RFC-совместимый IPv6-адрес действителен:
4.1.8. REMOTE_ADDR The REMOTE_ADDR variable MUST be set to the network address of the client sending the request to the server. REMOTE_ADDR = hostnumber hostnumber = ipv4-address | ipv6-address ipv4-address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit ipv6-address = hexpart [ ":" ipv4-address ] hexpart = hexseq | ( [ hexseq ] "::" [ hexseq ] ) hexseq = 1*4hex *( ":" 1*4hex ) The format of an IPv6 address is described in RFC 3513 [15].
-4.1.8. REMOTE_ADDR The REMOTE_ADDR variable MUST be set to the network address of the client sending the request to the server. REMOTE_ADDR = hostnumber hostnumber = ipv4-address | ipv6-address ipv4-address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit ipv6-address = hexpart [ ":" ipv4-address ] hexpart = hexseq | ( [ hexseq ] "::" [ hexseq ] ) hexseq = 1*4hex *( ":" 1*4hex ) The format of an IPv6 address is described in RFC 3513 [15].
Разумный программист проверяет все входы. Поэтому вы должны рассматривать любую переменную среды как испорченный вход и проверку / преобразование. Заголовки, предоставляемые клиентом, такие как X-Forward-For и др., ВСЕГДА следует обращаться с подозрением.
Итак, как насчет расширения адресов IPv6?
Этот вопрос задан раньше, и есть несколько решений, включая PEAR
Надеюсь это поможет!