Gestion des plages d'IP en PHP/MySQL
Publié le mercredi 5 juillet 2023 à 18:59
J'ai eu récemment à trouver comment restreindre l'accès à un service en ligne à certaines plages d'IP. Voici la solution qui a répondu à mes besoins.
J'ai récemment du autoriser l'accès à un service en ligne à seulement quelques plages d'IP.
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 :