Domain Detective is a domain, DNS, and email security auditing toolkit.
What we deliver today:
- C# library: compose and automate checks in .NET
- PowerShell module: fast, scriptable cmdlets with sensible aliases
- Cross‑platform CLI: quick interactive and batch workflows (Windows/macOS/Linux)
Why: enable offline, automatable versions of the tools you usually find on the web — repeatable, script‑friendly and ready for CI/CD or air‑gapped environments.
DNS & Infrastructure
- NS, SOA, Delegation, zone transfer checks
- MX, PTR/Reverse, FCrDNS
- DNSSEC: chain and DS validation
- TTL analysis; wildcard detection; EDNS support; open resolver
- DNS propagation (ad‑hoc + background monitor)
Email Authentication & Transport
- SPF: chain traversal and flattening; DNS‑lookup budget; terminal policy (-all); trailing content; null/exists lookups; macro validation (RFC 7208).
- DKIM: key presence and length, weak/old keys; canonicalization/hash checks; deprecated tags; per‑selector analysis (RFC 6376/8617 for ARC where applicable).
- DMARC: policy and alignment, pct/sp modes, rua/ruf parsing, aggregate/forensic import (RFC 7489 / dmarcbis draft).
- BIMI: record presence and logo/VMC hints (draft spec).
- MTA‑STS and TLS‑RPT: policy retrieval/validation and reporting posture (RFC 8461 / RFC 8460).
- Transport posture: SMTP STARTTLS, SMTP banner RFC‑conformance, IMAP/POP3 TLS, open relay checks, mail latency.
Web & Certificates
- HTTPS reachability (HTTP/2/3), enforced HTTPS redirects, forms over HTTPS, mixed‑content flags.
- Security headers posture: HSTS, CSP, Referrer‑Policy, Permissions‑Policy, X‑Frame‑Options and more.
- Certificate insights: chain/issuer/CT presence, key algorithm/size, weak/SHA‑1 flags, OCSP stapling; optional DANE/TLSA; S/MIMEA.
Static Website Scan
- Crawl starting URL, follow in‑scope links, and map redirect chains.
- Detect broken links/resources (first‑party vs third‑party) and mixed content.
- Surface missing/weak headers (CSP, HSTS, Referrer‑Policy, etc.).
- Third‑party inventory; top‑by‑bytes/requests; simple tracker/analytics detection.
- Lightweight technology fingerprinting from headers/body (no headless browser required).
- Robots.txt and sitemap hints to guide or explain coverage.
Reputation, Registry & Routing
- Threat intel hooks and feed ingestion (configurable), VirusTotal helpers.
- DNSBL lookups with customizable provider lists (domain/IP modes).
- WHOIS and RDAP (RFC 9083) for registration data.
- RPKI origin validation (route/origin hygiene).
Discovery, Exposure & Identity
- Autodiscover (mail client setup), Security.txt, Contact TXT.
- Directory exposure checks (well‑known paths/leaks).
- Identity provider info (OIDC discovery / user realm hints).
Infrastructure Hygiene
- Dangling/Takeover‑prone CNAMEs, flattening service detection.
- Subdomain enumeration, IP neighbor analysis.
- Reverse DNS/FCrDNS consistency, wildcard DNS detection.
Network Services
- Port availability and lightweight port scan profiles.
- SNMP and NTP posture checks.
Reporting & UX
- HTML and JSON reports, interactive CLI wizard, PowerShell views
- Offline‑first: make common online tools available locally, safely and repeatably.
- Automation‑ready: clean models, stable outputs, designed for scripting and CI/CD.
- Cross‑platform: consistent experience on Windows, macOS and Linux.
- Extensible: C# SDK + PowerShell + CLI, with provider hooks.
- Raw: strongly‑typed analysis models suitable for automation and downstream processing (
view.Raw
). - Narrative: persona‑driven, human‑friendly storyline in CLI/PowerShell (without polluting the raw data).
- Highlights: concise status, counts and key flags for dashboards and at‑a‑glance summaries.
These layers are available both from the CLI and PowerShell; use summaries for quick triage and drill into raw for evidence and provenance.
- SPF: RFC 7208 • DKIM: RFC 6376 • ARC: RFC 8617
- DMARC: RFC 7489 (plus dmarcbis draft) • BIMI (draft)
- MTA‑STS: RFC 8461 • TLS‑RPT: RFC 8460
- DANE/TLSA: RFC 6698 • SMIMEA: RFC 8162
- HSTS: RFC 6797 • EDNS(0): RFC 6891 • RDAP: RFC 9083
- Exports: Word (.docx), Excel (.xlsx), PDF, Markdown summaries.
- CLI packaging for Windows, macOS and Linux (single‑file and native package feeds).
- Live persona narration across CLI/PowerShell with per‑section highlights.
- More opinionated presets and batch modes for scheduled audits.
We’re designing persona‑driven narratives to present findings in different tones (e.g., business, geek) without changing the underlying data. Live streaming of persona output and per‑section summaries are part of the roadmap. The raw objects and reports remain clean and automation‑friendly.
Prefixed Name | Alias Name | Purpose |
---|---|---|
Test-DDEmailArcRecord |
Test-EmailArc |
Validate ARC headers |
Test-DDEmailAutoDiscover |
Test-EmailAutoDiscover |
Check mail client discovery |
Test-DDEmailBimiRecord |
Test-EmailBimi |
Verify BIMI record |
Test-DDEmailDkimRecord |
Test-EmailDkim |
Verify DKIM selectors |
Test-DDEmailDmarcRecord |
Test-EmailDmarc |
Verify DMARC policy |
Test-DDEmailSpfRecord |
Test-EmailSpf |
Verify SPF policy |
Test-DDEmailTlsRptRecord |
Test-EmailTlsRpt |
Inspect TLS-RPT |
Test-DDEmailStartTls |
Test-EmailStartTls |
Check STARTTLS advertisement |
Test-DDEmailSmtpTls |
Test-EmailSmtpTls |
Check SMTP TLS posture |
Test-DDEmailOpenRelay |
Test-EmailOpenRelay |
Detect open SMTP relay |
Get-DDEmailMessageHeaderInfo |
Get-EmailHeaderInfo |
Parse raw email headers |
Test-DDEmailLatency |
Test-EmailLatency |
Measure SMTP responsiveness |
Test-DDEmailImapTls |
Test-EmailImapTls |
IMAP TLS check |
Test-DDEmailPop3Tls |
Test-EmailPop3Tls |
POP3 TLS check |
Test-DDEmailSmtpBanner |
Test-EmailSmtpBanner |
Inspect SMTP banner |
Test-DDDmarcAggregate |
Test-EmailDmarcAggregate |
Parse DMARC aggregate reports |
New-DDDmarcRecord |
New-DmarcRecord |
Build DMARC record |
Prefixed Name | Alias Name | Purpose |
---|---|---|
Test-DDWebsite |
Test-Website |
Combined website check (cert + HTTPS security) |
Test-DDWebsiteSecurity |
Test-WebsiteSecurity |
HTTPS security headers + mixed content |
Test-DDDomainCertificate |
Test-DomainCertificate |
Website certificate incl. TLS grade |
Prefixed Name | Alias Name | Purpose |
---|---|---|
Test-DDDnsCaaRecord |
Test-DnsCaa |
Verify CAA |
Test-DDDnsNsRecord |
Test-DnsNs |
Verify NS |
Test-DDDnsSoaRecord |
Test-DnsSoa |
Verify SOA |
Test-DDDnsSecStatus |
Test-DnsSec |
Verify DNSSEC |
Test-DDDnsBlacklist |
Test-DnsBlacklist |
Check DNSBL (domain + MX IPs) |
Test-DDMailDomainClassification |
Classify sending/receiving/parked + signals | |
Test-DDDnsOpenResolver |
Test-DnsOpenResolver |
Detect open resolver |
Test-DDDnsDanglingCname |
Test-DnsDanglingCname |
Find dangling CNAME |
Test-DDDnsPropagation |
Test-DnsPropagation |
Check global propagation |
Start-DDDnsPropagationMonitor |
Start-DnsPropagationMonitor |
Background propagation monitor |
Stop-DDDnsPropagationMonitor |
Stop-DnsPropagationMonitor |
Stop propagation monitor |
Test-DDDnsTtl |
Test-DnsTtl |
TTL analysis |
Test-DDDnsTunneling |
Test-DnsTunneling |
Detect DNS tunneling (logs) |
Test-DDDnsWildcard |
Test-DnsWildcard |
Detect wildcard catch-all |
Test-DDDnsEdnsSupport |
Test-DnsEdnsSupport |
EDNS support |
Test-DDDnsHealth |
Test-DnsHealth |
Authoritative SOA/apex/TTL consistency |
Test-DDDnsSmimeaRecord |
Test-DnsSmimea |
S/MIMEA |
Test-DDDnsForwardReverse |
Test-DnsFcrDns |
FCrDNS |
Test-DDDnsMxRecord |
Test-DnsMx |
MX records |
Test-DDDnsDelegation |
Test-DnsDelegation |
Parent NS/glue consistency |
Test-DDDnsReverseDns |
Test-DnsReverseDns |
Reverse DNS |
Test-DDDnsZoneTransfer |
Test-DnsZoneTransfer |
AXFR exposure |
Prefixed Name | Alias Name | Purpose |
---|---|---|
Test-DDDomainContactRecord |
Test-DomainContact |
WHOIS contact sanity |
Test-DDDomainSecurityTxt |
Test-DomainSecurityTxt |
security.txt checks |
Test-DDDomainCertificate |
Test-DomainCertificate |
Website certificate checks |
Test-DDDomainOverallHealth |
Test-DomainHealth |
Composite health; returns a View (with Raw), supports -Export* |
Get-DDDomainWhois |
Get-DomainWhois |
WHOIS |
Get-DDDomainFlattenedSpfIp |
Get-DomainFlattenedSpfIp |
Flatten SPF to IPs |
Test-DDDomainThreatIntel |
Test-DomainThreatIntel |
Threat intel lookups |
Get-DDRdap |
Get-Rdap |
RDAP |
Get-DDRdapObject |
Get-RdapObject |
RDAP raw object |
Get-DDSearchEngineInfo |
Get-SearchEngineInfo |
Search engine queries |
Prefixed Name | Alias Name | Purpose |
---|---|---|
Test-DDTlsDaneRecord |
Test-TlsDane |
DANE/TLSA |
Get-DDTlsCertificateInfo |
Get-CertificateInfo |
Parse PEM/DER certs |
Test-DDNetworkIpNeighbor |
Test-NetworkIpNeighbor |
IP neighbors (add -IncludeMX for mail IPs) |
Test-DDNetworkPortAvailability |
Test-NetworkPortAvailability |
Port scanning |
Prefixed Name | Alias Name | Purpose |
---|---|---|
Add-DDDnsblProvider |
Add-DnsblProvider |
Manage DNSBL |
Remove-DDDnsblProvider |
Remove-DnsblProvider |
Manage DNSBL |
Clear-DDDnsblProviderList |
Clear-DnsblProvider |
Manage DNSBL |
Import-DDDnsblConfig |
Import-DnsblConfig |
Manage DNSBL |
Import-DDDmarcReport |
Import-DmarcReport |
DMARC aggregate zip |
Import-DDDmarcForensic |
Import-DmarcForensic |
DMARC forensic zip |
Import-DDEmailTlsRpt |
Import-EmailTlsRpt |
TLS-RPT JSON |
- Compose any mix via pipeline:
Import-Module ./Module/DomainDetective.psd1 -Force
$spf = Test-DDEmailSpfRecord -DomainName 'evotec.pl'
$dnsbl = Test-DDDnsBlacklist -NameOrIpAddress 'evotec.pl'
($spf + $dnsbl) | Export-DDSecurityReport -Scope Detailed -ExportFormat Word -ExportPath .\\Reports -OpenReport
- Or inline with a script block:
Import-Module ./Module/DomainDetective.psd1 -Force
Export-DDSecurityReport -Scope Detailed -ExportFormat Word -ExportPath .\\Reports -OpenReport -Compose {
Test-DDEmailSpfRecord -DomainName 'evotec.pl'
Test-DDDnsBlacklist -NameOrIpAddress 'evotec.xyz'
Test-DDMailDomainClassification -DomainName 'evotec.pl'
}
-
Metadata overrides (PowerShell):
- Set defaults once:
Set-DDExportOptions -Title "Evotec — Q3 Portfolio Review" -Subject "Executive summary and remediation plan" -Category "Email Security" -Keywords "SPF,DKIM,DMARC" -Creator "Evotec"
- Or per-call:
Export-DDSecurityReport -ExportFormat Word -Title "Evotec — MX Review" -Subject "MX and transport policies"
- Set defaults once:
-
Notes:
- The Word header shows the generated timestamp; company branding can be applied via export options.
- Executive Summary → Overview includes the domain count and total warnings/errors across all domains.
DNSBL lists used for blacklist checks can be customized. DNSBLAnalysis
comes with a built-in list, but you can modify it at runtime. Each list entry exposes Domain
, Enabled
, and Comment
fields. Use the following methods on DNSBLAnalysis
to manage the list:
AddDNSBL
/AddDNSBL(IEnumerable<string>)
RemoveDNSBL
ClearDNSBL
LoadDNSBL
You can load a custom list from a file using LoadDNSBL
. Additionally, JSON files describing DNSBL providers can be imported with ImportDnsblConfig
.
Flags and knobs:
-TreatAsDomain
: Force domain-mode (domain lists + MX IPs) even if input looks like an IP.-TreatAsIp
: Force IP-mode (only IP DNSBLs). Fails if input is not a valid IP.-MaxConcurrency
: Hint to the resolver to cap concurrency (applied if supported by the underlying DNS client).-BlacklistedOnly
: Filter output to only entries that are actually listed.
Example usage in C#:
var analysis = new DNSBLAnalysis();
// add a provider
analysis.AddDNSBL("dnsbl.example.com", comment: "custom");
// remove a provider
analysis.RemoveDNSBL("dnsbl.example.com");
// clear all configured providers
analysis.ClearDNSBL();
// load providers from JSON configuration
analysis.LoadDnsblConfig("DnsblProviders.json", overwriteExisting: true);
Same actions are available from PowerShell using dedicated cmdlets:
Add-DnsblProvider -Domain 'dnsbl.example.com' -Comment 'custom'
Remove-DnsblProvider -Domain 'dnsbl.example.com'
Clear-DnsblProvider
Import-DnsblConfig -Path './DnsblProviders.json' -OverwriteExisting
VerifyWebsiteCertificate
can be called with or without a URL scheme. When the scheme is omitted, https://
is used automatically before checking the certificate.
The CertificateAnalysis
result now includes:
KeyAlgorithm
andKeySize
for the leaf certificate.WeakKey
when the key is under 2048 bits.Sha1Signature
when the certificate uses SHA‑1.IsSelfSigned
when the certificate subject equals the issuer and the chain length is one.- With
CaptureTlsDetails
enabled,TlsProtocol
,CipherAlgorithm
andCipherStrength
describe the negotiated cipher-suite. PresentInCtLogs
when the certificate appears in public CT logs.CtLogApiTemplates
allows customizing the list of CT log APIs queried.SkipRevocation
disables CRL and OCSP checks. Use with care as revoked certificates may appear valid.
PowerShell users can run a combined check returning a single WebsiteInfo
object:
Test-Website -DomainName evotec.xyz | Select-Object Area,Check,Status,Summary,CertificateGrade,HttpGrade
This aggregates CertificateInfo
and HttpInfo
with grades, HSTS presence, and mixed-content flag.
DkimRecordAnalysis
exposes several indicators:
WeakKey
when the RSA key is under 2048 bits.OldKey
when the creation date is over 12 months old.DeprecatedTags
listing tags such asg
orh=sha1
.
SMTPTLSAnalysis
now stores the negotiated certificate and reports expiration
details and chain validity for each server.
HttpAnalysis.DefaultSecurityHeaders
lists security headers that are inspected when header collection is enabled. The list includes Content-Security-Policy
, Referrer-Policy
, X-Frame-Options
, Permissions-Policy
, Origin-Agent-Cluster
and several Cross-Origin policies. You can modify the list to capture additional headers.
HttpAnalysis
also sets HstsPreloaded
when the host is found in the bundled HSTS preload list.
Each HTTP check also computes a coarse Grade
(A–F) summarizing header posture and mixed-content. See Test-WebsiteSecurity
and Test-Website
.
Use the .NET SDK to restore dependencies, build the solution and execute tests:
dotnet restore
dotnet build DomainDetective.sln
dotnet test DomainDetective.Tests/DomainDetective.Tests.csproj
PowerShell specific tests can be run with:
pwsh ./Module/DomainDetective.Tests.ps1
RPKI validation in C#:
var hc = new DomainHealthCheck();
await hc.VerifyRPKI("example.com");
foreach (var r in hc.RpkiAnalysis.Results)
Console.WriteLine($"{r.IpAddress} {r.Asn} {r.Valid}");
Import the module and call any of the testing cmdlets:
Import-Module ./Module/DomainDetective.psd1 -Force
Test-EmailSpf -DomainName "example.com"
Test-EmailAutoDiscover -DomainName "example.com"
Test-DnsFcrDns -DomainName "example.com"
By default, all DNS-related cmdlets use the system DNS resolver. You can specify a different endpoint with the -DnsEndpoint parameter when needed.
Analyze TTL values:
Test-DnsTtl -DomainName "example.com"
Get concise summaries (Area/Check/Status/Summary) for views returned by cmdlets:
Get-DDApexAddressInfo -DomainName "example.com" | Select-Object Area,Check,Status,Summary
Check wildcard DNS:
Test-DnsWildcard -DomainName "example.com"
Check EDNS support:
Test-DnsEdnsSupport -DomainName "example.com"
Query an S/MIMEA record:
Test-DnsSmimea -EmailAddress "[email protected]"
Analyze ARC headers from PowerShell:
Get-Content './headers.txt' -Raw | Test-EmailArc
Validate RPKI origins:
Test-Rpki -DomainName "example.com"
Run the example project and CLI scenarios:
dotnet run --project DomainDetective.Example example.com --json
ddcli example.com --checks autodiscover
ddcli example.com --subdomain-policy
ddcli example.com --checks fcrdns
ddcli TestSMIMEA [email protected]
ddcli DnsPropagation --domain example.com --record-type A
ddcli example.com --check-web
ddcli example.com --checks DNSHEALTH
#### SPF host simulation
ddcli SpfTestHost example.com --ip 192.0.2.10 --sender [email protected] --json
IdP tenant hints in C#:
```csharp
var hc = new DomainHealthCheck();
await hc.VerifyIdpInfo("example.com");
var idp = hc.IdpInfoAnalysis;
Console.WriteLine($"Tenant: {idp.TenantId}, Namespace: {idp.NameSpaceType}, FederatedAuthUrl: {idp.FederatedAuthUrl}");
DMARC aggregate enrichment and summaries in C#:
var paths = Directory.GetFiles("./reports", "*.xml");
var reports = paths.Select(p => DmarcReportParser.Parse(p)).ToList();
// Enrich records with ASN and country
await DmarcAggregateEnrichment.EnrichAsync(reports.SelectMany(r => r.Records));
// Reporter summary
var pairs = reports.SelectMany(r => r.Records.Select(rec => (Report: r, Record: rec)));
var byReporter = pairs.SummarizeFailuresByReporter().OrderByDescending(x => x.Count);
// By ASN
var all = reports.SelectMany(r => r.Records);
var byAsn = all.SummarizeFailuresByAsn().OrderByDescending(x => x.Count);
// By Country
var byCountry = all.SummarizeFailuresByCountry().OrderByDescending(x => x.Count);
Returns a verdict (pass/fail/softfail/neutral/permerror), the matched token/type and the include/redirect chain that led to the match.
### CLI wizard
```bash
ddcli
Guides you through domain entry, check selection, and JSON vs summary output. For web-focused checks from CLI:
ddcli example.com --check-web
ddcli example.com --checks DNSHEALTH
ddcli AnalyzeMessageHeader --file ./headers.txt --json
ddcli AnalyzeARC --file ./headers.txt --json
# List recent runs from artifacts index
ddcli RunsList --subject example.com --count 5
# Open the most recent run (scan.json or directory)
ddcli RunsOpen --subject example.com
- Dns endpoint: most cmdlets accept
-DnsEndpoint
to control resolution. - Scope selection: DNS propagation supports
-Country
,-Location
,-Take
and background monitor with start/stop cmdlets. - Snapshots and diffs:
-SnapshotPath
and-Diff
compare against stored snapshots. - Output formats: report tooling supports HTML/Word/Excel/PDF/JSON (work-in-progress where noted).
If you don't need to automate the process, or if you just want to quickly query for your domain name, you can use the following web based tools:
This project uses GitHub Actions to run .NET and PowerShell tests on Windows, Linux and macOS. Code coverage results are published to Codecov.
Project status: pre-release; some checks are under active development. For gaps and current limitations see issues: https://github.com/EvotecIT/DomainDetective/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen
We welcome feedback, PRs, and ideas to improve coverage and reporting.
Each analysis type returns an object exposing properties that map to fields described in the relevant RFCs. For example, SPF checks follow RFC 7208 and DMARC analysis references RFC 7489. DKIM validations follow RFC 6376 and enforce RSA public keys of at least 1024 bits. DKIM analysis also sets WeakKey
when the RSA key is shorter than 2048 bits. DANE TLSA lookups follow RFC 6698. SMIMEA records are parsed according to RFC 8162.
Boolean fields indicate whether a particular requirement was met. You can inspect the object returned from DomainHealthCheck
or the PowerShell cmdlets to review these properties and make decisions in automation.
SpfAnalysis
exposes additional collections capturing every token discovered through nested include
and redirect
records. These Resolved*
lists mirror the top-level properties but aggregate results from the entire chain (for example ResolvedARecords
, ResolvedMxRecords
, ResolvedIpv4Records
and ResolvedIpv6Records
).
DNS lookup counting adheres to RFC 7208 Section 4.6.4. Queries caused by the include
, a
, mx
, ptr
, and exists
mechanisms as well as the redirect
modifier are tallied, and exceeding ten during evaluation sets ExceedsDnsLookups
.
WHOIS analysis surfaces the expiration date and whether the registrar lock is enabled. DomainSummary
exposes these fields so you can monitor upcoming renewals:
var health = new DomainHealthCheck();
await health.Verify("example.com");
var summary = health.BuildSummary();
Console.WriteLine($"Expires on: {summary.ExpiryDate}");
Console.WriteLine($"Registrar lock: {summary.RegistrarLocked}");
Console.WriteLine($"Is public suffix: {summary.IsPublicSuffix}");
WHOIS snapshots can be stored by specifying a snapshot directory when running the CLI or PowerShell cmdlet. Comparing the latest data to the previous snapshot highlights registrar changes. Querying once a day is typically sufficient for monitoring purposes and avoids unnecessary load on WHOIS servers.
Human-friendly descriptions for each health check are stored in CheckDescriptions.cs
. The CLI and any report generators look up a CheckDescription
by HealthCheckType
to display its summary, RFC link and remediation steps. You can extend or override these mappings by creating additional entries before generating output.