Недавно мы писали о том что сделали поддержку 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 при достижении заданного количества запросов в единицу времени).