Недавно мы писали о том что сделали поддержку IPv6 в антиспам плагине. Но не только спамеры начали использовать IPv6, для других видов атак на сайты злоумышленники их тоже используют.
Мы реализовали поддержку IPv6 в плагине безопасности для WordPress. Обновлены методы определения IP адресов, хранения и передачи информации в облако.
Мы должны были научить плагин различать, стандартизировать, искать подсети и хранить IPv6 адреса. Несмотря на массу различных готовых решений пришлось делать свою реализацию и главная загвоздка в том что PHP может быть собран с различными параметрами, да и вообще может быть устаревшей версии, поэтому пришлось делать все с нуля.
Как только к нам попадает IP-адрес мы проверяем валидный ли он и его тип.
Затем определяем его принадлежность к частотному диапазону IP или диапазону CDN (Если существуют заголовки конкретных CDN). Вот тут и была самая главная сложность, так как все это необходимо было реализовать самостоятельно, а заодно и напомнить себе что к чему.
Решено было сделать поиск подсетей универсальным, чтобы на вход он мог получать как IPv4 так и IPv6, а при желании и IPv7, если доживем. Единственное что прописано жестко — это база X-тетов (октета для IPv4 и хекстетат для IPv6). Естественно рекурсия…
Надо отметить что функция принимает только нормализованные IPv6 адреса и сети(строку или массив строк сетей). Например, сеть Cloud Flare 2a06:98c0::0/29 не подойдет, ее надо будет развернуть в 2a06:98c0:0:0:0:0:0:0/29
Из-за того что, из локальной базы фаервола надо выбирать адреса на лету, средствами БД, а не средствами PHP. IPv6 адрес пришлось разбить на 4 колонки, каждая из них по 32 бита, соответствует одному IPv4 адресу. Соответственно, при такой структуре можно использовать старый метод выборки, с бинарными операциями.
Так же были внесены изменения в Панели управления сервисом и баз данных, для корректной обработки и отображения информации.
Реализована поддержка IPv6 для персональных черных списков, security firewall и функции Traffic Control(блокировка IP при достижении заданного количества запросов в единицу времени).
Мы реализовали поддержку IPv6 в плагине безопасности для WordPress. Обновлены методы определения IP адресов, хранения и передачи информации в облако.
Мы должны были научить плагин различать, стандартизировать, искать подсети и хранить IPv6 адреса. Несмотря на массу различных готовых решений пришлось делать свою реализацию и главная загвоздка в том что PHP может быть собран с различными параметрами, да и вообще может быть устаревшей версии, поэтому пришлось делать все с нуля.
Как только к нам попадает IP-адрес мы проверяем валидный ли он и его тип.
Затем определяем его принадлежность к частотному диапазону IP или диапазону CDN (Если существуют заголовки конкретных CDN). Вот тут и была самая главная сложность, так как все это необходимо было реализовать самостоятельно, а заодно и напомнить себе что к чему.
Решено было сделать поиск подсетей универсальным, чтобы на вход он мог получать как IPv4 так и IPv6, а при желании и IPv7, если доживем. Единственное что прописано жестко — это база X-тетов (октета для IPv4 и хекстетат для IPv6). Естественно рекурсия…
/* * Check if the IP belong to mask. Recursive. * Octet by octet for IPv4 * Hextet by hextet for IPv6 * @param ip string * @param cird mixed (string|array of strings) * @param ip_type string * @param cird mixed (string|array of strings) */ static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0){ if(is_array($cidr)){ foreach($cidr as $curr_mask){ if(self::ip__mask_match($ip, $curr_mask, $ip_type)){ return true; } } unset($curr_mask); return false; } if($ip_type == 'v4') $xtet_base = 8; if($ip_type == 'v6') $xtet_base = 16; // Calculate mask $exploded = explode('/', $cidr); // Exit condition $xtet_end = ceil($exploded[1] / $xtet_base); if($xtet_count == $xtet_end) return true; $mask = $exploded[1] - $xtet_base * $xtet_count >= 0 ? $xtet_base : $exploded[1] - $xtet_base * ($xtet_count - 1); $mask = 4294967295 << ($xtet_base - $mask); // Calculate first ip X-tet $ip_xtet = explode($ip_type == 'v4' ? '.' : ':', $ip); $ip_xtet = $ip_type == 'v4' ? $ip_xtet[$xtet_count] : hexdec($ip_xtet[$xtet_count]); // Calculate first net X-tet $net_xtet = explode($ip_type == 'v4' ? '.' : ':', $exploded[0]); $net_xtet = $ip_type == 'v4' ? $net_xtet[$xtet_count] : hexdec($net_xtet[$xtet_count]); $result = ($ip_xtet & $mask) == ($net_xtet & $mask); if($result) $result = self::ip__mask_match($ip, $cidr, $ip_type, $xtet_count + 1); return $result; }
Надо отметить что функция принимает только нормализованные IPv6 адреса и сети(строку или массив строк сетей). Например, сеть Cloud Flare 2a06:98c0::0/29 не подойдет, ее надо будет развернуть в 2a06:98c0:0:0:0:0:0:0/29
Из-за того что, из локальной базы фаервола надо выбирать адреса на лету, средствами БД, а не средствами PHP. IPv6 адрес пришлось разбить на 4 колонки, каждая из них по 32 бита, соответствует одному IPv4 адресу. Соответственно, при такой структуре можно использовать старый метод выборки, с бинарными операциями.
Так же были внесены изменения в Панели управления сервисом и баз данных, для корректной обработки и отображения информации.
Реализована поддержка IPv6 для персональных черных списков, security firewall и функции Traffic Control(блокировка IP при достижении заданного количества запросов в единицу времени).
