Pull to refresh

Поддержка IPv6 в CleanTalk Security для WordPress

Reading time 2 min
Views 997
Недавно мы писали о том что сделали поддержку IPv6 в антиспам плагине. Но не только спамеры начали использовать IPv6, для других видов атак на сайты злоумышленники их тоже используют.

Мы реализовали поддержку 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 при достижении заданного количества запросов в единицу времени).
Tags:
Hubs:
+6
Comments 0
Comments Leave a comment

Articles

Information

Website
cleantalk.org
Registered
Founded
Employees
2–10 employees
Location
Россия