📜 ⬆️ ⬇️

IPv6 support in CleanTalk Security for WordPress

Recently we wrote about the fact that we did support IPv6 in the antispam plugin . But not only spammers began to use IPv6, for other types of attacks on sites, attackers also use them.

We implemented IPv6 support in a WordPress security plugin . Updated methods for determining IP addresses, storing and transmitting information to the cloud.

We had to teach the plugin to distinguish, standardize, search for subnets and store IPv6 addresses. Despite a lot of different ready-made solutions, I had to do my implementation and the main catch was that PHP could be built with different parameters, and indeed it could be an outdated version, so I had to do everything from scratch.

As soon as we get an IP address, we check whether it is valid and its type.
')
Then we define its belonging to the IP frequency range or CDN range (If there are specific CDN headers). This was the main difficulty, since it was necessary to implement all this independently, and at the same time remind ourselves of what was happening.

It was decided to make the search for subnets universal, so that at the entrance it could receive both IPv4 and IPv6, and if desired, IPv7 if we live. The only thing that is spelled out is the base of X-thets (octet for IPv4 and hextetat for IPv6). Naturally recursion ...

/* * 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; } 


It should be noted that the function accepts only normalized IPv6 addresses and networks (a string or an array of network strings). For example, the Cloud Flare 2a06: 98c0 :: 0/29 network will not work, it will need to be deployed in 2a06: 98c0: 0: 0: 0: 0: 0: 0/29

Due to the fact that, from the local firewall database, it is necessary to select addresses on the fly, using database tools, and not using PHP tools. The IPv6 address had to be divided into 4 columns, each of them 32 bits each, corresponding to one IPv4 address. Accordingly, with this structure, you can use the old sampling method, with binary operations.

Also, changes were made in the Service Control Panel and databases for correct processing and display of information.

Implemented IPv6 support for personal blacklists, security firewall and Traffic Control functions (blocking IP when a specified number of requests are reached at a time).

Source: https://habr.com/ru/post/353716/


All Articles