PHP应用中如何通过反向DNS查询获取真实域名而非通用域名?
获取Web流量日志中真实域名的可行方案
核心问题说明
反向DNS查询返回通用域名是因为多数公网IP属于CDN、云服务商或共享主机,其反向解析记录指向服务商的通用域名,而非用户实际访问的站点域名。要获取真实域名,需借助TLS/HTTP协议层面的信息补充。
可行解决方案
1. 捕获TLS握手阶段的SNI字段
SNI(Server Name Indication)是HTTPS连接时客户端发送的第一个关键信息,直接包含用户访问的真实域名。
- 如果是实时流量采集:调整流量监控工具(如tcpdump、Suricata),解析TLS握手包的Client Hello消息,提取SNI字段并存入日志表。
- 如果是历史日志补全:可尝试对高频访问的IP,批量发起模拟TLS握手请求获取SNI,PHP中可通过
openssl扩展实现:
function getSNIByIP(string $ip): ?string { $socket = @stream_socket_client("ssl://{$ip}:443", $errno, $errstr, 5); if (!$socket) { return null; } $context = stream_context_get_options(stream_context_get_default()); if (isset($context['ssl']['peer_certificate'])) { $cert = openssl_x509_parse($context['ssl']['peer_certificate']); if (isset($cert['extensions']['subjectAltName'])) { preg_match('/DNS:([^\s,]+)/', $cert['extensions']['subjectAltName'], $matches); return $matches[1] ?? null; } } fclose($socket); return null; }
2. 解析SSL证书的SAN字段
每个HTTPS站点的SSL证书会包含**Subject Alternative Name(SAN)**字段,记录该证书对应的所有域名。通过发起HTTPS请求获取证书,可提取这些域名:
function getDomainsFromSSLCert(string $ip): array { $domains = []; $context = stream_context_create([ 'ssl' => [ 'capture_peer_cert' => true, 'verify_peer' => false, 'verify_peer_name' => false, ] ]); $stream = @stream_socket_client("ssl://{$ip}:443", $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $context); if ($stream) { $certData = stream_context_get_options($context)['ssl']['peer_certificate']; $certInfo = openssl_x509_parse($certData); if (isset($certInfo['extensions']['subjectAltName'])) { preg_match_all('/DNS:([^\s,]+)/', $certInfo['extensions']['subjectAltName'], $matches); $domains = $matches[1] ?? []; } fclose($stream); } return $domains; }
注意:一个IP可能对应多个域名,返回的是证书覆盖的所有域名,需结合访问频率、时间窗口等日志维度匹配最可能的真实域名;同时需对查询结果做缓存,避免频繁请求触发IP封禁。
3. 补充采集HTTP Host头信息
如果流量是HTTP(非HTTPS),可直接解析请求的Host头获取域名;对于HTTPS,需通过深度包检测(DPI)工具解密流量后提取Host头(仅适用于可控内部网络场景)。
4. 结合WHOIS数据缩小范围
查询IP的WHOIS信息,确定其归属的服务商(如Cloudflare、AWS),再结合服务商公开的IP范围文档,可辅助判断域名类型,但无法直接获取真实域名,需配合上述方法使用。
总结
反向DNS无法满足需求时,捕获SNI字段是最直接有效的方案,因为现代HTTPS连接几乎都会发送SNI。若无法调整实时采集流程,可通过批量解析SSL证书的方式补全历史日志的域名信息,同时做好缓存和请求频率控制。
内容的提问来源于stack exchange,提问作者lockdown
相关产品推荐
相关产品推荐

