cboxdk / laravel-dns
Laravel integration for cboxdk/dns — authoritative DNS lookups, domain-ownership verification, DNSSEC validation, and intoDNS/MxToolbox-style diagnostics via a facade, Artisan commands, and validation rules.
Requires
- php: ^8.4
- cboxdk/dns: ^0.1
- illuminate/console: ^12.0 || ^13.0
- illuminate/contracts: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^3.5 || ^4.0
- pestphp/pest-plugin-laravel: ^3.0 || ^4.0
README
The DNS toolkit for Laravel: authoritative lookups, domain-ownership verification, DNSSEC validation, and intoDNS/MxToolbox-style diagnostics — exposed through a facade, Artisan commands, and validation rules.
This package is the Laravel integration for the framework-agnostic
cboxdk/dns engine. The DNS protocol handling,
verification, propagation, SPF/DMARC parsing, and DNSSEC chain validation all live
in that core library; this package wires it into the container, config, the
console, and the validator so it is one composer require away in a Laravel app.
Installation
composer require cboxdk/laravel-dns
The service provider is auto-discovered. Publish the config if you want to tune the resolver:
php artisan vendor:publish --tag="dns-config"
It works with zero configuration out of the box (a raw UDP/TCP socket resolver
against 1.1.1.1).
Configuration
config/dns.php:
| Key | Env | Default | Purpose |
|---|---|---|---|
resolver |
DNS_RESOLVER |
socket |
Transport: socket (raw UDP/TCP) or doh (DNS-over-HTTPS JSON). |
nameserver |
DNS_NAMESERVER |
1.1.1.1 |
Recursive resolver for the socket transport. |
timeout |
DNS_TIMEOUT |
3.0 |
Per-query timeout, seconds. |
doh_endpoint |
DNS_DOH_ENDPOINT |
https://dns.google/resolve |
JSON DoH endpoint when resolver=doh. |
challenge_prefix |
DNS_CHALLENGE_PREFIX |
_cbox-challenge |
Label for ownership-verification TXT records. |
allow_non_public_nameservers |
DNS_ALLOW_NON_PUBLIC_NAMESERVERS |
false |
Lifts the SSRF filter on authoritative reads. Local testing only. |
The
sockettransport can target a zone's own authoritative nameservers, which domain-ownership verification and propagation checks require. Thedohtransport only queries a provider's recursive resolver, so it cannot answer authoritative or propagation queries.
Facade
use Cbox\LaravelDns\Facades\Dns; use Cbox\Dns\Enums\RecordType; $response = Dns::lookup('example.com', RecordType::MX); $response->values(); // ['mail.example.com'] Dns::verifyDomain('example.com', $token); // bool — read authoritatively Dns::challengeHost('example.com'); // '_cbox-challenge.example.com' $report = Dns::diagnose('example.com'); // Cbox\Dns\Diagnostics\Report $report->hasErrors(); Dns::dnssec()->validate('example.com'); // Cbox\Dns\Dnssec\ValidationResult
You can also inject the core types directly — the container binds both
Cbox\Dns\Dns and the Cbox\Dns\Contracts\Resolver contract:
public function __construct(private \Cbox\Dns\Dns $dns) {}
Artisan commands
php artisan dns:lookup example.com MX # table of records php artisan dns:verify example.com <token> # ownership challenge + result php artisan dns:diagnose example.com # grouped findings, non-zero exit on errors php artisan dns:propagation www.example.com A example.com [--all] php artisan dns:dnssec example.com # secure / insecure / bogus + reason
Validation rules
use Cbox\LaravelDns\Rules\DnsRecordExists; use Cbox\LaravelDns\Rules\DomainVerified; use Cbox\Dns\Enums\RecordType; $request->validate([ 'mail_domain' => ['required', new DnsRecordExists(RecordType::MX)], 'domain' => ['required', new DomainVerified($team->dns_token)], ]);
DnsRecordExists fails when the value resolves no record of the given type;
DomainVerified fails unless the value publishes the challenge token in its
authoritative TXT record.
Testing
Compose InteractsWithDns into your host application's TestCase to stub records
and assert with zero network I/O:
use Cbox\LaravelDns\Testing\InteractsWithDns; use Cbox\Dns\Enums\RecordType; $this->fakeDns()->stub('example.com', RecordType::MX, ['mail.example.com']); Dns::lookup('example.com', RecordType::MX)->values(); // ['mail.example.com']
fakeDns() swaps the container's resolver and Dns bindings for an in-memory
fake, so the facade, commands, and validation rules all resolve stubbed records.
Requirements
- PHP 8.4+
- Laravel 12.x or 13.x
The DNS engine
All DNS behaviour is provided by cboxdk/dns —
including the spoofing-resistant resolver, the SSRF-guarded authoritative reader,
SPF/DMARC/CAA parsing, and DNSSEC chain validation against the IANA root trust
anchors. This package claims only the Laravel integration.
Documentation
Full documentation lives in docs/.
Credits
License
The MIT License (MIT). See LICENSE.md.