A tool for auditing TLS certificates on DNS-over-TLS servers.
Analyzes TLS certificates on DoT servers (port 853). Resolves NS records for each domain, uses them as SNI during TLS handshake, and extracts certificate information.
- Automatic SNI selection from NS records
- Certificate analysis (CN, SAN, validity, chain trust, issuer)
- IP address validation (checks if connected IP is listed in certificate SAN IPs)
- Multiple output formats (verbose, markdown, JSON, HTML)
- Self-signed and expired certificate detection with visual highlighting
- Interactive HTML reports with DataTables (sorting, filtering, search)
- Per-column filtering in HTML output
- Concurrent processing with configurable workers
- Detailed certificate validation and chain trust verification
Requires Python 3.10 or later.
pip install dnspython cryptographypython3 dot_auditor.py input.csvThe CSV file should contain at least two columns: IP address and domain name.
Example input.csv:
45.55.10.200,powerdns.com
206.189.140.177,technitium.com
2604:a880:1:20::132:5001,powerdns.com
| Option | Description |
|---|---|
csv_file |
CSV file with IP and domain columns (required) |
--has-header |
Skip the first CSV row as header |
--delimiter |
CSV delimiter (default: ,) |
--ip-col |
Zero-based index of the IP column (default: 0) |
--domain-col |
Zero-based index of the domain column (default: 1) |
--port |
Port to check (default: 853) |
--timeout |
Timeout for DNS and TLS operations in seconds (default: 5.0) |
--workers |
Number of concurrent checks (default: 64) |
--format |
Output format: verbose, markdown, json, or html (default: verbose) |
-o, --output |
Output file path (default: stdout) |
Detailed human-readable output with all certificate information:
python3 dot_auditor.py input.csv --format=verbose=== 45.55.10.200 (powerdns.com) :853 ===
Matching NS hostname(s): pdns-public-ns2.powerdns.com
SNI used: pdns-public-ns2.powerdns.com
TLS: OK
Leaf certificate received: yes
CN(s):
- *.powerdns.com
SAN DNS:
- *.powerdns.com
- powerdns.com
Validity: 2025-01-15T12:00:00+00:00 -> 2026-01-15T12:00:00+00:00 (expired: False)
Issued by: Let's Encrypt (R12)
Self-signed: False
Chains to system CA: True
Connected IP listed in cert IP SANs: False
Formatted as a table for documentation and reports:
python3 dot_auditor.py input.csv --format=markdown| IP | Domain | SNI Used | Matching NS | TLS | Leaf Cert | Chain Trusted | IP in Cert | Expired | Self-Signed | Issued By | CN(s) | SAN DNS | SAN IPs |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
45.55.10.200 |
powerdns.com |
pdns-public-ns2.powerdns.com |
pdns-public-ns2.powerdns.com |
✅ | ✅ | ✅ | YES | NO | NO | Let's Encrypt (R12) |
*.powerdns.com |
*.powerdns.com, powerdns.com |
- |
Machine-readable structured output for automation:
python3 dot_auditor.py input.csv --format=json[
{
"ip": "45.55.10.200",
"domain": "powerdns.com",
"port": 853,
"matching_ns": ["pdns-public-ns2.powerdns.com"],
"sni_used": "pdns-public-ns2.powerdns.com",
"tls_ok": true,
"error_tls": null,
"leaf_cert_received": true,
"connected_ip": "45.55.10.200",
"not_before": "2025-01-15T12:00:00+00:00",
"not_after": "2026-01-15T12:00:00+00:00",
"is_expired": false,
"is_self_signed": false,
"issued_by_trusted_ca": true,
"issuer_cn": "Let's Encrypt (R12)",
"cn_list": ["*.powerdns.com"],
"san_dns": ["*.powerdns.com", "powerdns.com"],
"san_ips": [],
"connected_ip_in_cert": false
}
]Interactive HTML reports with DataTables integration for advanced filtering and sorting:
python3 dot_auditor.py input.csv --format=html -o report.htmlFeatures:
- Sortable columns: Click any column header to sort
- Global search: Filter across all columns at once
- Per-column filtering: Individual search boxes for each column
- Pagination: Navigate through large datasets (50 entries per page)
- Visual highlighting: Expired and self-signed certificates shown in red
- Column tooltips: Hover over column headers for descriptions
- Generation timestamp: UTC timestamp displayed at bottom of report
- Responsive design: Works on desktop and mobile browsers
The HTML output uses monospace fonts for technical data (IPs, domains, hostnames) and includes all certificate details in a clean, professional format.
Interactive features powered by DataTables - a powerful jQuery plugin for enhanced HTML tables.
Sample Reports: View live examples of HTML and Markdown output:
- Query NS records for the domain
- Resolve NS hostnames to find which matches the target IP
- Use matching NS hostname as SNI during TLS handshake
- Retrieve certificate and validate against system CA store
- Extract certificate details (CN, SAN, validity, chain trust)
- Audit DoT server certificate configurations
- Monitor certificate expiration
- Verify certificate chain trust
- Check for self-signed certificates
python3 dot_auditor.py public-dns-servers.csv --format=markdown -o audit-report.mdpython3 dot_auditor.py servers.csv --port=8853 --timeout=10.0 --workers=32python3 dot_auditor.py servers.csv --format=json -o results.jsonSee CONTRIBUTING.md for development setup, testing, and contribution guidelines.
This project relies on the following excellent open-source libraries:
- dnspython - DNS toolkit for Python
- cryptography - Cryptographic recipes and primitives
- DataTables - jQuery plugin for interactive HTML tables (used in HTML output)
This project is licensed under the BSD 2-Clause License - see the LICENSE file for details.