Dealing with IP range in PHP/MySQL

Published the Saturday, 2 November 2024 at 04:00

The goal is to process some CIDR blocks to tighten a webservice security.

First let's see how to compute the first and last address of an IP range with just the block base IP and mask:

$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));
}

How to detect if an IP is present in a CIDR block:

$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;
}

As a first bonus, how to retrieve amazon IP ranges:

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

Microsoft Azure IP ranges urls:

Google IP ranges urls: