*/ protected static function resolve(string $host): array { if (filter_var($host, FILTER_VALIDATE_IP)) { return [$host]; } $ips = []; $records = @dns_get_record($host, DNS_A + DNS_AAAA); if ($records) { foreach ($records as $record) { if (! empty($record['ip'])) { $ips[] = $record['ip']; } elseif (! empty($record['ipv6'])) { $ips[] = $record['ipv6']; } } } if (empty($ips)) { $resolved = gethostbynamel($host); if ($resolved !== false) { $ips = $resolved; } } return $ips; } protected static function isPublicIp(string $ip): bool { if (! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return false; } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $long = ip2long($ip); $blockedRanges = [ ['127.0.0.0', '127.255.255.255'], // loopback ['169.254.0.0', '169.254.255.255'], // link-local + cloud metadata ['100.64.0.0', '100.127.255.255'], // CGNAT ['0.0.0.0', '0.255.255.255'], // "this" network ]; foreach ($blockedRanges as [$start, $end]) { if ($long >= ip2long($start) && $long <= ip2long($end)) { return false; } } } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $lower = strtolower($ip); if ($lower === '::1' || str_starts_with($lower, 'fe80') || str_starts_with($lower, 'fc') || str_starts_with($lower, 'fd')) { return false; } } return true; } }