Gestion des plages d'IP en PHP/MySQL

Publié le samedi 2 novembre 2024 à 04:00

L'objectif est de traiter des blocs CIDR pour renforcer la sécurité d’un service web.

Premièrement, voyons comment calculer la première et la dernière adresse IP d'une plage (bloc CIDR) avec sa base et son masque :

$range = ['127.0.0.1', 8];
function rangeBegin($range) {
        return $range[0];
}
function rangeEnd($range) {
        return long2ip(ip2long($range[0]) | ((1 << (32 - $range[1])) - 1));
}

Maintenant comment vérifier si une IP est présente dans une plage (bloc CIDR) :

$ip = '127.0.0.1';
$range = ['127.0.0.1', 8];
function ipInRange($ip, $range) {
        if (ip2long($range[0]) <= ip2long($ip) && ip2long($ip) <= (ip2long($range[0]) | ((1 << (32 - $range[1])) - 1))) {
                return true;
        }
        return false;
}

En premier bonus, comment récupérer les plages d'IP d'amazon :

function fetchAmazonRange() {
        //Init array
        $amazonRanges = [];

        $ctx = stream_context_create(
                [
                        'http' => [
                                'method' => 'GET',
                                'max_redirects' => 0,
                                'timeout' => 5,
                                'ignore_errors' => false,
                                'header' => [
                                        'Connection: close',
                                        'Accept: application/json'
                                ]
                        ]
                ]
        ];

        //Fetch json
        if (($json = file_get_contents('https://ip-ranges.amazonaws.com/ip-ranges.json', false, $ctx)) === false) {
                return null;
        }

        //Decode it
        if (($json = json_decode($json)) === null || empty($json->prefixes)) {
                return false;
        }

        //Deal with prefixes
        foreach($json->prefixes as $range) {
                //Skip ipv6 and invalid ranges
                if (empty($range->ip_prefix)||!preg_match('/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/([0-9]+)$/', $range->ip_prefix, $matche
s)) {
                        continue;
                }
                //Remove whole match
                array_shift($matches);
                //Add ip and mask
                $amazonRanges[] = $matches;
        }

        //Send back result
        return $amazonRanges;
}

Urls pour les plages d'IP de Microsoft Azure :

Urls pour les plages d'IP de Google :