*/ namespace ImageHeberg; /** * Fonctions relative à Tor */ class Tor { private const IPV4 = 'IPv4'; private const IPV6 = 'IPv6'; /** * Mettre à jour la liste des adresses IP des noeuds de sortie Tor */ public function updateListeExitNodes(): void { // Récupération du dernier fichier $objJson = json_decode(file_get_contents(_TOR_EXIT_NODE_LIST_URL_)); $tabIP = []; $tabIP[self::IPV4] = []; $tabIP[self::IPV6] = []; foreach ($objJson->relays as $unRelay) { // Adresse IP de sortie (IPv4 uniquement) // https://metrics.torproject.org/onionoo.html#details_relay_exit_addresses if (isset($unRelay->exit_addresses)) { foreach ($unRelay->exit_addresses as $uneIp) { $this->addToTab($uneIp, $tabIP); } } // Adresse IP sur lequel le noeud écoute (IPv4 + IPv6) // Lorsque exit_addresses incluera les IPv6, plus besoin de cette partie qui surbloque... if (isset($unRelay->or_addresses)) { foreach ($unRelay->or_addresses as $uneIp) { $this->addToTab($uneIp, $tabIP, true); } } } // Enregister le résultat sur le disque $retour = file_put_contents(_TOR_LISTE_IPV4_, json_encode($tabIP[self::IPV4])); echo 'IPv4 : ' . $retour; $retour = file_put_contents(_TOR_LISTE_IPV6_, json_encode($tabIP[self::IPV6])); echo '
IPv6 : ' . $retour; } /** * Nettoyer et ajouter une IP dans le tableau des adresses connues * @param string $ip @ IP à ajouter * @param string[] $tabIp Liste des addresses IP déjà connues * @param bool $withPort Le port est précisé (1.2.3.4:1234) */ private function addToTab(string $ip, array &$tabIp, bool $withPort = false): void { if (substr_count($ip, ':') > 1) { // C'est une IPv6 // Supprimer le port if ($withPort) { $ip = substr($ip, 0, strrpos($ip, ':')); } // Supprimer les crochets de la notation [1234:5678::] $ip = str_replace(['[', ']'], '', $ip); // Forcer la réécriture de l'IP $ip = inet_ntop(inet_pton($ip)); if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $this->saveInTab($ip, $tabIp, self::IPV6); } } else { // C'est une IPv4 // Supprimer le port if ($withPort) { $ip = substr($ip, 0, strrpos($ip, ':')); } // Valider l'IP et l'enregistrer si inconnue if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $this->saveInTab($ip, $tabIp, self::IPV4); } } } /** * Insérer dans le tableau une adresse sans faire de doublon * @param string $ip @ IP à ajouter * @param array $tabIp Liste des addresses IP déjà connues * @param string $typeIp IPv4 ou IPv6 */ private function saveInTab(string $ip, array &$tabIp, string $typeIp): void { if (!in_array($ip, $tabIp[$typeIp])) { $tabIp[$typeIp][] = self::formatIp($ip); } } /** * Formatter une adresse IP * @param string $ip adresse IP à formatter * @return string adresse IP formattée */ private static function formatIp(string $ip): string { return inet_ntop(inet_pton($ip)); } /** * Vérifie si une IP correspond à un noeud de sortie Tor * @param string $ip * @return bool */ public static function checkIp(string $ip): bool { $monRetour = true; $ip = self::formatIp($ip); if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { if (file_exists(_TOR_LISTE_IPV6_) && filesize(_TOR_LISTE_IPV6_) > 0) { $tabIp = json_decode(file_get_contents(_TOR_LISTE_IPV6_)); if (!in_array($ip, $tabIp)) { $monRetour = false; } } } elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { if (file_exists(_TOR_LISTE_IPV4_) && filesize(_TOR_LISTE_IPV4_) > 0) { $tabIp = json_decode(file_get_contents(_TOR_LISTE_IPV4_)); if (!in_array($ip, $tabIp)) { $monRetour = false; } } } return $monRetour; } }