*/ private const NON_PUBLIC_RANGES = [ '192.0.2.0/24', // TEST-NET-1 (RFC 5737) '198.51.100.0/24', // TEST-NET-2 (RFC 5737) '203.0.113.0/24', // TEST-NET-3 (RFC 5737) '100.64.0.0/10', // Carrier-Grade NAT (RFC 6598) '224.0.0.0/4', // Multicast ]; /** @return array */ public function run(?string $endpoint = null): array { $endpoint ??= ProvisioningSettings::wgEndpoint(); if (blank($endpoint)) { return ['ok' => false, 'reason' => 'missing']; } if (! str_contains($endpoint, ':')) { return ['ok' => false, 'reason' => 'no_port']; } $host = Str::beforeLast($endpoint, ':'); // No valid IP means: a name. It can resolve publicly, and guessing // here would be worse than letting it through — the check states what // it knows, not what it suspects. if (! filter_var($host, FILTER_VALIDATE_IP)) { return ['ok' => true, 'reason' => 'hostname', 'address' => $host]; } // NO_PRIV_RANGE covers RFC 1918, NO_RES_RANGE covers loopback and // link-local among others — exactly the private address that stood // at one host on 2026-07-30. $public = filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); if ($public === false || $this->isKnownNonPublicRange($host)) { return ['ok' => false, 'reason' => 'not_public', 'address' => $host]; } return ['ok' => true, 'reason' => 'public', 'address' => $host]; } private function isKnownNonPublicRange(string $ip): bool { if (! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { return false; } $long = ip2long($ip); foreach (self::NON_PUBLIC_RANGES as $cidr) { [$subnet, $bits] = explode('/', $cidr); $mask = -1 << (32 - (int) $bits); if (($long & $mask) === (ip2long($subnet) & $mask)) { return true; } } return false; } }