diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 6d7c312b8..461e7c266 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -2068,7 +2068,7 @@ function validateDNSEntry(string $fqdn, Server $server) $type = dnsRecordTypeForIp($ip) === 'AAAA' ? DNSTypes::NAME_AAAA : DNSTypes::NAME_A; foreach ($dns_servers as $dns_server) { try { - $query = new DNSQuery($dns_server); + $query = createDnsQuery($dns_server); $results = $query->query($host, $type); if ($results === false || $query->hasError()) { } else { @@ -2076,11 +2076,11 @@ function validateDNSEntry(string $fqdn, Server $server) if ($result->getType() == $type) { if (isCloudflareIp($result->getData())) { $found_matching_ip = true; - break; + break 2; } if ($ip && $result->getData() === $ip) { $found_matching_ip = true; - break; + break 2; } } } @@ -2092,6 +2092,15 @@ function validateDNSEntry(string $fqdn, Server $server) return $found_matching_ip; } +function createDnsQuery(string $dnsServer): DNSQuery +{ + return app()->make(DNSQuery::class, [ + 'server' => $dnsServer, + 'port' => 53, + 'timeout' => 5, + ]); +} + function isCloudflareIp(string $ip): bool { // https://www.cloudflare.com/ips/ diff --git a/tests/Feature/DnsValidationTest.php b/tests/Feature/DnsValidationTest.php new file mode 100644 index 000000000..aed8eb85c --- /dev/null +++ b/tests/Feature/DnsValidationTest.php @@ -0,0 +1,57 @@ + InstanceSettings::query()->updateOrCreate( + ['id' => 0], + [ + 'is_dns_validation_enabled' => true, + 'custom_dns_servers' => '192.0.2.1,192.0.2.2', + ] + )); + + $queriedServers = new ArrayObject; + $targetIp = '203.0.113.10'; + + app()->bind(DNSQuery::class, function ($app, array $parameters) use ($queriedServers, $resolvedIp) { + return new class($parameters['server'], $queriedServers, $resolvedIp) extends DNSQuery + { + public function __construct( + private readonly string $dnsServer, + private readonly ArrayObject $queriedServers, + private readonly string $resolvedIp, + ) { + parent::__construct($dnsServer); + } + + public function query(string $question, string $typeName = DNSTypes::NAME_A) + { + $this->queriedServers->append($this->dnsServer); + + return [new DNSResult($typeName, 1, 'IN', 60, $this->resolvedIp, $question, '', [])]; + } + + public function hasError(): bool + { + return false; + } + }; + }); + + $server = new Server(['ip' => $targetIp]); + $server->id = 1; + + expect(validateDNSEntry('https://example.com', $server))->toBeTrue() + ->and($queriedServers->getArrayCopy())->toBe(['192.0.2.1']); +})->with([ + 'target server IP' => '203.0.113.10', + 'Cloudflare IP' => '104.16.0.1', +]); diff --git a/tests/Unit/DnsQueryTimeoutTest.php b/tests/Unit/DnsQueryTimeoutTest.php new file mode 100644 index 000000000..ce0140a09 --- /dev/null +++ b/tests/Unit/DnsQueryTimeoutTest.php @@ -0,0 +1,10 @@ +getProperty('timeout')->getValue($query); + + expect($timeout)->toBe(5); +});