Add your description here
Project description
Nadzoring
An open source tool and python library for detecting website blocks, downdetecting and network analysis
Explore the docs »
Getting Started
·
Basic Usage
·
Pitchhut
·
Context7
·
Latest Documentation
·
License
Nadzoring (from Russian "надзор" — supervision/oversight + English "-ing" suffix) is a free and open-source command-line tool for detecting website blocks, monitoring service availability, and network analysis. It helps you investigate network connectivity issues, check if websites are accessible, analyze network configurations with comprehensive DNS diagnostics — including reverse DNS, DNS poisoning detection, ARP spoofing monitoring, SSL/TLS certificate analysis, HTTP security header auditing, email security validation (SPF/DKIM/DMARC), subdomain discovery, and much more.
Nadzoring is fully typed, has a zero-warnings linter policy, and is written according to SOLID, modularity, and SRP principles. It also has detailed documentation that is connected to Context7.
This utility has high-quality typing and a library API for use in your projects.
Table of Contents
- Nadzoring
- Getting Started
- Prerequisites
- Installation
- Usage
- Output Formats
- Saving Results
- Logging Levels
- Error Handling
- Python API
- Examples
- DNS Diagnostics
- Reverse DNS Batch Lookup
- DNS Poisoning Detection
- DNS Performance Benchmarking
- Port Scanning
- HTTP Service Probing
- SSL/TLS Certificate Auditing
- HTTP Security Header Auditing
- Email Security Validation
- Subdomain Discovery
- Continuous SSL Monitoring
- ARP Spoofing Detection
- Network Path Analysis
- Complete Network Diagnostics
- Automated DNS Server Monitoring
- Quick Website Block Check
- Contributing
- Documentation
- License & Support
Getting Started
Prerequisites
- Python 3.12+
- pip
Optional system utilities:
| Utility | Required by |
|---|---|
traceroute / tracepath |
network-base traceroute (Linux) |
whois |
network-base whois |
ip / route |
network-base params, network-base route |
net-tools |
network-base params on some Linux distros (sudo apt install net-tools) |
ss |
network-base connections (Linux) |
dig / nslookup |
security check-email (DNS TXT lookups; dnspython used when available) |
Installation
pip install nadzoring
Verify:
nadzoring --help
Development version:
pip install git+https://github.com/alexeev-prog/nadzoring.git
Usage
Nadzoring uses a hierarchical command structure: nadzoring <group> <command> [OPTIONS].
The four main groups are dns, network-base, security, and arp.
Global Options
These options work with every command:
| Option | Short | Description | Default |
|---|---|---|---|
--verbose |
Enable debug output with execution timing | False |
|
--quiet |
Suppress non-error output | False |
|
--no-color |
Disable colored output | False |
|
--output |
-o |
Output format: table, json, csv, html, html_table |
table |
--save |
Save results to file | None |
DNS Commands
dns resolve
Resolve DNS records for one or more domains.
nadzoring dns resolve [OPTIONS] DOMAINS...
| Option | Short | Description | Default |
|---|---|---|---|
--type |
-t |
Record type: A, AAAA, CNAME, MX, NS, TXT, ALL | A |
--nameserver |
-n |
Nameserver IP to use | System default |
--short |
Compact output | False |
|
--show-ttl |
Show TTL value | False |
|
--format-style |
Output style: standard, bind, host, dig | standard |
# A record lookup
nadzoring dns resolve google.com
# Multiple record types
nadzoring dns resolve -t MX -t TXT -t A example.com
# All record types with a specific nameserver
nadzoring dns resolve -t ALL -n 8.8.8.8 github.com
# Show TTL values
nadzoring dns resolve --show-ttl --type A cloudflare.com
Python API:
from nadzoring.dns_lookup.utils import resolve_with_timer
result = resolve_with_timer("example.com", "A")
if result["error"]:
# Possible values:
# "Domain does not exist" — NXDOMAIN
# "No A records" — record type not found
# "Query timeout" — nameserver did not respond
print("DNS error:", result["error"])
else:
print(result["records"]) # ['93.184.216.34']
print(result["response_time"]) # milliseconds
# With TTL and custom nameserver
result = resolve_with_timer(
"example.com", "MX",
nameserver="8.8.8.8",
include_ttl=True,
)
print(result["records"]) # ['10 mail.example.com']
print(result["ttl"]) # e.g. 3600
dns reverse
Perform reverse DNS lookups (PTR records) to find the hostname for an IP address.
nadzoring dns reverse [OPTIONS] IP_ADDRESSES...
| Option | Short | Description |
|---|---|---|
--nameserver |
-n |
Nameserver IP to use |
# Single IP
nadzoring dns reverse 8.8.8.8
# Multiple IPs
nadzoring dns reverse 1.1.1.1 8.8.8.8 9.9.9.9
# Use a specific nameserver
nadzoring dns reverse -n 208.67.222.222 8.8.4.4
# Save as JSON
nadzoring dns reverse -o json --save reverse_lookup.json 8.8.8.8 1.1.1.1
Python API:
from nadzoring.dns_lookup.reverse import reverse_dns
# IPv4 reverse lookup
result = reverse_dns("8.8.8.8")
if result["error"]:
# Possible values:
# "No PTR record" — IP has no reverse entry
# "No reverse DNS" — NXDOMAIN on reverse zone
# "Query timeout" — resolver timed out
# "Invalid IP address: …" — malformed input
print("Lookup failed:", result["error"])
else:
print(result["hostname"]) # 'dns.google'
print(result["response_time"]) # milliseconds
# IPv6 reverse lookup
result = reverse_dns("2001:4860:4860::8888")
print(result["hostname"]) # 'dns.google'
# Compact error-safe pattern
hostname = result["hostname"] or f"[{result['error']}]"
# Custom nameserver
result = reverse_dns("8.8.8.8", nameserver="1.1.1.1")
print(result["hostname"])
dns check
Perform a comprehensive DNS check including MX priority validation and SPF/DKIM analysis.
nadzoring dns check [OPTIONS] DOMAINS...
| Option | Short | Description | Default |
|---|---|---|---|
--nameserver |
-n |
Nameserver IP | System default |
--types |
-t |
Record types to check | ALL |
--validate-mx |
Validate MX priority uniqueness | False |
|
--validate-txt |
Validate SPF and DKIM TXT records | False |
# Full DNS check
nadzoring dns check example.com
# Check MX and TXT only with validation
nadzoring dns check -t MX -t TXT --validate-mx --validate-txt gmail.com
# Multiple domains
nadzoring dns check -n 9.9.9.9 google.com cloudflare.com
Python API:
from nadzoring.dns_lookup.health import check_dns
result = check_dns(
"example.com",
record_types=["MX", "TXT"],
validate_mx=True,
validate_txt=True,
)
print(result["records"]) # {'MX': ['10 mail.example.com']}
print(result["errors"]) # {'AAAA': 'No AAAA records'} — only failed types
print(result["response_times"]) # per-type timing in ms
print(result["validations"]) # {'mx': {'valid': True, 'issues': [], 'warnings': []}}
dns trace
Trace the complete DNS resolution delegation chain from root to authoritative nameserver.
nadzoring dns trace [OPTIONS] DOMAIN
| Option | Short | Description |
|---|---|---|
--nameserver |
-n |
Starting nameserver (default: root 198.41.0.4) |
# Trace from root servers
nadzoring dns trace example.com
# Start trace from a specific nameserver
nadzoring dns trace -n 8.8.8.8 google.com
# Verbose with timing
nadzoring dns trace -v github.com
Python API:
from nadzoring.dns_lookup.trace import trace_dns
result = trace_dns("example.com")
for hop in result["hops"]:
ns = hop["nameserver"]
rtt = f"{hop['response_time']} ms" if hop["response_time"] else "timeout"
err = f" ERROR: {hop['error']}" if hop.get("error") else ""
print(f" {ns} {rtt}{err}")
for rec in hop.get("records", []):
print(f" {rec}")
if result["final_answer"]:
print("Final answer:", result["final_answer"]["records"])
else:
print("No authoritative answer found")
dns compare
Compare DNS responses from multiple servers and detect discrepancies.
nadzoring dns compare [OPTIONS] DOMAIN
| Option | Short | Description | Default |
|---|---|---|---|
--servers |
-s |
DNS servers to compare | 8.8.8.8, 1.1.1.1, 9.9.9.9 |
--type |
-t |
Record types to compare | A |
# Compare A records across default servers
nadzoring dns compare example.com
# Compare MX records with custom servers
nadzoring dns compare -t MX -s 8.8.8.8 -s 208.67.222.222 -s 9.9.9.9 gmail.com
# Multiple record types
nadzoring dns compare -t A -t AAAA -t NS cloudflare.com
Python API:
from nadzoring.dns_lookup.compare import compare_dns_servers
result = compare_dns_servers(
"example.com",
servers=["8.8.8.8", "1.1.1.1", "9.9.9.9"],
record_types=["A", "MX"],
)
if not result["differences"]:
print("All servers agree")
else:
for diff in result["differences"]:
print(f"Server {diff['server']} — {diff['type']} mismatch")
print(f" Expected (baseline): {diff['expected']}")
print(f" Got: {diff['got']}")
if diff["ttl_difference"] is not None:
print(f" TTL delta: {diff['ttl_difference']}s")
dns health
Perform a scored DNS health check across all standard record types.
nadzoring dns health [OPTIONS] DOMAIN
| Option | Short | Description |
|---|---|---|
--nameserver |
-n |
Nameserver IP |
Health score: 80–100 = Healthy · 50–79 = Degraded · 0–49 = Unhealthy
nadzoring dns health example.com
nadzoring dns health -n 1.1.1.1 google.com
nadzoring dns health -o json --save health.json example.com
Python API:
from nadzoring.dns_lookup.health import health_check_dns
result = health_check_dns("example.com")
print(f"Score: {result['score']}/100")
print(f"Status: {result['status']}") # 'healthy' | 'degraded' | 'unhealthy'
for issue in result["issues"]:
print(" CRITICAL:", issue)
for warn in result["warnings"]:
print(" WARN:", warn)
for rtype, score in result["record_scores"].items():
print(f" {rtype}: {score}/100")
dns benchmark
Benchmark DNS server response times across multiple servers.
nadzoring dns benchmark [OPTIONS]
| Option | Short | Description | Default |
|---|---|---|---|
--domain |
-d |
Domain to query | google.com |
--servers |
-s |
Servers to benchmark | All public servers |
--type |
-t |
Record type | A |
--queries |
-q |
Queries per server | 10 |
--parallel/--sequential |
Run concurrently or one by one | parallel |
nadzoring dns benchmark
nadzoring dns benchmark -s 8.8.8.8 -s 1.1.1.1 -s 9.9.9.9 --queries 20
nadzoring dns benchmark -t MX -d gmail.com --sequential
nadzoring dns benchmark -o json --save benchmark.json
Python API:
from nadzoring.dns_lookup.benchmark import benchmark_dns_servers, benchmark_single_server
# Single server
result = benchmark_single_server("8.8.8.8", queries=10)
print(f"avg={result['avg_response_time']:.1f}ms success={result['success_rate']}%")
# Multiple servers — returned sorted fastest-first
results = benchmark_dns_servers(
servers=["8.8.8.8", "1.1.1.1", "9.9.9.9"],
queries=10,
parallel=True,
)
fastest = results[0]
print(f"Fastest: {fastest['server']} at {fastest['avg_response_time']:.1f}ms")
dns poisoning
Detect DNS poisoning, censorship, or unusual CDN routing for a domain.
nadzoring dns poisoning [OPTIONS] DOMAIN
| Option | Short | Description | Default |
|---|---|---|---|
--control-server |
-c |
Trusted control resolver | 8.8.8.8 |
--test-servers |
-t |
Servers to test against control | All public servers |
--type |
-T |
Record type | A |
--additional-types |
-a |
Extra record types from control server | None |
Severity levels: NONE → LOW → MEDIUM → HIGH → CRITICAL / SUSPICIOUS
nadzoring dns poisoning example.com
nadzoring dns poisoning -c 1.1.1.1 -a MX -a TXT google.com
nadzoring dns poisoning -o html --save poisoning_report.html twitter.com
Python API:
from nadzoring.dns_lookup.poisoning import check_dns_poisoning
result = check_dns_poisoning("example.com")
level = result.get("poisoning_level", "NONE")
confidence = result.get("confidence", 0.0)
print(f"Level: {level} Confidence: {confidence:.0f}%")
if result.get("poisoned"):
for inc in result.get("inconsistencies", []):
print("Inconsistency:", inc)
if result.get("cdn_detected"):
print(f"CDN: {result['cdn_owner']} ({result['cdn_percentage']:.0f}%)")
dns monitor
Continuously monitor DNS health and performance for a domain. Logs each cycle to a structured JSONL file and fires configurable alerts when response time or success rate thresholds are breached.
nadzoring dns monitor [OPTIONS] DOMAIN
| Option | Short | Description | Default |
|---|---|---|---|
--nameserver |
-n |
Nameserver to monitor (repeatable) | 8.8.8.8, 1.1.1.1 |
--interval |
Seconds between check cycles | 60 |
|
--cycles |
Number of cycles to run (0 = infinite) | 0 |
|
--max-rt |
Alert threshold: max response time (ms) | 300 |
|
--min-success |
Alert threshold: minimum success rate (0–1) | 0.95 |
|
--log-file |
Path to JSONL log file | None |
# Monitor with default servers, save log
nadzoring dns monitor example.com \
--interval 60 \
--log-file dns_monitor.jsonl
# Strict thresholds — alert above 150 ms or below 99 % success
nadzoring dns monitor example.com \
-n 8.8.8.8 -n 1.1.1.1 -n 9.9.9.9 \
--interval 30 \
--max-rt 150 --min-success 0.99 \
--log-file dns_monitor.jsonl
# Run exactly 10 cycles and save a JSON report (great for CI)
nadzoring dns monitor example.com --cycles 10 -o json --save report.json
# Quiet mode for cron / systemd
nadzoring dns monitor example.com \
--quiet --log-file /var/log/nadzoring/dns_monitor.jsonl
After Ctrl-C (or after --cycles completes), a statistical summary is printed automatically.
Python API:
from nadzoring.dns_lookup.monitor import AlertEvent, DNSMonitor, MonitorConfig
def my_alert_handler(alert: AlertEvent) -> None:
print(f"ALERT [{alert.alert_type}]: {alert.message}")
config = MonitorConfig(
domain="example.com",
nameservers=["8.8.8.8", "1.1.1.1"],
interval=60.0,
queries_per_sample=3,
max_response_time_ms=300.0,
min_success_rate=0.95,
log_file="dns_monitor.jsonl",
alert_callback=my_alert_handler,
)
monitor = DNSMonitor(config)
monitor.run()
print(monitor.report())
dns monitor-report
Analyse a JSONL log file produced by dns monitor.
nadzoring dns monitor-report [OPTIONS] LOG_FILE
nadzoring dns monitor-report dns_monitor.jsonl
nadzoring dns monitor-report dns_monitor.jsonl --server 8.8.8.8 -o json
Network Base Commands
ping
Check reachability using ICMP ping.
nadzoring network-base ping ADDRESSES...
nadzoring network-base ping 8.8.8.8
nadzoring network-base ping google.com cloudflare.com 1.1.1.1
nadzoring network-base ping -o json github.com
Python API:
from nadzoring.network_base.ping_address import ping_addr
print(ping_addr("8.8.8.8")) # True
print(ping_addr("https://google.com")) # True — URLs are normalised automatically
print(ping_addr("192.0.2.1")) # False — unreachable
# Note: ICMP may be blocked by firewalls even for reachable hosts
http-ping
Measure HTTP/HTTPS response timing and inspect headers.
nadzoring network-base http-ping [OPTIONS] URLS...
| Option | Description | Default |
|---|---|---|
--timeout |
Request timeout (seconds) | 10.0 |
--no-ssl-verify |
Disable SSL certificate check | False |
--no-redirects |
Do not follow redirects | False |
--show-headers |
Include response headers | False |
Output includes: DNS time, TTFB, total download time, status code, content size, redirects.
nadzoring network-base http-ping https://example.com
nadzoring network-base http-ping --show-headers https://github.com https://google.com
nadzoring network-base http-ping --timeout 5 --no-ssl-verify https://self-signed.badssl.com
nadzoring network-base http-ping -o csv --save http_metrics.csv https://api.github.com
Python API:
from nadzoring.network_base.http_ping import http_ping
result = http_ping("https://example.com", timeout=10.0, include_headers=True)
if result.error:
print("HTTP probe failed:", result.error)
else:
print(f"Status: {result.status_code}")
print(f"DNS: {result.dns_ms} ms")
print(f"TTFB: {result.ttfb_ms} ms")
print(f"Total: {result.total_ms} ms")
print(f"Size: {result.content_length} bytes")
if result.final_url:
print(f"Redirect → {result.final_url}")
host-to-ip
Resolve hostnames to IP addresses with IPv4/IPv6 availability checks.
nadzoring network-base host-to-ip HOSTNAMES...
nadzoring network-base host-to-ip google.com github.com cloudflare.com
nadzoring network-base host-to-ip -o csv --save resolutions.csv example.com
Python API:
from nadzoring.utils.validators import resolve_hostname
ip = resolve_hostname("example.com")
if ip is None:
print("Resolution failed")
else:
print(ip) # "93.184.216.34"
# Validate IP format before resolving
from nadzoring.utils.validators import validate_ip, validate_ipv4, validate_ipv6
validate_ip("8.8.8.8") # True
validate_ipv4("::1") # False
validate_ipv6("::1") # True
# Get router/gateway IP
from nadzoring.network_base.router_ip import router_ip
gateway = router_ip() # '192.168.1.1' on most home networks
gateway6 = router_ip(ipv6=True)
geolocation
Get geographic location for IP addresses.
nadzoring network-base geolocation IPS...
Output: latitude, longitude, country, city.
nadzoring network-base geolocation 8.8.8.8 1.1.1.1
nadzoring network-base geolocation --save locations.json 8.8.8.8
Python API:
from nadzoring.network_base.geolocation_ip import geo_ip
result = geo_ip("8.8.8.8")
if not result:
# Empty dict returned on failure (private IP, rate-limit, network error)
print("Geolocation unavailable")
else:
print(f"{result['city']}, {result['country']}")
print(f"Coordinates: {result['lat']}, {result['lon']}")
Note: ip-api.com rate-limits free callers to 45 requests per minute. Private/reserved IP addresses (e.g.
192.168.x.x) return an empty dict.
params
Show local network interface configuration.
nadzoring network-base params [OPTIONS]
Output: interface name, IPv4, IPv6, gateway IP, MAC address, public IP.
nadzoring network-base params
nadzoring network-base params -o json --save net_params.json
Python API:
from nadzoring.network_base.network_params import network_param
info = network_param()
print(info["IPv4 address"]) # '192.168.1.42'
print(info["Router ip-address"]) # '192.168.1.1'
print(info["MAC-address"]) # '00:11:22:33:44:55'
print(info["Public IP address"]) # your external IP
port-scan
Scan for open TCP/UDP ports on one or more targets.
nadzoring network-base port-scan [OPTIONS] TARGETS...
| Option | Description | Default |
|---|---|---|
--mode |
fast, full, or custom |
fast |
--ports |
Port list or range, e.g. 22,80,443 or 1-1024 |
None |
--protocol |
tcp or udp |
tcp |
--timeout |
Socket timeout (seconds) | 2.0 |
--workers |
Concurrent workers | 50 |
--no-banner |
Disable banner grabbing | False |
--show-closed |
Show closed ports | False |
Scan modes: fast = common ports · full = all 1–65535 · custom = your list or range.
nadzoring network-base port-scan example.com
nadzoring network-base port-scan --mode full 192.168.1.1
nadzoring network-base port-scan --mode custom --ports 22,80,443,8080 example.com
nadzoring network-base port-scan --protocol udp --mode fast example.com
nadzoring network-base port-scan -o json --save scan.json example.com
Python API:
from nadzoring.network_base.port_scanner import ScanConfig, scan_ports
config = ScanConfig(
targets=["example.com"],
mode="fast",
protocol="tcp",
timeout=2.0,
)
results = scan_ports(config)
for scan in results:
print(f"Target: {scan.target} ({scan.target_ip})")
print(f"Open ports: {scan.open_ports}")
for port in scan.open_ports:
r = scan.results[port]
print(f" {port}/tcp {r.service} {r.response_time}ms")
if r.banner:
print(f" Banner: {r.banner[:80]}")
port-service
Identify the service typically running on a port number.
nadzoring network-base port-service PORTS...
nadzoring network-base port-service 80 443 22 53 3306
nadzoring network-base port-service -o json 8080 5432 27017
Python API:
from nadzoring.network_base.service_on_port import get_service_on_port
print(get_service_on_port(80)) # 'http'
print(get_service_on_port(443)) # 'https'
print(get_service_on_port(22)) # 'ssh'
print(get_service_on_port(9999)) # 'unknown'
whois
Look up WHOIS registration data for domains or IP addresses.
Requires the system
whoisutility:
- Debian/Ubuntu:
sudo apt install whois- macOS:
brew install whois- RHEL/Fedora:
sudo dnf install whois
nadzoring network-base whois [OPTIONS] TARGETS...
nadzoring network-base whois example.com
nadzoring network-base whois google.com cloudflare.com 8.8.8.8
nadzoring network-base whois -o json --save whois_data.json github.com
Python API:
from nadzoring.network_base.whois import whois_lookup
result = whois_lookup("example.com")
print(result["registrar"]) # 'RESERVED-Internet Assigned Numbers Authority'
print(result["creation_date"]) # '1995-08-14T04:00:00Z'
print(result["expiry_date"])
print(result["name_servers"])
if result.get("error"):
print("Error:", result["error"]) # whois not installed, lookup failed, etc.
domain-info
Retrieve comprehensive information about a domain in a single call. Aggregates WHOIS registration data, DNS record lookups (A, AAAA, MX, NS, TXT), IP geolocation for the primary resolved address, and reverse DNS — all returned as a structured response.
nadzoring network-base domain-info [OPTIONS] DOMAINS...
nadzoring network-base domain-info example.com
nadzoring network-base domain-info google.com github.com cloudflare.com
nadzoring network-base domain-info -o json --save domain_report.json example.com
Python API:
from nadzoring.network_base.domain_info import get_domain_info
info = get_domain_info("example.com")
# WHOIS registration data
print(info["whois"]["registrar"])
print(info["whois"]["creation_date"])
print(info["whois"]["expiry_date"])
# Resolved IP addresses
print(info["dns"]["ipv4"]) # '93.184.216.34'
print(info["dns"]["ipv6"]) # '2606:2800:220:1:248:1893:25c8:1946'
# DNS records by type
for rtype, records in info["dns"]["records"].items():
print(f" {rtype}: {records}")
# Geolocation of the primary IP
geo = info["geolocation"]
if geo:
print(f"{geo['city']}, {geo['country']} ({geo['lat']}, {geo['lon']})")
# Reverse DNS for the primary IP
print(info["reverse_dns"]) # 'example.com' or None
connections
List active TCP/UDP network connections.
nadzoring network-base connections [OPTIONS]
| Option | Short | Description | Default |
|---|---|---|---|
--protocol |
-p |
Filter: tcp, udp, all |
all |
--state |
-s |
State filter substring, e.g. LISTEN |
None |
--no-process |
Skip PID/process info | False |
nadzoring network-base connections
nadzoring network-base connections --protocol tcp --state LISTEN
nadzoring network-base connections --protocol udp --no-process
nadzoring network-base connections -o csv --save connections.csv
Python API:
from nadzoring.network_base.connections import get_connections
# All connections
connections = get_connections()
# Listening TCP sockets only
listening = get_connections(protocol="tcp", state_filter="LISTEN")
for conn in listening:
print(conn.protocol, conn.local_address, conn.state, conn.process)
traceroute
Trace the network path to a host.
nadzoring network-base traceroute [OPTIONS] TARGETS...
| Option | Description | Default |
|---|---|---|
--max-hops |
Maximum hops | 30 |
--timeout |
Per-hop timeout (seconds) | 2.0 |
--sudo |
Run with sudo (Linux) | False |
Linux privilege note:
tracerouteneeds raw-socket access. Either use--sudo, run as root, or:sudo setcap cap_net_raw+ep $(which traceroute)Nadzoring automatically falls back totracepath(no root required) if traceroute fails.
nadzoring network-base traceroute google.com
nadzoring network-base traceroute --max-hops 20 github.com cloudflare.com
nadzoring network-base traceroute --sudo example.com
nadzoring network-base traceroute -o html --save trace.html 8.8.8.8
Python API:
from nadzoring.network_base.traceroute import traceroute
hops = traceroute("8.8.8.8", max_hops=15)
for hop in hops:
rtts = [f"{r}ms" if r else "*" for r in hop.rtt_ms]
print(f"{hop.hop:2} {hop.ip or '*':16} {' '.join(rtts)}")
route
Display the system IP routing table.
nadzoring network-base route [OPTIONS]
nadzoring network-base route
nadzoring network-base route -o json
nadzoring network-base route --save routing_table.json
Python API:
from nadzoring.network_base.route_table import get_route_table
routes = get_route_table()
for route in routes:
print(route.destination, "via", route.gateway, "dev", route.interface)
Security Commands
The security group provides SSL/TLS certificate inspection, HTTP security header auditing, email security record validation, subdomain discovery, and continuous certificate monitoring.
nadzoring security --help
security check-ssl
Inspect the SSL/TLS certificate for one or more domains. Checks expiry, issuer, subject, Subject Alternative Names, key strength, domain match, and which TLS protocol versions the server accepts (TLSv1.0 through TLSv1.3).
By default only a compact summary is shown. Use --full to see all fields including the complete SAN list, protocol details, chain length, and raw serial number.
nadzoring security check-ssl [OPTIONS] DOMAINS...
| Option | Short | Description | Default |
|---|---|---|---|
--days-before |
-d |
Days before expiry to flag as warning status |
7 |
--no-verify |
Disable certificate chain verification (falls back automatically) | False |
|
--full |
Show all certificate fields instead of compact summary | False |
Status values:
| Status | Meaning |
|---|---|
valid |
Certificate is valid and not near expiry |
warning |
Fewer than --days-before days remaining |
expired |
Certificate has already expired |
error |
Could not connect or parse the certificate |
# Basic check — compact summary table
nadzoring security check-ssl example.com
# Check multiple domains with a 30-day warning window
nadzoring security check-ssl --days-before 30 google.com github.com cloudflare.com
# Check without verifying the certificate chain (useful for self-signed certs)
nadzoring security check-ssl --no-verify internal.corp.example.com
# Full details including SAN list, protocol support, chain info
nadzoring security check-ssl --full ya.ru
# Save results as JSON for further processing
nadzoring security check-ssl -o json --save ssl_report.json example.com github.com
Python API:
from nadzoring.security.check_website_ssl_cert import (
check_ssl_certificate,
check_ssl_expiry,
check_ssl_expiry_with_fallback,
)
# Verified check (full certificate chain validation)
result = check_ssl_certificate("example.com", days_before=14)
print(result["status"]) # 'valid' | 'warning' | 'expired' | 'error'
print(result["remaining_days"]) # e.g. 142
print(result["expiry_date"]) # '2025-10-15T12:00:00+00:00'
print(result["verification"]) # 'verified' | 'unverified' | 'failed'
# Subject and issuer dicts
print(result["subject"]["CN"]) # 'example.com'
print(result["issuer"]["CN"]) # 'DigiCert TLS RSA SHA256 2020 CA1'
print(result["issuer"]["O"]) # 'DigiCert Inc'
# Subject Alternative Names
for san in result.get("san", []):
print(san) # 'DNS:example.com', 'DNS:www.example.com', ...
# Domain matching
print(result["domain_match"]) # True
print(result["matched_names"]) # ['DNS:example.com']
# Public key info
key = result["public_key"]
print(key["algorithm"]) # 'RSA' | 'EC' | 'Ed25519' | ...
print(key.get("key_size")) # 2048 (RSA/DSA)
print(key.get("curve")) # 'secp256r1' (EC)
print(key["strength"]) # 'weak' | 'good' | 'strong'
# Protocol support (TLSv1.0 – TLSv1.3)
protos = result["protocols"]
print(protos["supported"]) # ['TLSv1.2', 'TLSv1.3']
print(protos["has_outdated"]) # False
# Chain info (only when verify=True)
print(result.get("chain_length")) # 3
print(result.get("chain_valid")) # True
# Simplified expiry-only check
result = check_ssl_expiry("example.com")
# Automatic fallback to unverified mode if chain check fails
result = check_ssl_expiry_with_fallback("self-signed.badssl.com")
print(result["verification"]) # 'unverified' when fallback was used
security check-headers
Analyse the HTTP security headers returned by one or more URLs. Checks for the presence of eleven recommended headers, flags deprecated headers (e.g. X-XSS-Protection), identifies information-leaking headers (e.g. Server, X-Powered-By), and produces a 0–100 coverage score.
nadzoring security check-headers [OPTIONS] URLS...
| Option | Description | Default |
|---|---|---|
--timeout |
Request timeout in seconds | 10.0 |
--no-verify |
Disable SSL certificate verification | False |
Checked security headers:
| Header | Purpose |
|---|---|
Strict-Transport-Security |
Enforce HTTPS (HSTS) |
Content-Security-Policy |
Mitigate XSS and injection attacks |
X-Content-Type-Options |
Prevent MIME-type sniffing |
X-Frame-Options |
Prevent clickjacking |
X-XSS-Protection |
Legacy XSS filter (deprecated) |
Referrer-Policy |
Control referrer information leakage |
Permissions-Policy |
Restrict browser feature access |
Cross-Origin-Embedder-Policy |
Isolate cross-origin resources |
Cross-Origin-Opener-Policy |
Isolate browsing context |
Cross-Origin-Resource-Policy |
Control cross-origin resource sharing |
Cache-Control |
Prevent caching of sensitive responses |
# Check a single URL
nadzoring security check-headers https://example.com
# Check multiple URLs and save results
nadzoring security check-headers https://google.com https://github.com https://cloudflare.com
# Skip SSL verification for internal/self-signed endpoints
nadzoring security check-headers --no-verify https://internal.corp.example.com
# Export as JSON for CI integration or dashboards
nadzoring security check-headers -o json --save headers_audit.json https://example.com
# Adjust timeout for slow servers
nadzoring security check-headers --timeout 20 https://slow-api.example.com
Python API:
from nadzoring.security.http_headers import check_http_security_headers
result = check_http_security_headers("https://example.com", timeout=10.0)
print(result["url"]) # final URL after redirects
print(result["status_code"]) # 200
print(result["score"]) # 0–100 coverage score
# Present security headers
for header, value in result["present"].items():
print(f" ✓ {header}: {value}")
# Missing security headers
for header in result["missing"]:
print(f" ✗ {header}")
# Deprecated headers found in the response
for header in result["deprecated"]:
print(f" ⚠ deprecated: {header}")
# Information-leaking headers
for header, value in result["leaking"].items():
print(f" ⚠ leaking: {header} = {value}")
if result["error"]:
print("Request failed:", result["error"])
security check-email
Validate the email security configuration for one or more domains. Checks SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail) by probing common selectors, and DMARC (Domain-based Message Authentication, Reporting and Conformance). Returns structured findings including detected issues and an overall score.
Note: Requires
digornslookupto be available on the system, ordnspythoninstalled in the Python environment (pip install dnspython).dnspythonis preferred as it handles multi-chunk TXT records reliably.
nadzoring security check-email [OPTIONS] DOMAINS...
# Check a single domain
nadzoring security check-email gmail.com
# Check multiple domains at once
nadzoring security check-email google.com github.com cloudflare.com
# Export full JSON report
nadzoring security check-email -o json --save email_security.json example.com
# Quiet mode for scripting — results only, no progress bars
nadzoring security check-email --quiet example.com
Python API:
from nadzoring.security.email_security import check_email_security
result = check_email_security("example.com")
print(result["domain"])
# Overall score: 0 = none of SPF/DKIM/DMARC found, 3 = all found
print(result["overall_score"]) # e.g. 3
# SPF analysis
spf = result["spf"]
print(spf["found"]) # True
print(spf["record"]) # 'v=spf1 include:_spf.example.com ~all'
print(spf["mechanisms"]) # ['include:_spf.example.com']
print(spf["all_qualifier"]) # '~' (softfail — recommended minimum)
for issue in spf["issues"]:
print(" SPF issue:", issue)
# DKIM analysis
dkim = result["dkim"]
print(dkim["found"]) # True
print(dkim["selectors_checked"]) # list of 13 common selectors probed
for selector, record in dkim["records"].items():
print(f" DKIM selector '{selector}': {record[:60]}...")
for issue in dkim["issues"]:
print(" DKIM issue:", issue)
# DMARC analysis
dmarc = result["dmarc"]
print(dmarc["found"]) # True
print(dmarc["record"]) # 'v=DMARC1; p=reject; rua=mailto:...'
print(dmarc["policy"]) # 'none' | 'quarantine' | 'reject'
print(dmarc["subdomain_policy"]) # sp= tag value or None
print(dmarc["pct"]) # percentage of messages the policy applies to
print(dmarc["rua"]) # aggregate report addresses
print(dmarc["ruf"]) # forensic report addresses
for issue in dmarc["issues"]:
print(" DMARC issue:", issue)
# All issues aggregated across SPF + DKIM + DMARC
for issue in result["all_issues"]:
print("Issue:", issue)
Common issues reported:
| Category | Issue |
|---|---|
| SPF | No SPF record found |
| SPF | Multiple SPF records (RFC violation) |
| SPF | +all allows any sender (insecure) |
| SPF | Missing all mechanism |
| SPF | Exceeds 10 DNS lookup limit |
| DKIM | No DKIM records found for common selectors |
| DMARC | No DMARC record found |
| DMARC | Policy p=none does not protect against spoofing |
| DMARC | No aggregate report address (rua=) configured |
| DMARC | Policy applies to less than 100% of messages |
security subdomains
Discover subdomains for a target domain using two complementary methods: certificate transparency (CT) log queries via crt.sh and concurrent DNS brute-force using a built-in wordlist of 80+ common prefixes (or a custom wordlist file). Each result is tagged with its discovery source.
nadzoring security subdomains [OPTIONS] DOMAIN
| Option | Description | Default |
|---|---|---|
--wordlist |
Path to a custom wordlist file (one prefix per line) | Built-in 80+ prefix list |
--threads |
Number of concurrent DNS resolution threads | 20 |
--timeout |
Per-host DNS resolution timeout in seconds | 3.0 |
--no-bruteforce |
Skip DNS brute-force entirely, use CT logs only | False |
# Discover subdomains using CT logs + built-in wordlist
nadzoring security subdomains example.com
# CT logs only — no brute-force DNS
nadzoring security subdomains --no-bruteforce example.com
# Use a custom wordlist file
nadzoring security subdomains --wordlist /path/to/subdomains.txt example.com
# Increase concurrency and timeout for faster / more thorough scanning
nadzoring security subdomains --threads 50 --timeout 5 example.com
# Export results as JSON
nadzoring security subdomains -o json --save subdomains.json example.com
# Quiet mode for scripting
nadzoring security subdomains --quiet example.com
Python API:
from nadzoring.security.subdomain_scan import scan_subdomains
# CT logs + built-in wordlist brute-force
results = scan_subdomains("example.com", max_threads=20, timeout=3.0)
for r in results:
print(f"{r['subdomain']:40} {r['ip']:16} [{r['source']}]")
# CT logs only
results = scan_subdomains("example.com", wordlist_path="")
# Custom wordlist
results = scan_subdomains(
"example.com",
wordlist_path="/path/to/custom_wordlist.txt",
max_threads=50,
timeout=5.0,
)
# Source values: 'ct_log' | 'brute_force'
ct_found = [r for r in results if r["source"] == "ct_log"]
brute_found = [r for r in results if r["source"] == "brute_force"]
print(f"CT log: {len(ct_found)} Brute-force: {len(brute_found)}")
Built-in wordlist includes prefixes for:
common web services (www, mail, ftp, smtp), admin panels (admin, portal, cpanel, whm, plesk), APIs and apps (api, app, dev, staging, test, beta), infrastructure (vpn, proxy, lb, waf, gateway, ns, ns1, ns2), CDN and static assets (cdn, static, assets, media, images), DevOps tooling (git, gitlab, jenkins, ci, cd, docker, k8s, grafana, kibana), databases (db, mysql, postgres, mongo, redis, elastic), and more.
security watch-ssl
Continuously monitor SSL/TLS certificates for one or more domains. On each check cycle the certificate is re-fetched and alerts are fired for: near-expiry (status == warning), expired certificates, certificate changes (expiry date difference between consecutive checks), and check failures. Runs indefinitely until Ctrl-C or for a fixed number of cycles.
nadzoring security watch-ssl [OPTIONS] DOMAINS...
| Option | Short | Description | Default |
|---|---|---|---|
--interval |
-i |
Seconds between full check cycles | 3600 |
--cycles |
-c |
Number of cycles to run (0 = run indefinitely) |
0 |
--days-before |
-d |
Days before expiry to trigger a warning alert | 7 |
# Monitor ya.ru indefinitely, check every hour
nadzoring security watch-ssl ya.ru
# Monitor multiple domains with a 14-day warning threshold
nadzoring security watch-ssl --days-before 14 example.com github.com cloudflare.com
# Run exactly 5 check cycles with a 60-second interval (useful for CI/testing)
nadzoring security watch-ssl --cycles 5 --interval 60 example.com
# Frequent checks — every 5 minutes — for a critical service
nadzoring security watch-ssl --interval 300 api.example.com
# Save all check results as JSON after monitoring ends
nadzoring security watch-ssl --cycles 3 -o json --save ssl_history.json example.com
# Quiet mode — suppress progress output, emit only alert lines
nadzoring security watch-ssl --quiet --cycles 10 --interval 30 example.com
Alert events fired:
| Trigger | Message example |
|---|---|
| Check failure | Check failed: [Errno 111] Connection refused |
| Expired certificate | Certificate has EXPIRED |
| Near expiry | Certificate expires in 5 day(s) |
| Certificate changed | Certificate changed: expiry 2025-06-01 → 2025-12-01 |
Python API:
from nadzoring.security.ssl_monitor import SSLMonitor
# Create monitor for multiple domains
monitor = SSLMonitor(
domains=["example.com", "github.com", "cloudflare.com"],
interval=3600, # seconds between cycles
days_before=14, # alert when fewer than 14 days remain
)
# Custom alert handler
def on_alert(domain: str, message: str) -> None:
print(f"ALERT {domain}: {message}")
# send to Slack, PagerDuty, email, etc.
monitor.set_alert_callback(on_alert)
# Run a fixed number of cycles (blocking)
results = monitor.run_cycles(cycles=5)
# Or run indefinitely until KeyboardInterrupt
try:
monitor.run()
except KeyboardInterrupt:
pass
# Retrieve full history of all check results
for entry in monitor.history():
print(entry["domain"], entry["status"], entry["remaining_days"], entry["checked_at"])
ARP Commands
arp cache
Show the current ARP cache table (IP-to-MAC mappings).
nadzoring arp cache [OPTIONS]
nadzoring arp cache
nadzoring arp cache -o csv --save arp_cache.csv
nadzoring arp cache -o json
Python API:
from nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError
try:
cache = ARPCache()
entries = cache.get_cache()
except ARPCacheRetrievalError as exc:
print("Cannot read ARP cache:", exc)
else:
for entry in entries:
print(
f"{entry.ip_address} "
f"{entry.mac_address or '(incomplete)'} "
f"{entry.interface} "
f"{entry.state.value}"
)
arp detect-spoofing
Statically detect ARP spoofing by analysing the current ARP cache.
nadzoring arp detect-spoofing [OPTIONS] [INTERFACES]...
Detects: duplicate MAC across IPs (duplicate_mac) and duplicate IP with multiple MACs (duplicate_ip).
nadzoring arp detect-spoofing
nadzoring arp detect-spoofing eth0 wlan0
nadzoring arp detect-spoofing -o json --save spoofing_alerts.json
Python API:
from nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError
from nadzoring.arp.detector import ARPSpoofingDetector
try:
cache = ARPCache()
detector = ARPSpoofingDetector(cache)
alerts = detector.detect()
except ARPCacheRetrievalError as exc:
print("ARP cache error:", exc)
else:
if not alerts:
print("No spoofing detected")
for alert in alerts:
print(f"[{alert.alert_type}] {alert.description}")
arp monitor-spoofing
Monitor live network traffic for ARP spoofing in real time (requires root/admin).
nadzoring arp monitor-spoofing [OPTIONS]
| Option | Short | Description | Default |
|---|---|---|---|
--interface |
-i |
Interface to monitor | All |
--count |
-c |
Packets to capture | 10 |
--timeout |
-t |
Capture timeout (seconds) | 30 |
nadzoring arp monitor-spoofing
nadzoring arp monitor-spoofing --interface eth0 --count 200 --timeout 60
nadzoring arp monitor-spoofing -o json --save arp_alerts.json
Python API:
from nadzoring.arp.realtime import ARPRealtimeDetector
detector = ARPRealtimeDetector()
alerts = detector.monitor(interface="eth0", count=100, timeout=30)
for alert in alerts:
print(f"{alert['timestamp']} {alert['message']}")
print(f" src_ip={alert['src_ip']} src_mac={alert['src_mac']}")
# Get monitoring stats
stats = detector.get_stats()
print(f"Processed: {stats['packets_processed']} Alerts: {stats['alerts_generated']}")
# Custom callback for integration with external systems
def on_packet(packet, alert):
if alert:
print("ALERT:", alert) # integrate with your alerting pipeline here
detector.monitor(interface=None, count=0, timeout=0, packet_callback=on_packet)
Output Formats
Use -o / --output to change the output format:
| Format | Description |
|---|---|
table |
Rich terminal table (default) |
json |
JSON array, suitable for scripting |
csv |
Comma-separated values |
html |
Complete HTML page with CSS |
html_table |
HTML table fragment only |
nadzoring dns resolve -o json example.com
nadzoring dns health -o html --save health.html example.com
nadzoring network-base connections -o csv --save conns.csv
nadzoring security check-ssl -o json example.com
nadzoring security check-headers -o html --save headers.html https://example.com
nadzoring security check-email -o json --save email_audit.json example.com
nadzoring security subdomains -o json --save subdomains.json example.com
Saving Results
nadzoring dns check -o html --save dns_report.html example.com
nadzoring dns compare -o csv --save comparison.csv google.com
nadzoring dns poisoning -o json --save poisoning.json example.com
nadzoring network-base port-scan -o json --save scan.json example.com
nadzoring network-base domain-info -o json --save domain_info.json example.com
nadzoring security check-ssl -o json --save ssl_report.json example.com
nadzoring security check-headers -o json --save headers_report.json https://example.com
nadzoring security check-email -o json --save email_security.json example.com
nadzoring security subdomains -o json --save subdomains.json example.com
nadzoring arp cache -o csv --save arp.csv
Logging Levels
| Mode | Flag | Behaviour |
|---|---|---|
| Normal | (none) | Warnings + progress bars |
| Verbose | --verbose |
Debug logs + execution timing |
| Quiet | --quiet |
Results only — ideal for scripting |
Error Handling
Every public Python API function follows a consistent error contract — functions never raise on expected DNS or network failures. All errors are returned as structured data so that scripts can handle them uniformly.
DNS result-dict pattern — check result["error"] before using result["records"]:
from nadzoring.dns_lookup.utils import resolve_with_timer
result = resolve_with_timer("example.com", "A")
if result["error"]:
# "Domain does not exist" — NXDOMAIN
# "No A records" — record type not present
# "Query timeout" — nameserver did not respond
print("DNS error:", result["error"])
else:
print(result["records"])
print(f"RTT: {result['response_time']} ms")
Return-None / empty-dict pattern — used where a result cannot be partially valid:
from nadzoring.network_base.geolocation_ip import geo_ip
result = geo_ip("8.8.8.8")
if not result:
print("Geolocation unavailable")
else:
print(f"{result['city']}, {result['country']}")
Exception pattern — used only for system-level failures (missing commands, unsupported OS):
from nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError
try:
cache = ARPCache()
entries = cache.get_cache()
except ARPCacheRetrievalError as exc:
print("Cannot read ARP cache:", exc)
All library exceptions inherit from nadzoring.utils.errors.NadzorингError and can be caught at any granularity:
from nadzoring.utils.errors import NadzorингError, DNSError, NetworkError, ARPError
For a complete reference of all error patterns and possible error values, see the Error Handling guide in the documentation.
Python API
Nadzoring can be used as a Python library — all functionality is accessible programmatically without invoking the CLI.
DNS Lookup API
from nadzoring.dns_lookup.utils import resolve_with_timer, get_public_dns_servers
# Resolve any record type
result = resolve_with_timer("example.com", "MX", include_ttl=True)
if result["error"]:
print("Error:", result["error"])
else:
print(result["records"]) # ['10 mail.example.com']
print(result["ttl"]) # 3600
print(result["response_time"]) # 45.2
# List built-in public servers
servers = get_public_dns_servers() # ['8.8.8.8', '1.1.1.1', ...]
Reverse DNS API
from nadzoring.dns_lookup.reverse import reverse_dns
# Standard reverse lookup
result = reverse_dns("8.8.8.8")
if result["error"]:
# Possible values: 'No PTR record', 'No reverse DNS',
# 'Query timeout', 'Invalid IP address: ...'
print("Failed:", result["error"])
else:
print(result["hostname"]) # 'dns.google'
# With a custom nameserver
result = reverse_dns("1.1.1.1", nameserver="8.8.8.8")
print(result["hostname"]) # 'one.one.one.one'
# Compact error-safe pattern
hostname = result["hostname"] or f"[{result['error']}]"
Network Base API
from nadzoring.network_base.ping_address import ping_addr
from nadzoring.network_base.http_ping import http_ping
from nadzoring.network_base.geolocation_ip import geo_ip
from nadzoring.network_base.traceroute import traceroute
from nadzoring.network_base.connections import get_connections
from nadzoring.network_base.route_table import get_route_table
from nadzoring.network_base.network_params import network_param
from nadzoring.network_base.whois import whois_lookup
from nadzoring.network_base.domain_info import get_domain_info
from nadzoring.network_base.port_scanner import ScanConfig, scan_ports
# Ping — returns bool
alive = ping_addr("8.8.8.8")
# HTTP probe — check .error before reading timing fields
r = http_ping("https://example.com")
if not r.error:
print(r.ttfb_ms, r.status_code)
# Geolocation — returns {} on failure
loc = geo_ip("8.8.8.8")
if loc:
print(loc["country"], loc["city"])
# Comprehensive domain info — WHOIS + DNS + geo + reverse DNS
info = get_domain_info("example.com")
print(info["whois"]["registrar"])
print(info["dns"]["ipv4"])
print(info["geolocation"]["country"])
print(info["reverse_dns"])
# Traceroute
for hop in traceroute("8.8.8.8", max_hops=10):
print(hop.hop, hop.ip, hop.rtt_ms)
# Active connections
for conn in get_connections(protocol="tcp", state_filter="ESTABLISHED"):
print(conn.local_address, "->", conn.remote_address)
# Port scan
config = ScanConfig(targets=["example.com"], mode="fast", timeout=2.0)
for result in scan_ports(config):
print("Open ports:", result.open_ports)
Security API
from nadzoring.security.check_website_ssl_cert import (
check_ssl_certificate,
check_ssl_expiry,
check_ssl_expiry_with_fallback,
)
from nadzoring.security.http_headers import check_http_security_headers
from nadzoring.security.email_security import check_email_security
from nadzoring.security.subdomain_scan import scan_subdomains
from nadzoring.security.ssl_monitor import SSLMonitor
# SSL/TLS certificate check
result = check_ssl_certificate("example.com", days_before=14)
print(result["status"], result["remaining_days"])
print(result["protocols"]["supported"]) # ['TLSv1.2', 'TLSv1.3']
print(result["public_key"]["strength"]) # 'good'
# Fallback mode for self-signed / problematic certs
result = check_ssl_expiry_with_fallback("self-signed.example.com")
# HTTP security header audit
headers = check_http_security_headers("https://example.com")
print(headers["score"]) # 0–100
print(headers["missing"]) # list of absent recommended headers
print(headers["leaking"]) # {'Server': 'nginx/1.18.0'}
# Email security (SPF / DKIM / DMARC)
email = check_email_security("example.com")
print(email["overall_score"]) # 0–3
print(email["spf"]["all_qualifier"]) # '~' (softfail)
print(email["dmarc"]["policy"]) # 'reject'
print(email["all_issues"]) # aggregated issue list
# Subdomain discovery
subdomains = scan_subdomains(
"example.com",
max_threads=30,
timeout=4.0,
)
for s in subdomains:
print(s["subdomain"], s["ip"], s["source"])
# Continuous SSL monitoring
monitor = SSLMonitor(["example.com", "github.com"], interval=3600, days_before=14)
monitor.set_alert_callback(lambda domain, msg: print(f"ALERT {domain}: {msg}"))
results = monitor.run_cycles(cycles=3)
for r in monitor.history():
print(r["domain"], r["status"], r["remaining_days"])
ARP API
from nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError
from nadzoring.arp.detector import ARPSpoofingDetector
from nadzoring.arp.realtime import ARPRealtimeDetector
# ARP cache — raises ARPCacheRetrievalError on system failure
try:
cache = ARPCache()
for entry in cache.get_cache():
print(entry.ip_address, entry.mac_address, entry.state.value)
except ARPCacheRetrievalError as exc:
print("ARP cache unavailable:", exc)
# Static spoofing detection
detector = ARPSpoofingDetector(cache)
for alert in detector.detect():
print(alert.alert_type, alert.description)
# Real-time monitoring
rt = ARPRealtimeDetector()
alerts = rt.monitor(interface="eth0", count=50, timeout=30)
print(rt.get_stats())
Examples
DNS Diagnostics
nadzoring dns health example.com
nadzoring dns trace example.com
nadzoring dns compare -t A -t MX example.com
nadzoring dns check -t ALL -v example.com
Reverse DNS Batch Lookup
# Look up multiple IPs at once
nadzoring dns reverse 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222
# Save results
nadzoring dns reverse -o json --save ptr_records.json 8.8.8.8 1.1.1.1
DNS Poisoning Detection
nadzoring dns poisoning -v twitter.com
nadzoring dns poisoning -c 8.8.8.8 -c 1.1.1.1 example.com
nadzoring dns poisoning -o html --save poisoning_report.html github.com
DNS Performance Benchmarking
nadzoring dns benchmark --queries 20 --parallel
nadzoring dns benchmark -s 8.8.8.8 -s 1.1.1.1 -s 208.67.222.222 -s 9.9.9.9
nadzoring dns benchmark -t MX -d gmail.com --queries 15
Port Scanning
nadzoring network-base port-scan --mode full --protocol tcp example.com
nadzoring network-base port-scan --mode custom --ports 20-1024 example.com
nadzoring network-base port-scan -o csv --save network_scan.csv 192.168.1.1
HTTP Service Probing
nadzoring network-base http-ping --show-headers https://api.example.com/health
nadzoring network-base http-ping https://google.com https://cloudflare.com https://github.com
nadzoring network-base http-ping -o csv --save http_metrics.csv https://example.com
SSL/TLS Certificate Auditing
# Quick check — compact summary
nadzoring security check-ssl example.com
# Check multiple domains with a 30-day warning window
nadzoring security check-ssl --days-before 30 google.com github.com cloudflare.com ya.ru
# Full details including SAN list, protocol versions, chain info
nadzoring security check-ssl --full example.com
# Check without verifying the chain (self-signed / internal CA)
nadzoring security check-ssl --no-verify https://internal.corp.example.com
# Save full report as JSON
nadzoring security check-ssl --full -o json --save ssl_audit.json example.com github.com
HTTP Security Header Auditing
# Single URL
nadzoring security check-headers https://example.com
# Batch audit of several services
nadzoring security check-headers \
https://api.example.com \
https://admin.example.com \
https://static.example.com
# Skip SSL verification for internal endpoints
nadzoring security check-headers --no-verify https://internal.corp.example.com
# Export as JSON for CI / dashboard integration
nadzoring security check-headers -o json --save headers_audit.json https://example.com
Email Security Validation
# Check a single domain
nadzoring security check-email example.com
# Audit multiple domains
nadzoring security check-email gmail.com outlook.com yahoo.com proton.me
# Export full JSON report with SPF/DKIM/DMARC details
nadzoring security check-email -o json --save email_audit.json example.com
# Check all your owned domains at once
nadzoring security check-email corp.example.com mail.example.com newsletter.example.com
Subdomain Discovery
# CT logs + built-in wordlist brute-force
nadzoring security subdomains example.com
# CT logs only — faster, no DNS brute-force
nadzoring security subdomains --no-bruteforce example.com
# Custom wordlist and more threads for deeper scanning
nadzoring security subdomains \
--wordlist /path/to/big-wordlist.txt \
--threads 100 \
--timeout 5 \
example.com
# Save discovered subdomains as JSON
nadzoring security subdomains -o json --save subdomains.json example.com
Continuous SSL Monitoring
# Monitor a single domain indefinitely (Ctrl-C to stop)
nadzoring security watch-ssl example.com
# Monitor multiple domains with a 14-day warning threshold
nadzoring security watch-ssl --days-before 14 \
example.com github.com cloudflare.com api.example.com
# Check every 5 minutes for a critical service
nadzoring security watch-ssl --interval 300 api.example.com
# Run 10 cycles with a 60-second interval and save all results
nadzoring security watch-ssl --cycles 10 --interval 60 \
-o json --save ssl_monitor_history.json example.com
ARP Spoofing Detection
nadzoring arp detect-spoofing eth0
nadzoring arp monitor-spoofing --interface eth0 --timeout 60
nadzoring arp monitor-spoofing -o json --save arp_alerts.json
Network Path Analysis
nadzoring network-base traceroute --max-hops 30 github.com
nadzoring network-base traceroute google.com cloudflare.com amazon.com
nadzoring network-base route
nadzoring network-base connections --state LISTEN
Complete Network Diagnostics
nadzoring network-base params -v
nadzoring network-base host-to-ip google.com cloudflare.com github.com
nadzoring network-base ping 8.8.8.8 1.1.1.1 google.com
nadzoring network-base geolocation 8.8.8.8 1.1.1.1
nadzoring network-base domain-info example.com
nadzoring network-base port-scan --mode fast example.com
nadzoring network-base traceroute cloudflare.com
nadzoring security check-ssl example.com
nadzoring security check-headers https://example.com
nadzoring security check-email example.com
nadzoring arp cache
Automated DNS Server Monitoring
This section covers three integration approaches for continuous monitoring: a shell script for use with cron/systemd, a Python script for in-process loops with alerting, and scheduling setup for both Linux and Windows.
Shell script with alerting thresholds
Save as dns_monitor.sh and make executable (chmod +x dns_monitor.sh):
#!/bin/bash
# dns_monitor.sh — continuous DNS health and performance monitor
# Designed to be called by cron or systemd timer.
set -euo pipefail
# ── Configuration ────────────────────────────────────────────────────────────
TARGET_DOMAIN="${1:-example.com}"
DNS_SERVER="${2:-8.8.8.8}"
REPORT_DIR="${DNS_MONITOR_DIR:-/var/log/nadzoring}"
ALERT_EMAIL="${DNS_ALERT_EMAIL:-}" # leave empty to disable email alerts
HEALTH_THRESHOLD=70 # score below this triggers an alert
BENCHMARK_QUERIES=5 # queries per server for each run
# ── Setup ────────────────────────────────────────────────────────────────────
mkdir -p "$REPORT_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$REPORT_DIR/monitor_${TIMESTAMP}.log"
SUMMARY_FILE="$REPORT_DIR/summary.jsonl" # append-only JSONL for trend analysis
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }
alert() {
log "ALERT: $*"
if [[ -n "$ALERT_EMAIL" ]]; then
echo "$*" | mail -s "[nadzoring] DNS alert: $TARGET_DOMAIN" "$ALERT_EMAIL" || true
fi
}
# ── DNS Health Check ─────────────────────────────────────────────────────────
log "Starting DNS health check for $TARGET_DOMAIN via $DNS_SERVER"
HEALTH_JSON="$REPORT_DIR/health_${TIMESTAMP}.json"
if nadzoring dns health -n "$DNS_SERVER" -o json --quiet \
--save "$HEALTH_JSON" "$TARGET_DOMAIN"; then
SCORE=$(python3 -c "import json,sys; d=json.load(open('$HEALTH_JSON')); print(d.get('score',0))" 2>/dev/null || echo 0)
STATUS=$(python3 -c "import json,sys; d=json.load(open('$HEALTH_JSON')); print(d.get('status','unknown'))" 2>/dev/null || echo unknown)
log "Health score: $SCORE ($STATUS)"
if [[ "$SCORE" -lt "$HEALTH_THRESHOLD" ]]; then
alert "Health score $SCORE is below threshold $HEALTH_THRESHOLD (status: $STATUS) for $TARGET_DOMAIN"
fi
else
alert "dns health check command failed for $TARGET_DOMAIN"
SCORE=0; STATUS="error"
fi
# ── DNS Benchmark ────────────────────────────────────────────────────────────
BENCH_JSON="$REPORT_DIR/benchmark_${TIMESTAMP}.json"
if nadzoring dns benchmark -s "$DNS_SERVER" -s 8.8.8.8 -s 1.1.1.1 \
-d "$TARGET_DOMAIN" -q "$BENCHMARK_QUERIES" \
-o json --quiet --save "$BENCH_JSON"; then
AVG_MS=$(python3 -c "
import json
data = json.load(open('$BENCH_JSON'))
target = next((r for r in data if r['server'] == '$DNS_SERVER'), None)
print(round(target['avg_response_time'], 1) if target else 'N/A')
" 2>/dev/null || echo "N/A")
log "Benchmark avg response time for $DNS_SERVER: ${AVG_MS}ms"
else
log "WARNING: benchmark failed"
AVG_MS="N/A"
fi
# ── DNS Compare (discrepancy detection) ─────────────────────────────────────
COMPARE_JSON="$REPORT_DIR/compare_${TIMESTAMP}.json"
nadzoring dns compare -t A -t MX \
-s "$DNS_SERVER" -s 8.8.8.8 -s 1.1.1.1 \
-o json --quiet --save "$COMPARE_JSON" "$TARGET_DOMAIN" || true
DIFFS=$(python3 -c "
import json
data = json.load(open('$COMPARE_JSON'))
diffs = data.get('differences', [])
print(len(diffs))
" 2>/dev/null || echo 0)
if [[ "$DIFFS" -gt 0 ]]; then
alert "$DIFFS DNS discrepancies detected for $TARGET_DOMAIN — possible poisoning or misconfiguration"
fi
log "DNS compare: $DIFFS discrepancies found"
# ── Reverse DNS Spot-check ───────────────────────────────────────────────────
RESOLVED_IP=$(nadzoring network-base host-to-ip --quiet -o json "$TARGET_DOMAIN" 2>/dev/null \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d[0].get('ip','') if d else '')" 2>/dev/null || echo "")
REVERSE_HOST="N/A"
if [[ -n "$RESOLVED_IP" ]]; then
REVERSE_JSON="$REPORT_DIR/reverse_${TIMESTAMP}.json"
nadzoring dns reverse -n "$DNS_SERVER" -o json --quiet \
--save "$REVERSE_JSON" "$RESOLVED_IP" || true
REVERSE_HOST=$(python3 -c "
import json
data = json.load(open('$REVERSE_JSON'))
print(data[0].get('hostname','N/A') if data else 'N/A')
" 2>/dev/null || echo "N/A")
log "Reverse DNS for $RESOLVED_IP → $REVERSE_HOST"
fi
# ── Append to JSONL summary for trend analysis ───────────────────────────────
python3 - <<EOF >> "$SUMMARY_FILE"
import json, datetime
print(json.dumps({
"timestamp": "$TIMESTAMP",
"domain": "$TARGET_DOMAIN",
"dns_server": "$DNS_SERVER",
"health_score": $SCORE,
"health_status": "$STATUS",
"avg_response_ms": "$AVG_MS",
"discrepancies": $DIFFS,
"resolved_ip": "$RESOLVED_IP",
"reverse_host": "$REVERSE_HOST",
}))
EOF
log "Run complete. Reports saved to $REPORT_DIR"
Scheduling with cron (Linux/macOS)
# Edit crontab
crontab -e
# Run every 5 minutes
*/5 * * * * /path/to/dns_monitor.sh example.com 8.8.8.8
# Run every hour with email alerts
0 * * * * DNS_ALERT_EMAIL=ops@example.com /path/to/dns_monitor.sh example.com 8.8.8.8
# Run every 15 minutes, logging cron output
*/15 * * * * /path/to/dns_monitor.sh example.com 8.8.8.8 >> /var/log/nadzoring/cron.log 2>&1
Scheduling with systemd timer (Linux, recommended)
Create /etc/systemd/system/nadzoring-dns-monitor.service:
[Unit]
Description=Nadzoring DNS health monitor
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/path/to/dns_monitor.sh example.com 8.8.8.8
Environment=DNS_MONITOR_DIR=/var/log/nadzoring
Environment=DNS_ALERT_EMAIL=ops@example.com
StandardOutput=journal
StandardError=journal
Create /etc/systemd/system/nadzoring-dns-monitor.timer:
[Unit]
Description=Run Nadzoring DNS monitor every 5 minutes
[Timer]
OnBootSec=60
OnUnitActiveSec=5min
Persistent=true
[Install]
WantedBy=timers.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now nadzoring-dns-monitor.timer
sudo systemctl status nadzoring-dns-monitor.timer
journalctl -u nadzoring-dns-monitor.service -f # follow live logs
Python continuous monitoring loop (in-process)
Use DNSMonitor directly for in-process monitoring with custom alerting:
Infinite loop (blocks until Ctrl-C or SIGTERM):
from nadzoring.dns_lookup.monitor import AlertEvent, DNSMonitor, MonitorConfig
def send_alert(alert: AlertEvent) -> None:
print(f"ALERT [{alert.alert_type}]: {alert.message}")
config = MonitorConfig(
domain="example.com",
nameservers=["8.8.8.8", "1.1.1.1"],
interval=60.0,
max_response_time_ms=500.0,
min_success_rate=0.95,
log_file="dns_monitor.jsonl",
alert_callback=send_alert,
)
monitor = DNSMonitor(config)
monitor.run()
print(monitor.report())
Finite cycles (CI pipelines, cron scripts):
from nadzoring.dns_lookup.monitor import DNSMonitor, MonitorConfig
from statistics import mean
config = MonitorConfig(
domain="example.com",
nameservers=["8.8.8.8", "1.1.1.1"],
interval=10.0,
run_health_check=False,
)
monitor = DNSMonitor(config)
history = monitor.run_cycles(6)
rts = [
s.avg_response_time_ms
for c in history
for s in c.samples
if s.avg_response_time_ms is not None
]
print(f"Mean RT: {mean(rts):.1f}ms")
print(monitor.report())
Analyse saved log:
from nadzoring.dns_lookup.monitor import load_log
from statistics import mean
cycles = load_log("dns_monitor.jsonl")
rts = [
s["avg_response_time_ms"]
for c in cycles
for s in c["samples"]
if s["avg_response_time_ms"] is not None
]
alerts = [a for c in cycles for a in c.get("alerts", [])]
print(f"Cycles: {len(cycles)} Mean RT: {mean(rts):.1f}ms Alerts: {len(alerts)}")
Quick Website Block Check
nadzoring dns resolve -t ALL example.com
nadzoring dns reverse 93.184.216.34
nadzoring dns trace example.com
nadzoring network-base ping example.com
nadzoring dns compare example.com
nadzoring dns poisoning example.com
nadzoring network-base http-ping https://example.com
nadzoring network-base traceroute example.com
nadzoring security check-ssl example.com
nadzoring security check-headers https://example.com
nadzoring security check-email example.com
nadzoring security subdomains example.com
Contributing
Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.
Workflow:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Areas we'd love help with:
- Additional DNS record type support
- New health check validation rules
- CDN network database expansion
- Performance optimisations
- Additional output formats
- ARP detection heuristics
- New network diagnostic commands
- Extended security auditing (HSTS preload check, certificate transparency monitoring, CAA record validation)
Documentation
| Version | Link | Status |
|---|---|---|
| main | Latest (development) | 🟡 Development |
| v0.1.8 | Stable release | 🟢 Stable |
| v0.1.7 | Previous release | ⚪ Legacy |
| v0.1.6 | Previous release | ⚪ Legacy |
| v0.1.5 | Previous release | ⚪ Legacy |
| v0.1.4 | Previous release | ⚪ Legacy |
| v0.1.3 | Legacy | ⚪ Legacy |
| v0.1.2 | Legacy | ⚪ Legacy |
| v0.1.1 | First version | ⚪ Legacy |
The documentation site includes:
- Error Handling guide — complete reference of all error patterns and return values
- Architecture overview — layer design, SRP/DRY/KISS principles applied
- DNS command reference — full CLI + Python API per command
- Security command reference — SSL, headers, email, subdomains, monitoring
- DNS monitoring guide — systemd, cron, trend analysis
License & Support
This project is licensed under the GNU GPL v3 License — see LICENSE for details.
For commercial support or enterprise features, contact alexeev.dev@mail.ru.
📖 Explore Docs · 🐛 Report Issue
Copyright © 2025 Alexeev Bronislav. Distributed under GNU GPL v3 license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nadzoring-0.1.8.tar.gz.
File metadata
- Download URL: nadzoring-0.1.8.tar.gz
- Upload date:
- Size: 374.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fc509438139f3f1161ffd1cc977adb25e0d3204004d97efe766a5a2f6d03dde
|
|
| MD5 |
56256a7a86f7232394581b17944b63f5
|
|
| BLAKE2b-256 |
d715c4a50350735304a344a964eaf78c51a54a9d99d7bd34cafbeea5be4bfcf7
|
File details
Details for the file nadzoring-0.1.8-py3-none-any.whl.
File metadata
- Download URL: nadzoring-0.1.8-py3-none-any.whl
- Upload date:
- Size: 148.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce32834d973bf8abbf59e4d5ef18927d96620c6e101582d6bf71beea9be92a26
|
|
| MD5 |
c2d1e972be2eabe7c1c0296f2a6be9a1
|
|
| BLAKE2b-256 |
9a6c573a163cad1a670c50c69a806d0a6a1a8462263bd430f718c65d4a3287ad
|