PHP如何通过IPv6地址获取主机名以验证Googlebot爬虫身份
PHP 环境IPv6 Googlebot身份验证落地方案
核心校验逻辑
完全对齐Google官方的爬虫验证规则,全程不需要依赖第三方接口:
- 对请求端IPv6地址做反向PTR解析,获取关联域名
- 校验域名后缀为
.google.com或.googlebot.com - 对解析得到的域名做正向AAAA记录解析,确认解析结果包含原始请求IP,避免伪造PTR记录
可直接运行的实现代码
function verifyGooglebotIPv6(string $ip): bool { // 先校验是否为合法IPv6地址 if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { return false; } // 构造IPv6反向PTR查询域名 $unpack = unpack('H*hex', inet_pton($ip)); $hex = $unpack['hex']; $ptrDomain = implode('.', str_split(strrev($hex))) . '.ip6.arpa'; // 查询PTR记录 $ptrRecords = dns_get_record($ptrDomain, DNS_PTR); if (empty($ptrRecords) || !isset($ptrRecords[0]['target'])) { return false; } $botDomain = $ptrRecords[0]['target']; // 校验域名后缀 $allowedSuffixes = ['.google.com', '.googlebot.com']; $isValidSuffix = false; foreach ($allowedSuffixes as $suffix) { if (str_ends_with($botDomain, $suffix)) { $isValidSuffix = true; break; } } if (!$isValidSuffix) { return false; } // 正向AAAA记录回查,避免PTR伪造 $aaaaRecords = dns_get_record($botDomain, DNS_AAAA); if (empty($aaaaRecords)) { return false; } foreach ($aaaaRecords as $record) { if (isset($record['ipv6']) && $record['ipv6'] === $ip) { return true; } } return false; } // 调用示例 $clientIp = $_SERVER['REMOTE_ADDR']; if (verifyGooglebotIPv6($clientIp)) { // 为真实Googlebot,执行对应逻辑 }
低版本PHP兼容说明
如果使用PHP8以下版本,没有内置str_ends_with函数,可以替换为以下判断逻辑:
function custom_str_ends_with(string $haystack, string $needle): bool { $length = strlen($needle); return $length === 0 || (substr($haystack, -$length) === $needle); }
生产环境优化建议
- 给DNS查询结果加12-24小时的缓存,避免频繁DNS查询导致的性能损耗
- 可以搭配IP段校验做双重验证,进一步提升校验效率
内容的提问来源于stack exchange,提问作者ma ja
相关产品推荐
相关产品推荐

