plugin = $plugin_instance; } /** * Función principal que comprueba si una IP es un bot conocido y verificado. * * @param string $ip La IP a verificar. * @param string $user_agent El User-Agent de la petición. * @return bool True si es un bot conocido y verificado, false en caso contrario. */ public function is_verified_bot($ip, $user_agent) { if (empty($ip) || empty($user_agent)) { return false; } // Usar caché estático para evitar múltiples consultas de DNS en la misma petición. if (isset(self::$verified_cache[$ip])) { return self::$verified_cache[$ip]; } $known_bots = [ // --- Motores de Búsqueda Principales (Alta Confianza) --- 'googlebot' => '.googlebot.com', 'google.com/bot' => '.google.com', 'adsbot-google' => '.googlebot.com', // Bot de Google Ads 'bingbot' => '.search.msn.com', 'adidxbot' => '.search.msn.com', // Bot de Bing Ads 'yandexbot' => '.yandex.com', 'duckduckbot' => '.duckduckgo.com', 'applebot' => '.applebot.apple.com', 'baiduspider' => '.baidu.com', // --- Bots de Redes Sociales (Meta Data Previews) --- 'facebookexternalhit' => '.facebook.com', 'facebot' => '.facebook.com', 'twitterbot' => '.twitter.com', 'linkedinbot' => '.linkedin.com', 'pinterestbot' => '.pinterest.com', // --- Herramientas SEO/Análisis (Recomendado Incluir) --- 'ahrefsbot' => '.ahrefs.com', 'semrushbot' => '.semrush.com', // --- Otros Bots de Confianza --- 'yahoo! slurp' => '.yahoo.com', // El bot principal de Yahoo 'yahoofaqbot' => '.yahoo.com', // Tu bot existente 'petalbot' => '.aspiegel.com', // Bot de Huawei / Petal Search ]; $is_known_bot = false; $expected_domain = ''; foreach ($known_bots as $ua_keyword => $domain) { if (stripos($user_agent, $ua_keyword) !== false) { $is_known_bot = true; $expected_domain = $domain; break; } } // Si el User-Agent no coincide con ningún bot conocido, no hay nada que verificar. if (!$is_known_bot) { return false; } // Ahora realizamos la verificación de DNS $is_verified = $this->verify_dns($ip, $expected_domain); self::$verified_cache[$ip] = $is_verified; return $is_verified; } /** * Realiza una verificación de DNS inversa (rDNS) y directa (forward DNS). * * @param string $ip La IP a verificar. * @param string $expected_domain El dominio que esperamos encontrar en el hostname. * @return bool True si la verificación es exitosa. */ private function verify_dns($ip, $expected_domain) { // Paso 1: Obtener el hostname de la IP (Reverse DNS - PTR Record) $hostname = gethostbyaddr($ip); // Si la IP no se resuelve a un hostname, o si el hostname es la propia IP, la verificación falla. if ($hostname === $ip || $hostname === false) { return false; } // Paso 2: Comprobar si el hostname pertenece al dominio esperado. // str_ends_with es de PHP 8.0+, usamos una alternativa compatible. if (substr($hostname, -strlen($expected_domain)) !== $expected_domain) { return false; } // Paso 3: Obtener la IP del hostname (Forward DNS - A Record) $resolved_ips = gethostbynamel($hostname); // Si el hostname no se resuelve a ninguna IP, la verificación falla. if ($resolved_ips === false || empty($resolved_ips)) { return false; } // Paso 4: Comprobar si la IP original está en la lista de IPs resueltas. return in_array($ip, $resolved_ips, true); } /** * Comprueba si un User-Agent coincide con un bot conocido, para identificar impostores. * No realiza la verificación de DNS, solo la coincidencia de UA. * * @param string $ip La IP a verificar. * @param string $user_agent El User-Agent de la petición. * @return bool True si el User-Agent coincide con un bot conocido. */ public function is_known_bot_impersonator($ip, $user_agent) { $known_bots = [ // --- Motores de Búsqueda Principales --- 'googlebot' => '.googlebot.com', 'google.com/bot'=> '.google.com', // Rastreadores específicos de Google 'bingbot' => '.search.msn.com', 'yandexbot' => '.yandex.com', 'duckduckbot' => '.duckduckgo.com', 'Applebot' => '.applebot.apple.com', // --- Bots de Redes Sociales (Meta Data Previews) --- 'facebot' => '.facebook.com', 'twitterbot' => '.twitter.com', 'linkedinbot' => '.linkedin.com', // --- Herramientas SEO/Análisis --- #'semrushbot' => '.semrush.com', #'ahrefsbot' => '.ahrefs.com', #'majestic-12' => '.mj12bot.com', // --- Otros --- 'yahoofaqbot' => '.yahoo.com', ]; foreach ($known_bots as $ua_keyword => $domain) { if (stripos($user_agent, $ua_keyword) !== false) { return true; // Coincide, pero la verificación principal ya ha fallado. } } return false; } }