{"id":45609556,"url":"https://github.com/alexeev-prog/nadzoring","last_synced_at":"2026-04-01T17:38:20.251Z","repository":{"id":339572106,"uuid":"1161646854","full_name":"alexeev-prog/nadzoring","owner":"alexeev-prog","description":"An open source tool for detecting website blocks, downdetecting, and network analysis","archived":false,"fork":false,"pushed_at":"2026-03-28T18:01:43.000Z","size":1438,"stargazers_count":12,"open_issues_count":16,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T20:04:13.072Z","etag":null,"topics":["ai-friendly","arp","censorship","cli","dns","network","network-analysis","network-monitoring","python","security","security-tools","utility"],"latest_commit_sha":null,"homepage":"https://alexeev-prog.github.io/nadzoring/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexeev-prog.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-19T10:57:08.000Z","updated_at":"2026-03-28T18:03:10.000Z","dependencies_parsed_at":"2026-02-25T19:01:04.090Z","dependency_job_id":"5be5ceef-4e93-4208-80e9-1ea5f01b507b","html_url":"https://github.com/alexeev-prog/nadzoring","commit_stats":null,"previous_names":["alexeev-prog/nadzoring"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/alexeev-prog/nadzoring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2Fnadzoring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2Fnadzoring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2Fnadzoring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2Fnadzoring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexeev-prog","download_url":"https://codeload.github.com/alexeev-prog/nadzoring/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2Fnadzoring/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-friendly","arp","censorship","cli","dns","network","network-analysis","network-monitoring","python","security","security-tools","utility"],"created_at":"2026-02-23T17:00:57.928Z","updated_at":"2026-04-01T17:38:20.213Z","avatar_url":"https://github.com/alexeev-prog.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca id=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/alexeev-prog/nadzoring/refs/heads/main/docs/logo.png\" width=300\u003e\n    \u003ch2\u003eNadzoring\u003c/h2\u003e\n    \u003cp\u003eAn open source tool and python library for detecting website blocks, downdetecting and network analysis\u003c/p\u003e\n    \u003ca href=\"https://alexeev-prog.github.io/nadzoring/v0.1.9\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"#-getting-started\"\u003eGetting Started\u003c/a\u003e\n    ·\n    \u003ca href=\"#-usage-examples\"\u003eBasic Usage\u003c/a\u003e\n    ·\n    \u003ca href=\"https://www.pitchhut.com/project/nadzoring-tool\"\u003ePitchhut\u003c/a\u003e\n    ·\n    \u003ca href=\"https://context7.com/alexeev-prog/nadzoring\"\u003eContext7\u003c/a\u003e\n    ·\n    \u003ca href=\"https://deepwiki.com/alexeev-prog/nadzoring\"\u003eDeepwiki\u003c/a\u003e\n    ·\n    \u003ca href=\"https://alexeev-prog.github.io/nadzoring/main\"\u003eLatest Documentation\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/alexeev-prog/nadzoring/blob/main/LICENSE\"\u003eLicense\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\u003chr\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/top/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/count/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Maintained-yes-green.svg?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub License\" src=\"https://img.shields.io/github/license/alexeev-prog/nadzoring?style=for-the-badge\u0026logo=gnu\"\u003e\n    \u003cimg alt=\"GitHub forks\" src=\"https://img.shields.io/github/forks/alexeev-prog/nadzoring?style=for-the-badge\u0026logo=github\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/stars/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/issues/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/last-commit/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub commits since latest release\" src=\"https://img.shields.io/github/commits-since/alexeev-prog/nadzoring/latest?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub Release Date\" src=\"https://img.shields.io/github/release-date-pre/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub Actions Workflow Status\" src=\"https://img.shields.io/github/actions/workflow/status/alexeev-prog/nadzoring/docs.yml?style=for-the-badge\u0026logo=github\u0026label=docs\"\u003e\n    \u003cimg alt=\"GitHub Actions Workflow Status\" src=\"https://img.shields.io/github/actions/workflow/status/alexeev-prog/nadzoring/python-package.yml?style=for-the-badge\u0026logo=python\u0026label=python%20package%20lint\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/wheel/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg alt=\"PyPI - Downloads\" src=\"https://img.shields.io/pypi/dm/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg alt=\"PyPI - Version\" src=\"https://img.shields.io/pypi/v/nadzoring?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub contributors\" src=\"https://img.shields.io/github/contributors/alexeev-prog/nadzoring?style=for-the-badge\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/alexeev-prog/nadzoring/refs/heads/main/docs/pallet-0.png\"\u003e\n\u003c/p\u003e\n\nNadzoring (from Russian \"надзор\" — supervision/oversight + the English \"-ing\" suffix) is a free and open-source command-line tool and Python library designed for in-depth network diagnostics, service availability monitoring, and website block detection. It empowers you to investigate connectivity issues, analyze network configurations, and audit security postures through a comprehensive suite of tools. From DNS diagnostics (including reverse lookups, poisoning detection, and delegation tracing) to ARP spoofing monitoring, SSL/TLS certificate analysis, HTTP security header auditing, email security validation (SPF/DKIM/DMARC), and subdomain discovery — Nadzoring brings together a wide range of capabilities in a single, consistent interface.\n\nBuilt from the ground up with AI-friendliness in mind, Nadzoring is fully type-annotated, enforces a strict zero-warnings linter policy, and is architected according to SOLID principles with a strong emphasis on modularity and the Single Responsibility Principle (SRP). This architectural clarity ensures that the codebase remains maintainable, testable, and easy to extend. The project's high-quality typing and well-structured domain logic make it equally suitable for use as a reliable Python library in your own applications, as well as a powerful standalone CLI tool.\n\nBeyond its technical strengths, Nadzoring is supported by an extensive, versioned documentation site, complete with an integrated AI chat powered by Context7 for interactive help, and is featured on DeepWiki and Pitchhut for broader discovery. The project maintains a clean separation between its CLI layer and domain logic, allowing the same core functionality to be used seamlessly from the command line or programmatically. With an active development cycle, comprehensive CI/CD pipelines, and a focus on code quality, Nadzoring is built to be a trustworthy foundation for network analysis and security auditing.\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://deepwiki.com/alexeev-prog/nadzoring\"\u003e\u003cimg src=\"https://deepwiki.com/badge.svg\" alt=\"Ask DeepWiki\"\u003e\u003c/a\u003e\n    \u003cimg src=\"https://scrutinizer-ci.com/g/alexeev-prog/nadzoring/badges/quality-score.png?b=main\"\u003e\n    \u003ca href=\"https://sloprank.io/repo/alexeev-prog/nadzoring\"\u003e\u003cimg src=\"https://sloprank.io/badge/alexeev-prog/nadzoring.svg\" alt=\"sloprank\"\u003e\u003c/a\u003e\n    \u003ca href='https://coveralls.io/github/alexeev-prog/nadzoring?branch=main'\u003e\u003cimg src='https://coveralls.io/repos/github/alexeev-prog/nadzoring/badge.svg?branch=main' alt='Coverage' /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n    - [Prerequisites](#prerequisites)\n    - [Installation](#installation)\n  - [Usage](#usage)\n    - [Global Options](#global-options)\n    - [DNS Commands](#dns-commands)\n      - [dns resolve](#dns-resolve)\n      - [dns reverse](#dns-reverse)\n      - [dns check](#dns-check)\n      - [dns trace](#dns-trace)\n      - [dns compare](#dns-compare)\n      - [dns health](#dns-health)\n      - [dns benchmark](#dns-benchmark)\n      - [dns poisoning](#dns-poisoning)\n      - [dns monitor](#dns-monitor)\n      - [dns monitor-report](#dns-monitor-report)\n    - [Network Base Commands](#network-base-commands)\n      - [ping](#ping)\n      - [http-ping](#http-ping)\n      - [host-to-ip](#host-to-ip)\n      - [parse-url](#parse-url)\n      - [geolocation](#geolocation)\n      - [params](#params)\n      - [port-scan](#port-scan)\n      - [detect-service](#detect-service)\n      - [port-service](#port-service)\n      - [whois](#whois)\n      - [domain-info](#domain-info)\n      - [connections](#connections)\n      - [traceroute](#traceroute)\n      - [route](#route)\n    - [Security Commands](#security-commands)\n      - [security check-ssl](#security-check-ssl)\n      - [security check-headers](#security-check-headers)\n      - [security check-email](#security-check-email)\n      - [security subdomains](#security-subdomains)\n      - [security watch-ssl](#security-watch-ssl)\n    - [ARP Commands](#arp-commands)\n      - [arp cache](#arp-cache)\n      - [arp detect-spoofing](#arp-detect-spoofing)\n      - [arp monitor-spoofing](#arp-monitor-spoofing)\n  - [Output Formats](#output-formats)\n  - [Saving Results](#saving-results)\n  - [Logging Levels](#logging-levels)\n  - [Error Handling](#error-handling)\n  - [Python API](#python-api)\n    - [DNS Lookup API](#dns-lookup-api)\n    - [Reverse DNS API](#reverse-dns-api)\n    - [Network Base API](#network-base-api)\n    - [Security API](#security-api)\n    - [ARP API](#arp-api)\n  - [Examples](#examples)\n    - [DNS Diagnostics](#dns-diagnostics)\n    - [Reverse DNS Batch Lookup](#reverse-dns-batch-lookup)\n    - [DNS Poisoning Detection](#dns-poisoning-detection)\n    - [DNS Performance Benchmarking](#dns-performance-benchmarking)\n    - [Port Scanning](#port-scanning)\n    - [HTTP Service Probing](#http-service-probing)\n    - [SSL/TLS Certificate Auditing](#ssltls-certificate-auditing)\n    - [HTTP Security Header Auditing](#http-security-header-auditing)\n    - [Email Security Validation](#email-security-validation)\n    - [Subdomain Discovery](#subdomain-discovery)\n    - [Continuous SSL Monitoring](#continuous-ssl-monitoring)\n    - [ARP Spoofing Detection](#arp-spoofing-detection)\n    - [Network Path Analysis](#network-path-analysis)\n    - [Complete Network Diagnostics](#complete-network-diagnostics)\n    - [Automated DNS Server Monitoring](#automated-dns-server-monitoring)\n      - [Shell script with alerting thresholds](#shell-script-with-alerting-thresholds)\n      - [Scheduling with cron (Linux/macOS)](#scheduling-with-cron-linuxmacos)\n      - [Scheduling with systemd timer (Linux, recommended)](#scheduling-with-systemd-timer-linux-recommended)\n      - [Python continuous monitoring loop (in-process)](#python-continuous-monitoring-loop-in-process)\n    - [Quick Website Block Check](#quick-website-block-check)\n  - [Contributing](#contributing)\n  - [Documentation](#documentation)\n  - [License \\\u0026 Support](#license--support)\n\n---\n\n# Getting Started\n\n### Prerequisites\n\n- Python 3.12+\n- pip\n\nOptional system utilities:\n\n| Utility | Required by |\n|---------|-------------|\n| `traceroute` / `tracepath` | `network-base traceroute` (Linux) |\n| `whois` | `network-base whois` |\n| `ip` / `route` | `network-base params`, `network-base route` |\n| `net-tools` | `network-base params` on some Linux distros (`sudo apt install net-tools`) |\n| `ss` | `network-base connections` (Linux) |\n| `dig` / `nslookup` | `security check-email` (DNS TXT lookups; `dnspython` used when available) |\n\n\u003e **Note:** The Python package `netifaces` (used by `network-base params`) is distributed as source code and requires compilation on Linux. If you encounter errors during installation (e.g., `gcc: command not found`), install the required build tools first:\n\u003e `sudo apt update \u0026\u0026 sudo apt install build-essential python3-dev` (Debian/Ubuntu)\n\u003e or the equivalent for your distribution. On other platforms (Windows, macOS) pre‑compiled wheels are usually available.\n\n### Installation\n\n```bash\npip install nadzoring\n```\n\nVerify:\n\n```bash\nnadzoring --help\n```\n\n**Development version:**\n\n```bash\npip install git+https://github.com/alexeev-prog/nadzoring.git\n```\n\n---\n\n## Usage\n\nNadzoring uses a hierarchical command structure: `nadzoring \u003cgroup\u003e \u003ccommand\u003e [OPTIONS]`.\nThe four main groups are `dns`, `network-base`, `security`, and `arp`.\n\n### Global Options\n\nThese options work with every command:\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--verbose` | | Enable debug output with execution timing | `False` |\n| `--quiet` | | Suppress non-error output | `False` |\n| `--no-color` | | Disable colored output | `False` |\n| `--output` | `-o` | Output format: `table`, `json`, `csv`, `html`, `html_table`, `yaml` | `table` |\n| `--save` | | Save results to file | None |\n\n---\n\n### DNS Commands\n\n#### dns resolve\n\nResolve DNS records for one or more domains.\n\n```bash\nnadzoring dns resolve [OPTIONS] DOMAINS...\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--type` | `-t` | Record type: A, AAAA, CNAME, MX, NS, TXT, ALL | `A` |\n| `--nameserver` | `-n` | Nameserver IP to use | System default |\n| `--short` | | Compact output | `False` |\n| `--show-ttl` | | Show TTL value | `False` |\n| `--format-style` | | Output style: standard, bind, host, dig | `standard` |\n\n```bash\n# A record lookup\nnadzoring dns resolve google.com\n\n# Multiple record types\nnadzoring dns resolve -t MX -t TXT -t A example.com\n\n# All record types with a specific nameserver\nnadzoring dns resolve -t ALL -n 8.8.8.8 github.com\n\n# Show TTL values\nnadzoring dns resolve --show-ttl --type A cloudflare.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.utils import resolve_with_timer\n\nresult = resolve_with_timer(\"example.com\", \"A\")\nif result[\"error\"]:\n    # Possible values:\n    # \"Domain does not exist\"  — NXDOMAIN\n    # \"No A records\"           — record type not found\n    # \"Query timeout\"          — nameserver did not respond\n    print(\"DNS error:\", result[\"error\"])\nelse:\n    print(result[\"records\"])       # ['93.184.216.34']\n    print(result[\"response_time\"]) # milliseconds\n\n# With TTL and custom nameserver\nresult = resolve_with_timer(\n    \"example.com\", \"MX\",\n    nameserver=\"8.8.8.8\",\n    include_ttl=True,\n)\nprint(result[\"records\"])  # ['10 mail.example.com']\nprint(result[\"ttl\"])      # e.g. 3600\n```\n\n---\n\n#### dns reverse\n\nPerform reverse DNS lookups (PTR records) to find the hostname for an IP address.\n\n```bash\nnadzoring dns reverse [OPTIONS] IP_ADDRESSES...\n```\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--nameserver` | `-n` | Nameserver IP to use |\n\n```bash\n# Single IP\nnadzoring dns reverse 8.8.8.8\n\n# Multiple IPs\nnadzoring dns reverse 1.1.1.1 8.8.8.8 9.9.9.9\n\n# Use a specific nameserver\nnadzoring dns reverse -n 208.67.222.222 8.8.4.4\n\n# Save as JSON\nnadzoring dns reverse -o json --save reverse_lookup.json 8.8.8.8 1.1.1.1\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.reverse import reverse_dns\n\n# IPv4 reverse lookup\nresult = reverse_dns(\"8.8.8.8\")\nif result[\"error\"]:\n    # Possible values:\n    # \"No PTR record\"          — IP has no reverse entry\n    # \"No reverse DNS\"         — NXDOMAIN on reverse zone\n    # \"Query timeout\"          — resolver timed out\n    # \"Invalid IP address: …\"  — malformed input\n    print(\"Lookup failed:\", result[\"error\"])\nelse:\n    print(result[\"hostname\"])       # 'dns.google'\n    print(result[\"response_time\"])  # milliseconds\n\n# IPv6 reverse lookup\nresult = reverse_dns(\"2001:4860:4860::8888\")\nprint(result[\"hostname\"])  # 'dns.google'\n\n# Compact error-safe pattern\nhostname = result[\"hostname\"] or f\"[{result['error']}]\"\n\n# Custom nameserver\nresult = reverse_dns(\"8.8.8.8\", nameserver=\"1.1.1.1\")\nprint(result[\"hostname\"])\n```\n\n---\n\n#### dns check\n\nPerform a comprehensive DNS check including MX priority validation and SPF/DKIM analysis.\n\n```bash\nnadzoring dns check [OPTIONS] DOMAINS...\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--nameserver` | `-n` | Nameserver IP | System default |\n| `--types` | `-t` | Record types to check | ALL |\n| `--validate-mx` | | Validate MX priority uniqueness | `False` |\n| `--validate-txt` | | Validate SPF and DKIM TXT records | `False` |\n\n```bash\n# Full DNS check\nnadzoring dns check example.com\n\n# Check MX and TXT only with validation\nnadzoring dns check -t MX -t TXT --validate-mx --validate-txt gmail.com\n\n# Multiple domains\nnadzoring dns check -n 9.9.9.9 google.com cloudflare.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.health import check_dns\n\nresult = check_dns(\n    \"example.com\",\n    record_types=[\"MX\", \"TXT\"],\n    validate_mx=True,\n    validate_txt=True,\n)\nprint(result[\"records\"])        # {'MX': ['10 mail.example.com']}\nprint(result[\"errors\"])         # {'AAAA': 'No AAAA records'} — only failed types\nprint(result[\"response_times\"]) # per-type timing in ms\nprint(result[\"validations\"])    # {'mx': {'valid': True, 'issues': [], 'warnings': []}}\n```\n\n---\n\n#### dns trace\n\nTrace the complete DNS resolution delegation chain from root to authoritative nameserver.\n\n```bash\nnadzoring dns trace [OPTIONS] DOMAIN\n```\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--nameserver` | `-n` | Starting nameserver (default: root `198.41.0.4`) |\n\n```bash\n# Trace from root servers\nnadzoring dns trace example.com\n\n# Start trace from a specific nameserver\nnadzoring dns trace -n 8.8.8.8 google.com\n\n# Verbose with timing\nnadzoring dns trace -v github.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.trace import trace_dns\n\nresult = trace_dns(\"example.com\")\n\nfor hop in result[\"hops\"]:\n    ns = hop[\"nameserver\"]\n    rtt = f\"{hop['response_time']} ms\" if hop[\"response_time\"] else \"timeout\"\n    err = f\" ERROR: {hop['error']}\" if hop.get(\"error\") else \"\"\n    print(f\"  {ns}  {rtt}{err}\")\n    for rec in hop.get(\"records\", []):\n        print(f\"    {rec}\")\n\nif result[\"final_answer\"]:\n    print(\"Final answer:\", result[\"final_answer\"][\"records\"])\nelse:\n    print(\"No authoritative answer found\")\n```\n\n---\n\n#### dns compare\n\nCompare DNS responses from multiple servers and detect discrepancies.\n\n```bash\nnadzoring dns compare [OPTIONS] DOMAIN\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--servers` | `-s` | DNS servers to compare | `8.8.8.8`, `1.1.1.1`, `9.9.9.9` |\n| `--type` | `-t` | Record types to compare | `A` |\n\n```bash\n# Compare A records across default servers\nnadzoring dns compare example.com\n\n# Compare MX records with custom servers\nnadzoring dns compare -t MX -s 8.8.8.8 -s 208.67.222.222 -s 9.9.9.9 gmail.com\n\n# Multiple record types\nnadzoring dns compare -t A -t AAAA -t NS cloudflare.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.compare import compare_dns_servers\n\nresult = compare_dns_servers(\n    \"example.com\",\n    servers=[\"8.8.8.8\", \"1.1.1.1\", \"9.9.9.9\"],\n    record_types=[\"A\", \"MX\"],\n)\nif not result[\"differences\"]:\n    print(\"All servers agree\")\nelse:\n    for diff in result[\"differences\"]:\n        print(f\"Server {diff['server']} — {diff['type']} mismatch\")\n        print(f\"  Expected (baseline): {diff['expected']}\")\n        print(f\"  Got:                 {diff['got']}\")\n        if diff[\"ttl_difference\"] is not None:\n            print(f\"  TTL delta: {diff['ttl_difference']}s\")\n```\n\n---\n\n#### dns health\n\nPerform a scored DNS health check across all standard record types.\n\n```bash\nnadzoring dns health [OPTIONS] DOMAIN\n```\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--nameserver` | `-n` | Nameserver IP |\n\nHealth score: **80–100** = Healthy · **50–79** = Degraded · **0–49** = Unhealthy\n\n```bash\nnadzoring dns health example.com\nnadzoring dns health -n 1.1.1.1 google.com\nnadzoring dns health -o json --save health.json example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.health import health_check_dns\n\nresult = health_check_dns(\"example.com\")\n\nprint(f\"Score: {result['score']}/100\")\nprint(f\"Status: {result['status']}\")  # 'healthy' | 'degraded' | 'unhealthy'\n\nfor issue in result[\"issues\"]:\n    print(\"  CRITICAL:\", issue)\nfor warn in result[\"warnings\"]:\n    print(\"  WARN:\", warn)\nfor rtype, score in result[\"record_scores\"].items():\n    print(f\"  {rtype}: {score}/100\")\n```\n\n---\n\n#### dns benchmark\n\nBenchmark DNS server response times across multiple servers.\n\n```bash\nnadzoring dns benchmark [OPTIONS]\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--domain` | `-d` | Domain to query | `google.com` |\n| `--servers` | `-s` | Servers to benchmark | All public servers |\n| `--type` | `-t` | Record type | `A` |\n| `--queries` | `-q` | Queries per server | `10` |\n| `--parallel/--sequential` | | Run concurrently or one by one | `parallel` |\n\n```bash\nnadzoring dns benchmark\nnadzoring dns benchmark -s 8.8.8.8 -s 1.1.1.1 -s 9.9.9.9 --queries 20\nnadzoring dns benchmark -t MX -d gmail.com --sequential\nnadzoring dns benchmark -o json --save benchmark.json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.benchmark import benchmark_dns_servers, benchmark_single_server\n\n# Single server\nresult = benchmark_single_server(\"8.8.8.8\", queries=10)\nprint(f\"avg={result['avg_response_time']:.1f}ms  success={result['success_rate']}%\")\n\n# Multiple servers — returned sorted fastest-first\nresults = benchmark_dns_servers(\n    servers=[\"8.8.8.8\", \"1.1.1.1\", \"9.9.9.9\"],\n    queries=10,\n    parallel=True,\n)\nfastest = results[0]\nprint(f\"Fastest: {fastest['server']} at {fastest['avg_response_time']:.1f}ms\")\n```\n\n---\n\n#### dns poisoning\n\nDetect DNS poisoning, censorship, or unusual CDN routing for a domain.\n\n```bash\nnadzoring dns poisoning [OPTIONS] DOMAIN\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--control-server` | `-c` | Trusted control resolver | `8.8.8.8` |\n| `--test-servers` | `-t` | Servers to test against control | All public servers |\n| `--type` | `-T` | Record type | `A` |\n| `--additional-types` | `-a` | Extra record types from control server | None |\n\nSeverity levels: `NONE` → `LOW` → `MEDIUM` → `HIGH` → `CRITICAL` / `SUSPICIOUS`\n\n```bash\nnadzoring dns poisoning example.com\nnadzoring dns poisoning -c 1.1.1.1 -a MX -a TXT google.com\nnadzoring dns poisoning -o html --save poisoning_report.html twitter.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.poisoning import check_dns_poisoning\n\nresult = check_dns_poisoning(\"example.com\")\n\nlevel = result.get(\"poisoning_level\", \"NONE\")\nconfidence = result.get(\"confidence\", 0.0)\nprint(f\"Level: {level}  Confidence: {confidence:.0f}%\")\n\nif result.get(\"poisoned\"):\n    for inc in result.get(\"inconsistencies\", []):\n        print(\"Inconsistency:\", inc)\n\nif result.get(\"cdn_detected\"):\n    print(f\"CDN: {result['cdn_owner']} ({result['cdn_percentage']:.0f}%)\")\n```\n\n---\n\n#### dns monitor\n\nContinuously 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.\n\n```bash\nnadzoring dns monitor [OPTIONS] DOMAIN\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--nameservers` | `-n` | DNS server to monitor (repeatable) | `8.8.8.8`, `1.1.1.1` |\n| `--interval` | `-i` | Seconds between monitoring cycles | `60` |\n| `--type` | `-t` | Record type: A, AAAA, MX, NS, TXT | `A` |\n| `--queries` | `-q` | Queries per server per cycle | `3` |\n| `--max-rt` | | Alert threshold: max avg response time (ms) | `500` |\n| `--min-success` | | Alert threshold: minimum success rate (0–1) | `0.95` |\n| `--no-health` | | Skip DNS health check each cycle | `False` |\n| `--log-file` | `-l` | JSONL file to append all cycle results to | None |\n| `--cycles` | `-c` | Stop after N cycles (0 = indefinite) | `0` |\n\n```bash\n# Monitor with default servers, save log\nnadzoring dns monitor example.com \\\n    --interval 60 \\\n    --log-file dns_monitor.jsonl\n\n# Strict thresholds — alert above 150 ms or below 99 % success\nnadzoring dns monitor example.com \\\n    -n 8.8.8.8 -n 1.1.1.1 -n 9.9.9.9 \\\n    --interval 30 \\\n    --max-rt 150 --min-success 0.99 \\\n    --log-file dns_monitor.jsonl\n\n# Run exactly 10 cycles and save a JSON report (great for CI)\nnadzoring dns monitor example.com --cycles 10 -o json --save report.json\n\n# Quiet mode for cron / systemd\nnadzoring dns monitor example.com \\\n    --quiet --log-file /var/log/nadzoring/dns_monitor.jsonl\n```\n\nAfter Ctrl-C (or after `--cycles` completes), a statistical summary is printed automatically.\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.monitor import AlertEvent, DNSMonitor, MonitorConfig\n\n\ndef my_alert_handler(alert: AlertEvent) -\u003e None:\n    print(f\"ALERT [{alert.alert_type}]: {alert.message}\")\n\n\nconfig = MonitorConfig(\n    domain=\"example.com\",\n    nameservers=[\"8.8.8.8\", \"1.1.1.1\"],\n    interval=60.0,\n    queries_per_sample=3,\n    max_response_time_ms=300.0,\n    min_success_rate=0.95,\n    log_file=\"dns_monitor.jsonl\",\n    alert_callback=my_alert_handler,\n)\n\nmonitor = DNSMonitor(config)\nmonitor.run()\nprint(monitor.report())\n```\n\n---\n\n#### dns monitor-report\n\nAnalyse a JSONL log file produced by `dns monitor`.\n\n```bash\nnadzoring dns monitor-report [OPTIONS] LOG_FILE\n```\n\n| Option | Description |\n|--------|-------------|\n| `--server` | Filter statistics to a specific server IP |\n\n```bash\nnadzoring dns monitor-report dns_monitor.jsonl\nnadzoring dns monitor-report dns_monitor.jsonl --server 8.8.8.8 -o json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.dns_lookup.monitor import load_log\nfrom statistics import mean\n\ncycles = load_log(\"dns_monitor.jsonl\")\n\nrts = [\n    s[\"avg_response_time_ms\"]\n    for c in cycles\n    for s in c[\"samples\"]\n    if s[\"avg_response_time_ms\"] is not None\n]\nalerts = [a for c in cycles for a in c.get(\"alerts\", [])]\n\nprint(f\"Cycles      : {len(cycles)}\")\nprint(f\"Avg RT (ms) : {mean(rts):.2f}\")\nprint(f\"Alerts      : {len(alerts)}\")\n```\n\n---\n\n### Network Base Commands\n\n#### ping\n\nCheck reachability using ICMP ping.\n\n```bash\nnadzoring network-base ping ADDRESSES...\n```\n\n```bash\nnadzoring network-base ping 8.8.8.8\nnadzoring network-base ping google.com cloudflare.com 1.1.1.1\nnadzoring network-base ping -o json github.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.ping_address import ping_addr\n\nprint(ping_addr(\"8.8.8.8\"))            # True\nprint(ping_addr(\"https://google.com\")) # True — URLs are normalised automatically\nprint(ping_addr(\"192.0.2.1\"))          # False — unreachable\n\n# Note: ICMP may be blocked by firewalls even for reachable hosts\n```\n\n---\n\n#### http-ping\n\nMeasure HTTP/HTTPS response timing and inspect headers.\n\n```bash\nnadzoring network-base http-ping [OPTIONS] URLS...\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--timeout` | Request timeout (seconds) | `10.0` |\n| `--no-ssl-verify` | Disable SSL certificate check | `False` |\n| `--no-redirects` | Do not follow redirects | `False` |\n| `--show-headers` | Include response headers | `False` |\n\nOutput includes: DNS time, TTFB, total download time, status code, content size, redirects.\n\n```bash\nnadzoring network-base http-ping https://example.com\nnadzoring network-base http-ping --show-headers https://github.com https://google.com\nnadzoring network-base http-ping --timeout 5 --no-ssl-verify https://self-signed.badssl.com\nnadzoring network-base http-ping -o csv --save http_metrics.csv https://api.github.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.http_ping import http_ping\n\nresult = http_ping(\"https://example.com\", timeout=10.0, include_headers=True)\n\nif result.error:\n    print(\"HTTP probe failed:\", result.error)\nelse:\n    print(f\"Status:  {result.status_code}\")\n    print(f\"DNS:     {result.dns_ms} ms\")\n    print(f\"TTFB:    {result.ttfb_ms} ms\")\n    print(f\"Total:   {result.total_ms} ms\")\n    print(f\"Size:    {result.content_length} bytes\")\n    if result.final_url:\n        print(f\"Redirect → {result.final_url}\")\n```\n\n---\n\n#### host-to-ip\n\nResolve hostnames to IP addresses with IPv4/IPv6 availability checks.\n\n```bash\nnadzoring network-base host-to-ip HOSTNAMES...\n```\n\n```bash\nnadzoring network-base host-to-ip google.com github.com cloudflare.com\nnadzoring network-base host-to-ip -o csv --save resolutions.csv example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.utils.validators import resolve_hostname\n\nip = resolve_hostname(\"example.com\")\nif ip is None:\n    print(\"Resolution failed\")\nelse:\n    print(ip)  # \"93.184.216.34\"\n\n# Validate IP format before resolving\nfrom nadzoring.utils.validators import validate_ip, validate_ipv4, validate_ipv6\n\nvalidate_ip(\"8.8.8.8\")    # True\nvalidate_ipv4(\"::1\")      # False\nvalidate_ipv6(\"::1\")      # True\n\n# Get router/gateway IP\nfrom nadzoring.network_base.router_ip import router_ip\ngateway = router_ip()         # '192.168.1.1' on most home networks\ngateway6 = router_ip(ipv6=True)\n```\n\n---\n\n#### parse-url\n\nParse a URL into its components (scheme, hostname, port, path, query, fragment, etc.).\n\n```bash\nnadzoring network-base parse-url URLS...\n```\n\n```bash\nnadzoring network-base parse-url https://example.com/path?q=1#section\nnadzoring network-base parse-url \"postgresql://user:pass@localhost:5432/db\"\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.parse_url import parse_url\n\nresult = parse_url(\"https://user:pass@example.com:8080/path?key=value#frag\")\nprint(result[\"protocol\"])   # 'https'\nprint(result[\"hostname\"])   # 'example.com'\nprint(result[\"port\"])       # 8080\nprint(result[\"username\"])   # 'user'\nprint(result[\"password\"])   # 'pass'\nprint(result[\"path\"])       # '/path'\nprint(result[\"query_params\"])  # [('key', 'value')]\nprint(result[\"fragment\"])   # 'frag'\n```\n\n---\n\n#### geolocation\n\nGet geographic location for IP addresses.\n\n```bash\nnadzoring network-base geolocation IPS...\n```\n\nOutput: latitude, longitude, country, city.\n\n```bash\nnadzoring network-base geolocation 8.8.8.8 1.1.1.1\nnadzoring network-base geolocation --save locations.json 8.8.8.8\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.geolocation_ip import geo_ip\n\nresult = geo_ip(\"8.8.8.8\")\n\nif not result:\n    # Empty dict returned on failure (private IP, rate-limit, network error)\n    print(\"Geolocation unavailable\")\nelse:\n    print(f\"{result['city']}, {result['country']}\")\n    print(f\"Coordinates: {result['lat']}, {result['lon']}\")\n```\n\n\u003e **Note:** ip-api.com rate-limits free callers to 45 requests per minute.\n\u003e Private/reserved IP addresses (e.g. `192.168.x.x`) return an empty dict.\n\n---\n\n#### params\n\nShow local network interface configuration.\n\n```bash\nnadzoring network-base params [OPTIONS]\n```\n\nOutput: interface name, IPv4, IPv6, gateway IP, MAC address, public IP.\n\n```bash\nnadzoring network-base params\nnadzoring network-base params -o json --save net_params.json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.network_params import network_param\n\ninfo = network_param()\nprint(info[\"IPv4 address\"])        # '192.168.1.42'\nprint(info[\"Router ip-address\"])   # '192.168.1.1'\nprint(info[\"MAC-address\"])         # '00:11:22:33:44:55'\nprint(info[\"Public IP address\"])   # your external IP\n```\n\n---\n\n#### port-scan\n\nScan for open TCP/UDP ports on one or more targets.\n\n```bash\nnadzoring network-base port-scan [OPTIONS] TARGETS...\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--mode` | `fast`, `full`, or `custom` | `fast` |\n| `--ports` | Port list or range, e.g. `22,80,443` or `1-1024` | None |\n| `--protocol` | `tcp` or `udp` | `tcp` |\n| `--timeout` | Socket timeout (seconds) | `2.0` |\n| `--workers` | Concurrent workers | `50` |\n| `--no-banner` | Disable banner grabbing | `False` |\n| `--show-closed` | Show closed ports | `False` |\n\nScan modes: **fast** = common ports · **full** = all 1–65535 · **custom** = your list or range.\n\n```bash\nnadzoring network-base port-scan example.com\nnadzoring network-base port-scan --mode full 192.168.1.1\nnadzoring network-base port-scan --mode custom --ports 22,80,443,8080 example.com\nnadzoring network-base port-scan --protocol udp --mode fast example.com\nnadzoring network-base port-scan -o json --save scan.json example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.port_scanner import ScanConfig, scan_ports\n\nconfig = ScanConfig(\n    targets=[\"example.com\"],\n    mode=\"fast\",\n    protocol=\"tcp\",\n    timeout=2.0,\n)\nresults = scan_ports(config)\n\nfor scan in results:\n    print(f\"Target: {scan.target}  ({scan.target_ip})\")\n    print(f\"Open ports: {scan.open_ports}\")\n    for port in scan.open_ports:\n        r = scan.results[port]\n        print(f\"  {port}/tcp  {r.service}  {r.response_time}ms\")\n        if r.banner:\n            print(f\"  Banner: {r.banner[:80]}\")\n```\n\n---\n\n#### detect-service\n\nActively connect to ports and detect actual running services by banner analysis.\n\n```bash\nnadzoring network-base detect-service [OPTIONS] TARGET PORTS...\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--timeout` | Connection timeout (seconds) | `3.0` |\n| `--no-probe` | Disable sending protocol-specific probes | `False` |\n\n```bash\n# Detect services on common ports\nnadzoring network-base detect-service example.com 80 443 22\n\n# Database ports with longer timeout\nnadzoring network-base detect-service --timeout 5 192.168.1.100 3306 5432 6379\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.service_detector import detect_service_on_host\n\n# Detect service on port 80\nresult = detect_service_on_host(\"example.com\", 80)\n\nif result.detected_service:\n    print(f\"Service: {result.detected_service} (method: {result.method})\")\n    print(f\"Banner: {result.banner}\")\nelse:\n    print(f\"Fallback guess: {result.guessed_service}\")\n    if result.error:\n        print(f\"Error: {result.error}\")\n```\n\n---\n\n#### port-service\n\nIdentify the service typically running on a port number.\n\n```bash\nnadzoring network-base port-service PORTS...\n```\n\n```bash\nnadzoring network-base port-service 80 443 22 53 3306\nnadzoring network-base port-service -o json 8080 5432 27017\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.service_on_port import get_service_on_port\n\nprint(get_service_on_port(80))    # 'http'\nprint(get_service_on_port(443))   # 'https'\nprint(get_service_on_port(22))    # 'ssh'\nprint(get_service_on_port(9999))  # 'unknown'\n```\n\n---\n\n#### whois\n\nLook up WHOIS registration data for domains or IP addresses.\n\n\u003e **Requires** the system `whois` utility:\n\u003e - Debian/Ubuntu: `sudo apt install whois`\n\u003e - macOS: `brew install whois`\n\u003e - RHEL/Fedora: `sudo dnf install whois`\n\n```bash\nnadzoring network-base whois [OPTIONS] TARGETS...\n```\n\n```bash\nnadzoring network-base whois example.com\nnadzoring network-base whois google.com cloudflare.com 8.8.8.8\nnadzoring network-base whois -o json --save whois_data.json github.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.whois_lookup import whois_lookup\n\nresult = whois_lookup(\"example.com\")\nprint(result[\"registrar\"])      # 'RESERVED-Internet Assigned Numbers Authority'\nprint(result[\"creation_date\"])  # '1995-08-14T04:00:00Z'\nprint(result[\"expiry_date\"])\nprint(result[\"name_servers\"])\nif result.get(\"error\"):\n    print(\"Error:\", result[\"error\"])  # whois not installed, lookup failed, etc.\n```\n\n---\n\n#### domain-info\n\nRetrieve 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.\n\n```bash\nnadzoring network-base domain-info [OPTIONS] DOMAINS...\n```\n\n```bash\nnadzoring network-base domain-info example.com\nnadzoring network-base domain-info google.com github.com cloudflare.com\nnadzoring network-base domain-info -o json --save domain_report.json example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.domain_info import get_domain_info\n\ninfo = get_domain_info(\"example.com\")\n\n# WHOIS registration data\nprint(info[\"whois\"][\"registrar\"])\nprint(info[\"whois\"][\"creation_date\"])\nprint(info[\"whois\"][\"expiry_date\"])\n\n# Resolved IP addresses\nprint(info[\"dns\"][\"ipv4\"])    # '93.184.216.34'\nprint(info[\"dns\"][\"ipv6\"])    # '2606:2800:220:1:248:1893:25c8:1946'\n\n# DNS records by type\nfor rtype, records in info[\"dns\"][\"records\"].items():\n    print(f\"  {rtype}: {records}\")\n\n# Geolocation of the primary IP\ngeo = info[\"geolocation\"]\nif geo:\n    print(f\"{geo['city']}, {geo['country']}  ({geo['lat']}, {geo['lon']})\")\n\n# Reverse DNS for the primary IP\nprint(info[\"reverse_dns\"])    # 'example.com' or None\n```\n\n---\n\n#### connections\n\nList active TCP/UDP network connections.\n\n```bash\nnadzoring network-base connections [OPTIONS]\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--protocol` | `-p` | Filter: `tcp`, `udp`, `all` | `all` |\n| `--state` | `-s` | State filter substring, e.g. `LISTEN` | None |\n| `--no-process` | | Skip PID/process info | `False` |\n\n```bash\nnadzoring network-base connections\nnadzoring network-base connections --protocol tcp --state LISTEN\nnadzoring network-base connections --protocol udp --no-process\nnadzoring network-base connections -o csv --save connections.csv\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.connections import get_connections\n\n# All connections\nconnections = get_connections()\n\n# Listening TCP sockets only\nlistening = get_connections(protocol=\"tcp\", state_filter=\"LISTEN\")\nfor conn in listening:\n    print(conn.protocol, conn.local_address, conn.state, conn.process)\n```\n\n---\n\n#### traceroute\n\nTrace the network path to a host.\n\n```bash\nnadzoring network-base traceroute [OPTIONS] TARGETS...\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--max-hops` | Maximum hops | `30` |\n| `--timeout` | Per-hop timeout (seconds) | `2.0` |\n| `--sudo` | Run with sudo (Linux) | `False` |\n\n\u003e **Linux privilege note:** `traceroute` needs raw-socket access.\n\u003e Either use `--sudo`, run as root, or: `sudo setcap cap_net_raw+ep $(which traceroute)`\n\u003e Nadzoring automatically falls back to `tracepath` (no root required) if traceroute fails.\n\n```bash\nnadzoring network-base traceroute google.com\nnadzoring network-base traceroute --max-hops 20 github.com cloudflare.com\nnadzoring network-base traceroute --sudo example.com\nnadzoring network-base traceroute -o html --save trace.html 8.8.8.8\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.traceroute import traceroute\n\nhops = traceroute(\"8.8.8.8\", max_hops=15)\nfor hop in hops:\n    rtts = [f\"{r}ms\" if r else \"*\" for r in hop.rtt_ms]\n    print(f\"{hop.hop:2}  {hop.ip or '*':16}  {' '.join(rtts)}\")\n```\n\n---\n\n#### route\n\nDisplay the system IP routing table.\n\n```bash\nnadzoring network-base route [OPTIONS]\n```\n\n```bash\nnadzoring network-base route\nnadzoring network-base route -o json\nnadzoring network-base route --save routing_table.json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.network_base.route_table import get_route_table\n\nroutes = get_route_table()\nfor route in routes:\n    print(route.destination, \"via\", route.gateway, \"dev\", route.interface)\n```\n\n---\n\n### Security Commands\n\nThe `security` group provides SSL/TLS certificate inspection, HTTP security header auditing, email security record validation, subdomain discovery, and continuous certificate monitoring.\n\n```bash\nnadzoring security --help\n```\n\n---\n\n#### security check-ssl\n\nInspect 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).\n\nBy 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.\n\n```bash\nnadzoring security check-ssl [OPTIONS] DOMAINS...\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--days-before` | `-d` | Days before expiry to flag as `warning` status | `7` |\n| `--no-verify` | | Disable certificate chain verification (falls back automatically) | `False` |\n| `--full` | | Show all certificate fields instead of compact summary | `False` |\n\n**Status values:**\n\n| Status | Meaning |\n|--------|---------|\n| `valid` | Certificate is valid and not near expiry |\n| `warning` | Fewer than `--days-before` days remaining |\n| `expired` | Certificate has already expired |\n| `error` | Could not connect or parse the certificate |\n\n```bash\n# Basic check — compact summary table\nnadzoring security check-ssl example.com\n\n# Check multiple domains with a 30-day warning window\nnadzoring security check-ssl --days-before 30 google.com github.com cloudflare.com\n\n# Check without verifying the certificate chain (useful for self-signed certs)\nnadzoring security check-ssl --no-verify internal.corp.example.com\n\n# Full details including SAN list, protocol support, chain info\nnadzoring security check-ssl --full ya.ru\n\n# Save results as JSON for further processing\nnadzoring security check-ssl -o json --save ssl_report.json example.com github.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.security.check_website_ssl_cert import (\n    check_ssl_certificate,\n    check_ssl_expiry,\n    check_ssl_expiry_with_fallback,\n)\n\n# Verified check (full certificate chain validation)\nresult = check_ssl_certificate(\"example.com\", days_before=14)\n\nprint(result[\"status\"])          # 'valid' | 'warning' | 'expired' | 'error'\nprint(result[\"remaining_days\"])  # e.g. 142\nprint(result[\"expiry_date\"])     # '2025-10-15T12:00:00+00:00'\nprint(result[\"verification\"])    # 'verified' | 'unverified' | 'failed'\n\n# Subject and issuer dicts\nprint(result[\"subject\"][\"CN\"])   # 'example.com'\nprint(result[\"issuer\"][\"CN\"])    # 'DigiCert TLS RSA SHA256 2020 CA1'\nprint(result[\"issuer\"][\"O\"])     # 'DigiCert Inc'\n\n# Subject Alternative Names\nfor san in result.get(\"san\", []):\n    print(san)                   # 'DNS:example.com', 'DNS:www.example.com', ...\n\n# Domain matching\nprint(result[\"domain_match\"])       # True\nprint(result[\"matched_names\"])      # ['DNS:example.com']\n\n# Public key info\nkey = result[\"public_key\"]\nprint(key[\"algorithm\"])             # 'RSA' | 'EC' | 'Ed25519' | ...\nprint(key.get(\"key_size\"))          # 2048 (RSA/DSA)\nprint(key.get(\"curve\"))             # 'secp256r1' (EC)\nprint(key[\"strength\"])              # 'weak' | 'good' | 'strong'\n\n# Protocol support (TLSv1.0 – TLSv1.3)\nprotos = result[\"protocols\"]\nprint(protos[\"supported\"])          # ['TLSv1.2', 'TLSv1.3']\nprint(protos[\"has_outdated\"])       # False\n\n# Chain info (only when verify=True)\nprint(result.get(\"chain_length\"))   # 3\nprint(result.get(\"chain_valid\"))    # True\n\n# Simplified expiry-only check\nresult = check_ssl_expiry(\"example.com\")\n\n# Automatic fallback to unverified mode if chain check fails\nresult = check_ssl_expiry_with_fallback(\"self-signed.badssl.com\")\nprint(result[\"verification\"])       # 'unverified' when fallback was used\n```\n\n---\n\n#### security check-headers\n\nAnalyse 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.\n\n```bash\nnadzoring security check-headers [OPTIONS] URLS...\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--timeout` | Request timeout in seconds | `10.0` |\n| `--no-verify` | Disable SSL certificate verification | `False` |\n\n**Checked security headers:**\n\n| Header | Purpose |\n|--------|---------|\n| `Strict-Transport-Security` | Enforce HTTPS (HSTS) |\n| `Content-Security-Policy` | Mitigate XSS and injection attacks |\n| `X-Content-Type-Options` | Prevent MIME-type sniffing |\n| `X-Frame-Options` | Prevent clickjacking |\n| `X-XSS-Protection` | Legacy XSS filter (deprecated) |\n| `Referrer-Policy` | Control referrer information leakage |\n| `Permissions-Policy` | Restrict browser feature access |\n| `Cross-Origin-Embedder-Policy` | Isolate cross-origin resources |\n| `Cross-Origin-Opener-Policy` | Isolate browsing context |\n| `Cross-Origin-Resource-Policy` | Control cross-origin resource sharing |\n| `Cache-Control` | Prevent caching of sensitive responses |\n\n```bash\n# Check a single URL\nnadzoring security check-headers https://example.com\n\n# Check multiple URLs and save results\nnadzoring security check-headers https://google.com https://github.com https://cloudflare.com\n\n# Skip SSL verification for internal/self-signed endpoints\nnadzoring security check-headers --no-verify https://internal.corp.example.com\n\n# Export as JSON for CI integration or dashboards\nnadzoring security check-headers -o json --save headers_audit.json https://example.com\n\n# Adjust timeout for slow servers\nnadzoring security check-headers --timeout 20 https://slow-api.example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.security.http_headers import check_http_security_headers\n\nresult = check_http_security_headers(\"https://example.com\", timeout=10.0)\n\nprint(result[\"url\"])          # final URL after redirects\nprint(result[\"status_code\"])  # 200\nprint(result[\"score\"])        # 0–100 coverage score\n\n# Present security headers\nfor header, value in result[\"present\"].items():\n    print(f\"  ✓ {header}: {value}\")\n\n# Missing security headers\nfor header in result[\"missing\"]:\n    print(f\"  ✗ {header}\")\n\n# Deprecated headers found in the response\nfor header in result[\"deprecated\"]:\n    print(f\"  ⚠ deprecated: {header}\")\n\n# Information-leaking headers\nfor header, value in result[\"leaking\"].items():\n    print(f\"  ⚠ leaking: {header} = {value}\")\n\nif result[\"error\"]:\n    print(\"Request failed:\", result[\"error\"])\n```\n\n---\n\n#### security check-email\n\nValidate 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.\n\n\u003e **Note:** Requires `dig` or `nslookup` to be available on the system, or `dnspython` installed in the Python environment (`pip install dnspython`). `dnspython` is preferred as it handles multi-chunk TXT records reliably.\n\n```bash\nnadzoring security check-email [OPTIONS] DOMAINS...\n```\n\n```bash\n# Check a single domain\nnadzoring security check-email gmail.com\n\n# Check multiple domains at once\nnadzoring security check-email google.com github.com cloudflare.com\n\n# Export full JSON report\nnadzoring security check-email -o json --save email_security.json example.com\n\n# Quiet mode for scripting — results only, no progress bars\nnadzoring security check-email --quiet example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.security.email_security import check_email_security\n\nresult = check_email_security(\"example.com\")\n\nprint(result[\"domain\"])\n\n# Overall score: 0 = none of SPF/DKIM/DMARC found, 3 = all found\nprint(result[\"overall_score\"])  # e.g. 3\n\n# SPF analysis\nspf = result[\"spf\"]\nprint(spf[\"found\"])             # True\nprint(spf[\"record\"])            # 'v=spf1 include:_spf.example.com ~all'\nprint(spf[\"mechanisms\"])        # ['include:_spf.example.com']\nprint(spf[\"all_qualifier\"])     # '~'  (softfail — recommended minimum)\nfor issue in spf[\"issues\"]:\n    print(\"  SPF issue:\", issue)\n\n# DKIM analysis\ndkim = result[\"dkim\"]\nprint(dkim[\"found\"])            # True\nprint(dkim[\"selectors_checked\"])  # list of 13 common selectors probed\nfor selector, record in dkim[\"records\"].items():\n    print(f\"  DKIM selector '{selector}': {record[:60]}...\")\nfor issue in dkim[\"issues\"]:\n    print(\"  DKIM issue:\", issue)\n\n# DMARC analysis\ndmarc = result[\"dmarc\"]\nprint(dmarc[\"found\"])           # True\nprint(dmarc[\"record\"])          # 'v=DMARC1; p=reject; rua=mailto:...'\nprint(dmarc[\"policy\"])          # 'none' | 'quarantine' | 'reject'\nprint(dmarc[\"subdomain_policy\"])  # sp= tag value or None\nprint(dmarc[\"pct\"])             # percentage of messages the policy applies to\nprint(dmarc[\"rua\"])             # aggregate report addresses\nprint(dmarc[\"ruf\"])             # forensic report addresses\nfor issue in dmarc[\"issues\"]:\n    print(\"  DMARC issue:\", issue)\n\n# All issues aggregated across SPF + DKIM + DMARC\nfor issue in result[\"all_issues\"]:\n    print(\"Issue:\", issue)\n```\n\n**Common issues reported:**\n\n| Category | Issue |\n|----------|-------|\n| SPF | No SPF record found |\n| SPF | Multiple SPF records (RFC violation) |\n| SPF | `+all` allows any sender (insecure) |\n| SPF | Missing `all` mechanism |\n| SPF | Exceeds 10 DNS lookup limit |\n| DKIM | No DKIM records found for common selectors |\n| DMARC | No DMARC record found |\n| DMARC | Policy `p=none` does not protect against spoofing |\n| DMARC | No aggregate report address (`rua=`) configured |\n| DMARC | Policy applies to less than 100% of messages |\n\n---\n\n#### security subdomains\n\nDiscover subdomains for a target domain using two complementary methods: certificate transparency (CT) log queries via [crt.sh](https://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.\n\n```bash\nnadzoring security subdomains [OPTIONS] DOMAIN\n```\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--wordlist` | Path to a custom wordlist file (one prefix per line) | Built-in 80+ prefix list |\n| `--threads` | Number of concurrent DNS resolution threads | `20` |\n| `--timeout` | Per-host DNS resolution timeout in seconds | `3.0` |\n| `--no-bruteforce` | Skip DNS brute-force entirely, use CT logs only | `False` |\n\n```bash\n# Discover subdomains using CT logs + built-in wordlist\nnadzoring security subdomains example.com\n\n# CT logs only — no brute-force DNS\nnadzoring security subdomains --no-bruteforce example.com\n\n# Use a custom wordlist file\nnadzoring security subdomains --wordlist /path/to/subdomains.txt example.com\n\n# Increase concurrency and timeout for faster / more thorough scanning\nnadzoring security subdomains --threads 50 --timeout 5 example.com\n\n# Export results as JSON\nnadzoring security subdomains -o json --save subdomains.json example.com\n\n# Quiet mode for scripting\nnadzoring security subdomains --quiet example.com\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.security.subdomain_scan import scan_subdomains\n\n# CT logs + built-in wordlist brute-force\nresults = scan_subdomains(\"example.com\", max_threads=20, timeout=3.0)\n\nfor r in results:\n    print(f\"{r['subdomain']:40}  {r['ip']:16}  [{r['source']}]\")\n\n# CT logs only\nresults = scan_subdomains(\"example.com\", wordlist_path=\"\")\n\n# Custom wordlist\nresults = scan_subdomains(\n    \"example.com\",\n    wordlist_path=\"/path/to/custom_wordlist.txt\",\n    max_threads=50,\n    timeout=5.0,\n)\n\n# Source values: 'ct_log' | 'brute_force'\nct_found     = [r for r in results if r[\"source\"] == \"ct_log\"]\nbrute_found  = [r for r in results if r[\"source\"] == \"brute_force\"]\nprint(f\"CT log: {len(ct_found)}  Brute-force: {len(brute_found)}\")\n```\n\n**Built-in wordlist includes prefixes for:**\ncommon 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.\n\n---\n\n#### security watch-ssl\n\nContinuously 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.\n\n```bash\nnadzoring security watch-ssl [OPTIONS] DOMAINS...\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--interval` | `-i` | Seconds between full check cycles | `3600` |\n| `--cycles` | `-c` | Number of cycles to run (`0` = run indefinitely) | `0` |\n| `--days-before` | `-d` | Days before expiry to trigger a warning alert | `7` |\n\n```bash\n# Monitor ya.ru indefinitely, check every hour\nnadzoring security watch-ssl ya.ru\n\n# Monitor multiple domains with a 14-day warning threshold\nnadzoring security watch-ssl --days-before 14 example.com github.com cloudflare.com\n\n# Run exactly 5 check cycles with a 60-second interval (useful for CI/testing)\nnadzoring security watch-ssl --cycles 5 --interval 60 example.com\n\n# Frequent checks — every 5 minutes — for a critical service\nnadzoring security watch-ssl --interval 300 api.example.com\n\n# Save all check results as JSON after monitoring ends\nnadzoring security watch-ssl --cycles 3 -o json --save ssl_history.json example.com\n\n# Quiet mode — suppress progress output, emit only alert lines\nnadzoring security watch-ssl --quiet --cycles 10 --interval 30 example.com\n```\n\n**Alert events fired:**\n\n| Trigger | Message example |\n|---------|-----------------|\n| Check failure | `Check failed: [Errno 111] Connection refused` |\n| Expired certificate | `Certificate has EXPIRED` |\n| Near expiry | `Certificate expires in 5 day(s)` |\n| Certificate changed | `Certificate changed: expiry 2025-06-01 → 2025-12-01` |\n\n**Python API:**\n\n```python\nfrom nadzoring.security.ssl_monitor import SSLMonitor\n\n# Create monitor for multiple domains\nmonitor = SSLMonitor(\n    domains=[\"example.com\", \"github.com\", \"cloudflare.com\"],\n    interval=3600,   # seconds between cycles\n    days_before=14,  # alert when fewer than 14 days remain\n)\n\n# Custom alert handler\ndef on_alert(domain: str, message: str) -\u003e None:\n    print(f\"ALERT  {domain}: {message}\")\n    # send to Slack, PagerDuty, email, etc.\n\nmonitor.set_alert_callback(on_alert)\n\n# Run a fixed number of cycles (blocking)\nresults = monitor.run_cycles(cycles=5)\n\n# Or run indefinitely until KeyboardInterrupt\ntry:\n    monitor.run()\nexcept KeyboardInterrupt:\n    pass\n\n# Retrieve full history of all check results\nfor entry in monitor.history():\n    print(entry[\"domain\"], entry[\"status\"], entry[\"remaining_days\"], entry[\"checked_at\"])\n```\n\n---\n\n### ARP Commands\n\n#### arp cache\n\nShow the current ARP cache table (IP-to-MAC mappings).\n\n```bash\nnadzoring arp cache [OPTIONS]\n```\n\n```bash\nnadzoring arp cache\nnadzoring arp cache -o csv --save arp_cache.csv\nnadzoring arp cache -o json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError\n\ntry:\n    cache = ARPCache()\n    entries = cache.get_cache()\nexcept ARPCacheRetrievalError as exc:\n    print(\"Cannot read ARP cache:\", exc)\nelse:\n    for entry in entries:\n        print(\n            f\"{entry.ip_address}  \"\n            f\"{entry.mac_address or '(incomplete)'}  \"\n            f\"{entry.interface}  \"\n            f\"{entry.state.value}\"\n        )\n```\n\n---\n\n#### arp detect-spoofing\n\nStatically detect ARP spoofing by analyzing the current ARP cache.\n\n```bash\nnadzoring arp detect-spoofing [OPTIONS] [INTERFACES]...\n```\n\nDetects: duplicate MAC across IPs (`duplicate_mac`) and duplicate IP with multiple MACs (`duplicate_ip`).\n\n```bash\nnadzoring arp detect-spoofing\nnadzoring arp detect-spoofing eth0 wlan0\nnadzoring arp detect-spoofing -o json --save spoofing_alerts.json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError\nfrom nadzoring.arp.detector import ARPSpoofingDetector\n\ntry:\n    cache = ARPCache()\n    detector = ARPSpoofingDetector(cache)\n    alerts = detector.detect()\nexcept ARPCacheRetrievalError as exc:\n    print(\"ARP cache error:\", exc)\nelse:\n    if not alerts:\n        print(\"No spoofing detected\")\n    for alert in alerts:\n        print(f\"[{alert.alert_type}] {alert.description}\")\n```\n\n---\n\n#### arp monitor-spoofing\n\nMonitor live network traffic for ARP spoofing in real time (requires root/admin).\n\n```bash\nnadzoring arp monitor-spoofing [OPTIONS]\n```\n\n| Option | Short | Description | Default |\n|--------|-------|-------------|---------|\n| `--interface` | `-i` | Interface to monitor | All |\n| `--count` | `-c` | Packets to capture | `10` |\n| `--timeout` | `-t` | Capture timeout (seconds) | `30` |\n\n```bash\nnadzoring arp monitor-spoofing\nnadzoring arp monitor-spoofing --interface eth0 --count 200 --timeout 60\nnadzoring arp monitor-spoofing -o json --save arp_alerts.json\n```\n\n**Python API:**\n\n```python\nfrom nadzoring.arp.realtime import ARPRealtimeDetector\n\ndetector = ARPRealtimeDetector()\nalerts = detector.monitor(interface=\"eth0\", count=100, timeout=30)\nfor alert in alerts:\n    print(f\"{alert['timestamp']}  {alert['message']}\")\n    print(f\"  src_ip={alert['src_ip']}  src_mac={alert['src_mac']}\")\n\n# Get monitoring stats\nstats = detector.get_stats()\nprint(f\"Processed: {stats['packets_processed']}  Alerts: {stats['alerts_generated']}\")\n\n# Custom callback for integration with external systems\ndef on_packet(packet, alert):\n    if alert:\n        print(\"ALERT:\", alert)  # integrate with your alerting pipeline here\n\ndetector.monitor(interface=None, count=0, timeout=0, packet_callback=on_packet)\n```\n\n---\n\n## Output Formats\n\nUse `-o` / `--output` to change the output format:\n\n| Format | Description |\n|--------|-------------|\n| `table` | Rich terminal table (default) |\n| `json` | JSON array, suitable for scripting |\n| `csv` | Comma-separated values |\n| `html` | Complete HTML page with CSS |\n| `html_table` | HTML table fragment only |\n| `yaml` | YAML format |\n\n```bash\nnadzoring dns resolve -o json example.com\nnadzoring dns health -o html --save health.html example.com\nnadzoring network-base connections -o csv --save conns.csv\nnadzoring security check-ssl -o json example.com\nnadzoring security check-headers -o json --save headers.json https://example.com\nnadzoring security check-email -o json --save email_audit.json example.com\nnadzoring security subdomains -o json --save subdomains.json example.com\n```\n\n## Saving Results\n\n```bash\nnadzoring dns check -o html --save dns_report.html example.com\nnadzoring dns compare -o csv --save comparison.csv google.com\nnadzoring dns poisoning -o json --save poisoning.json example.com\nnadzoring network-base port-scan -o json --save scan.json example.com\nnadzoring network-base domain-info -o json --save domain_info.json example.com\nnadzoring security check-ssl -o json --save ssl_report.json example.com\nnadzoring security check-headers -o json --save headers_report.json https://example.com\nnadzoring security check-email -o json --save email_security.json example.com\nnadzoring security subdomains -o json --save subdomains.json example.com\nnadzoring arp cache -o csv --save arp.csv\n```\n\n## Logging Levels\n\n| Mode | Flag | Behaviour |\n|------|------|-----------|\n| Normal | (none) | Warnings + progress bars |\n| Verbose | `--verbose` | Debug logs + execution timing |\n| Quiet | `--quiet` | Results only — ideal for scripting |\n\n---\n\n## Error Handling\n\nEvery 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.\n\n**DNS result-dict pattern** — check `result[\"error\"]` before using `result[\"records\"]`:\n\n```python\nfrom nadzoring.dns_lookup.utils import resolve_with_timer\n\nresult = resolve_with_timer(\"example.com\", \"A\")\nif result[\"error\"]:\n    # \"Domain does not exist\"  — NXDOMAIN\n    # \"No A records\"           — record type not present\n    # \"Query timeout\"          — nameserver did not respond\n    print(\"DNS error:\", result[\"error\"])\nelse:\n    print(result[\"records\"])\n    print(f\"RTT: {result['response_time']} ms\")\n```\n\n**Return-None / empty-dict pattern** — used where a result cannot be partially valid:\n\n```python\nfrom nadzoring.network_base.geolocation_ip import geo_ip\n\nresult = geo_ip(\"8.8.8.8\")\nif not result:\n    print(\"Geolocation unavailable\")\nelse:\n    print(f\"{result['city']}, {result['country']}\")\n```\n\n**Exception pattern** — used only for system-level failures (missing commands, unsupported OS):\n\n```python\nfrom nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError\n\ntry:\n    cache = ARPCache()\n    entries = cache.get_cache()\nexcept ARPCacheRetrievalError as exc:\n    print(\"Cannot read ARP cache:\", exc)\n```\n\nAll library exceptions inherit from `nadzoring.utils.errors.NadzoringError` and can be caught at any granularity:\n\n```python\nfrom nadzoring.utils.errors import NadzoringError, DNSError, NetworkError, ARPError\n```\n\nFor a complete reference of all error patterns and possible error values, see the [Error Handling guide](https://alexeev-prog.github.io/nadzoring/main/error_handling.html) in the documentation.\n\n---\n\n## Python API\n\nNadzoring can be used as a Python library — all functionality is accessible programmatically without invoking the CLI.\n\n### DNS Lookup API\n\n```python\nfrom nadzoring.dns_lookup.utils import resolve_with_timer, get_public_dns_servers\n\n# Resolve any record type\nresult = resolve_with_timer(\"example.com\", \"MX\", include_ttl=True)\nif result[\"error\"]:\n    print(\"Error:\", result[\"error\"])\nelse:\n    print(result[\"records\"])       # ['10 mail.example.com']\n    print(result[\"ttl\"])           # 3600\n    print(result[\"response_time\"]) # 45.2\n\n# List built-in public servers\nservers = get_public_dns_servers()  # ['8.8.8.8', '1.1.1.1', ...]\n```\n\n### Reverse DNS API\n\n```python\nfrom nadzoring.dns_lookup.reverse import reverse_dns\n\n# Standard reverse lookup\nresult = reverse_dns(\"8.8.8.8\")\nif result[\"error\"]:\n    # Possible values: 'No PTR record', 'No reverse DNS',\n    # 'Query timeout', 'Invalid IP address: ...'\n    print(\"Failed:\", result[\"error\"])\nelse:\n    print(result[\"hostname\"])  # 'dns.google'\n\n# With a custom nameserver\nresult = reverse_dns(\"1.1.1.1\", nameserver=\"8.8.8.8\")\nprint(result[\"hostname\"])  # 'one.one.one.one'\n\n# Compact error-safe pattern\nhostname = result[\"hostname\"] or f\"[{result['error']}]\"\n```\n\n### Network Base API\n\n```python\nfrom nadzoring.network_base.ping_address import ping_addr\nfrom nadzoring.network_base.http_ping import http_ping\nfrom nadzoring.network_base.geolocation_ip import geo_ip\nfrom nadzoring.network_base.traceroute import traceroute\nfrom nadzoring.network_base.connections import get_connections\nfrom nadzoring.network_base.route_table import get_route_table\nfrom nadzoring.network_base.network_params import network_param\nfrom nadzoring.network_base.whois_lookup import whois_lookup\nfrom nadzoring.network_base.domain_info import get_domain_info\nfrom nadzoring.network_base.port_scanner import ScanConfig, scan_ports\nfrom nadzoring.network_base.service_detector import detect_service_on_host\nfrom nadzoring.network_base.parse_url import parse_url\n\n# Ping — returns bool\nalive = ping_addr(\"8.8.8.8\")\n\n# HTTP probe — check .error before reading timing fields\nr = http_ping(\"https://example.com\")\nif not r.error:\n    print(r.ttfb_ms, r.status_code)\n\n# URL parsing\nparsed = parse_url(\"https://example.com/path?q=1\")\nprint(parsed[\"hostname\"], parsed[\"path\"])\n\n# Geolocation — returns {} on failure\nloc = geo_ip(\"8.8.8.8\")\nif loc:\n    print(loc[\"country\"], loc[\"city\"])\n\n# Comprehensive domain info — WHOIS + DNS + geo + reverse DNS\ninfo = get_domain_info(\"example.com\")\nprint(info[\"whois\"][\"registrar\"])\nprint(info[\"dns\"][\"ipv4\"])\nprint(info[\"geolocation\"][\"country\"])\nprint(info[\"reverse_dns\"])\n\n# Traceroute\nfor hop in traceroute(\"8.8.8.8\", max_hops=10):\n    print(hop.hop, hop.ip, hop.rtt_ms)\n\n# Active connections\nfor conn in get_connections(protocol=\"tcp\", state_filter=\"ESTABLISHED\"):\n    print(conn.local_address, \"-\u003e\", conn.remote_address)\n\n# Port scan\nconfig = ScanConfig(targets=[\"example.com\"], mode=\"fast\", timeout=2.0)\nfor result in scan_ports(config):\n    print(\"Open ports:\", result.open_ports)\n\n# Service detection on a specific port\nservice = detect_service_on_host(\"example.com\", 80)\nprint(service.detected_service or service.guessed_service)\n```\n\n### Security API\n\n```python\nfrom nadzoring.security.check_website_ssl_cert import (\n    check_ssl_certificate,\n    check_ssl_expiry,\n    check_ssl_expiry_with_fallback,\n)\nfrom nadzoring.security.http_headers import check_http_security_headers\nfrom nadzoring.security.email_security import check_email_security\nfrom nadzoring.security.subdomain_scan import scan_subdomains\nfrom nadzoring.security.ssl_monitor import SSLMonitor\n\n# SSL/TLS certificate check\nresult = check_ssl_certificate(\"example.com\", days_before=14)\nprint(result[\"status\"], result[\"remaining_days\"])\nprint(result[\"protocols\"][\"supported\"])   # ['TLSv1.2', 'TLSv1.3']\nprint(result[\"public_key\"][\"strength\"])   # 'good'\n\n# Fallback mode for self-signed / problematic certs\nresult = check_ssl_expiry_with_fallback(\"self-signed.example.com\")\n\n# HTTP security header audit\nheaders = check_http_security_headers(\"https://example.com\")\nprint(headers[\"score\"])     # 0–100\nprint(headers[\"missing\"])   # list of absent recommended headers\nprint(headers[\"leaking\"])   # {'Server': 'nginx/1.18.0'}\n\n# Email security (SPF / DKIM / DMARC)\nemail = check_email_security(\"example.com\")\nprint(email[\"overall_score\"])           # 0–3\nprint(email[\"spf\"][\"all_qualifier\"])    # '~' (softfail)\nprint(email[\"dmarc\"][\"policy\"])         # 'reject'\nprint(email[\"all_issues\"])              # aggregated issue list\n\n# Subdomain discovery\nsubdomains = scan_subdomains(\n    \"example.com\",\n    max_threads=30,\n    timeout=4.0,\n)\nfor s in subdomains:\n    print(s[\"subdomain\"], s[\"ip\"], s[\"source\"])\n\n# Continuous SSL monitoring\nmonitor = SSLMonitor([\"example.com\", \"github.com\"], interval=3600, days_before=14)\nmonitor.set_alert_callback(lambda domain, msg: print(f\"ALERT {domain}: {msg}\"))\nresults = monitor.run_cycles(cycles=3)\nfor r in monitor.history():\n    print(r[\"domain\"], r[\"status\"], r[\"remaining_days\"])\n```\n\n### ARP API\n\n```python\nfrom nadzoring.arp.cache import ARPCache, ARPCacheRetrievalError\nfrom nadzoring.arp.detector import ARPSpoofingDetector\nfrom nadzoring.arp.realtime import ARPRealtimeDetector\n\n# ARP cache — raises ARPCacheRetrievalError on system failure\ntry:\n    cache = ARPCache()\n    for entry in cache.get_cache():\n        print(entry.ip_address, entry.mac_address, entry.state.value)\nexcept ARPCacheRetrievalError as exc:\n    print(\"ARP cache unavailable:\", exc)\n\n# Static spoofing detection\ndetector = ARPSpoofingDetector(cache)\nfor alert in detector.detect():\n    print(alert.alert_type, alert.description)\n\n# Real-time monitoring\nrt = ARPRealtimeDetector()\nalerts = rt.monitor(interface=\"eth0\", count=50, timeout=30)\nprint(rt.get_stats())\n```\n\n---\n\n## Examples\n\n### DNS Diagnostics\n\n```bash\nnadzoring dns health example.com\nnadzoring dns trace example.com\nnadzoring dns compare -t A -t MX example.com\nnadzoring dns check -t ALL -v example.com\n```\n\n### Reverse DNS Batch Lookup\n\n```bash\n# Look up multiple IPs at once\nnadzoring dns reverse 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222\n\n# Save results\nnadzoring dns reverse -o json --save ptr_records.json 8.8.8.8 1.1.1.1\n```\n\n### DNS Poisoning Detection\n\n```bash\nnadzoring dns poisoning -v twitter.com\nnadzoring dns poisoning -c 8.8.8.8 -c 1.1.1.1 example.com\nnadzoring dns poisoning -o html --save poisoning_report.html github.com\n```\n\n### DNS Performance Benchmarking\n\n```bash\nnadzoring dns benchmark --queries 20 --parallel\nnadzoring dns benchmark -s 8.8.8.8 -s 1.1.1.1 -s 208.67.222.222 -s 9.9.9.9\nnadzoring dns benchmark -t MX -d gmail.com --queries 15\n```\n\n### Port Scanning\n\n```bash\nnadzoring network-base port-scan --mode full --protocol tcp example.com\nnadzoring network-base port-scan --mode custom --ports 20-1024 example.com\nnadzoring network-base port-scan -o csv --save network_scan.csv 192.168.1.1\n```\n\n### HTTP Service Probing\n\n```bash\nnadzoring network-base http-ping --show-headers https://api.example.com/health\nnadzoring network-base http-ping https://google.com https://cloudflare.com https://github.com\nnadzoring network-base http-ping -o csv --save http_metrics.csv https://example.com\n```\n\n### SSL/TLS Certificate Auditing\n\n```bash\n# Quick check — compact summary\nnadzoring security check-ssl example.com\n\n# Check multiple domains with a 30-day warning window\nnadzoring security check-ssl --days-before 30 google.com github.com cloudflare.com ya.ru\n\n# Full details including SAN list, protocol versions, chain info\nnadzoring security check-ssl --full example.com\n\n# Check without verifying the chain (self-signed / internal CA)\nnadzoring security check-ssl --no-verify https://internal.corp.example.com\n\n# Save full report as JSON\nnadzoring security check-ssl --full -o json --save ssl_audit.json example.com github.com\n```\n\n### HTTP Security Header Auditing\n\n```bash\n# Single URL\nnadzoring security check-headers https://example.com\n\n# Batch audit of several services\nnadzoring security check-headers \\\n    https://api.example.com \\\n    https://admin.example.com \\\n    https://static.example.com\n\n# Skip SSL verification for internal endpoints\nnadzoring security check-headers --no-verify https://internal.corp.example.com\n\n# Export as JSON for CI / dashboard integration\nnadzoring security check-headers -o json --save headers_audit.json https://example.com\n```\n\n### Email Security Validation\n\n```bash\n# Check a single domain\nnadzoring security check-email example.com\n\n# Audit multiple domains\nnadzoring security check-email gmail.com outlook.com yahoo.com proton.me\n\n# Export full JSON report with SPF/DKIM/DMARC details\nnadzoring security check-email -o json --save email_audit.json example.com\n\n# Check all your owned domains at once\nnadzoring security check-email corp.example.com mail.example.com newsletter.example.com\n```\n\n### Subdomain Discovery\n\n```bash\n# CT logs + built-in wordlist brute-force\nnadzoring security subdomains example.com\n\n# CT logs only — faster, no DNS brute-force\nnadzoring security subdomains --no-bruteforce example.com\n\n# Custom wordlist and more threads for deeper scanning\nnadzoring security subdomains \\\n    --wordlist /path/to/big-wordlist.txt \\\n    --threads 100 \\\n    --timeout 5 \\\n    example.com\n\n# Save discovered subdomains as JSON\nnadzoring security subdomains -o json --save subdomains.json example.com\n```\n\n### Continuous SSL Monitoring\n\n```bash\n# Monitor a single domain indefinitely (Ctrl-C to stop)\nnadzoring security watch-ssl example.com\n\n# Monitor multiple domains with a 14-day warning threshold\nnadzoring security watch-ssl --days-before 14 \\\n    example.com github.com cloudflare.com api.example.com\n\n# Check every 5 minutes for a critical service\nnadzoring security watch-ssl --interval 300 api.example.com\n\n# Run 10 cycles with a 60-second interval and save all results\nnadzoring security watch-ssl --cycles 10 --interval 60 \\\n    -o json --save ssl_monitor_history.json example.com\n```\n\n### ARP Spoofing Detection\n\n```bash\nnadzoring arp detect-spoofing eth0\nnadzoring arp monitor-spoofing --interface eth0 --timeout 60\nnadzoring arp monitor-spoofing -o json --save arp_alerts.json\n```\n\n### Network Path Analysis\n\n```bash\nnadzoring network-base traceroute --max-hops 30 github.com\nnadzoring network-base traceroute google.com cloudflare.com amazon.com\nnadzoring network-base route\nnadzoring network-base connections --state LISTEN\n```\n\n### Complete Network Diagnostics\n\n```bash\nnadzoring network-base params -v\nnadzoring network-base host-to-ip google.com cloudflare.com github.com\nnadzoring network-base ping 8.8.8.8 1.1.1.1 google.com\nnadzoring network-base geolocation 8.8.8.8 1.1.1.1\nnadzoring network-base domain-info example.com\nnadzoring network-base port-scan --mode fast example.com\nnadzoring network-base traceroute cloudflare.com\nnadzoring security check-ssl example.com\nnadzoring security check-headers https://example.com\nnadzoring security check-email example.com\nnadzoring arp cache\n```\n\n### Automated DNS Server Monitoring\n\nThis section covers three integration approaches for continuous monitoring:\na **shell script** for use with cron/systemd, a **Python script** for\nin-process loops with alerting, and **scheduling setup** for both Linux and Windows.\n\n#### Shell script with alerting thresholds\n\nSave as `dns_monitor.sh` and make executable (`chmod +x dns_monitor.sh`):\n\n```bash\n#!/bin/bash\n# dns_monitor.sh — continuous DNS health and performance monitor\n# Designed to be called by cron or systemd timer.\n\nset -euo pipefail\n\n# ── Configuration ────────────────────────────────────────────────────────────\nTARGET_DOMAIN=\"${1:-example.com}\"\nDNS_SERVER=\"${2:-8.8.8.8}\"\nREPORT_DIR=\"${DNS_MONITOR_DIR:-/var/log/nadzoring}\"\nALERT_EMAIL=\"${DNS_ALERT_EMAIL:-}\"        # leave empty to disable email alerts\nHEALTH_THRESHOLD=70                       # score below this triggers an alert\nBENCHMARK_QUERIES=5                       # queries per server for each run\n\n# ── Setup ────────────────────────────────────────────────────────────────────\nmkdir -p \"$REPORT_DIR\"\nTIMESTAMP=$(date +%Y%m%d_%H%M%S)\nLOG_FILE=\"$REPORT_DIR/monitor_${TIMESTAMP}.log\"\nSUMMARY_FILE=\"$REPORT_DIR/summary.jsonl\"  # append-only JSONL for trend analysis\n\nlog() { echo \"[$(date '+%Y-%m-%d %H:%M:%S')] $*\" | tee -a \"$LOG_FILE\"; }\nalert() {\n    log \"ALERT: $*\"\n    if [[ -n \"$ALERT_EMAIL\" ]]; then\n        echo \"$*\" | mail -s \"[nadzoring] DNS alert: $TARGET_DOMAIN\" \"$ALERT_EMAIL\" || true\n    fi\n}\n\n# ── DNS Health Check ─────────────────────────────────────────────────────────\nlog \"Starting DNS health check for $TARGET_DOMAIN via $DNS_SERVER\"\n\nHEALTH_JSON=\"$REPORT_DIR/health_${TIMESTAMP}.json\"\nif nadzoring dns health -n \"$DNS_SERVER\" -o json --quiet \\\n        --save \"$HEALTH_JSON\" \"$TARGET_DOMAIN\"; then\n    SCORE=$(python3 -c \"import json,sys; d=json.load(open('$HEALTH_JSON')); print(d.get('score',0))\" 2\u003e/dev/null || echo 0)\n    STATUS=$(python3 -c \"import json,sys; d=json.load(open('$HEALTH_JSON')); print(d.get('status','unknown'))\" 2\u003e/dev/null || echo unknown)\n    log \"Health score: $SCORE ($STATUS)\"\n\n    if [[ \"$SCORE\" -lt \"$HEALTH_THRESHOLD\" ]]; then\n        alert \"Health score $SCORE is below threshold $HEALTH_THRESHOLD (status: $STATUS) for $TARGET_DOMAIN\"\n    fi\nelse\n    alert \"dns health check command failed for $TARGET_DOMAIN\"\n    SCORE=0; STATUS=\"error\"\nfi\n\n# ── DNS Benchmark ────────────────────────────────────────────────────────────\nBENCH_JSON=\"$REPORT_DIR/benchmark_${TIMESTAMP}.json\"\nif nadzoring dns benchmark -s \"$DNS_SERVER\" -s 8.8.8.8 -s 1.1.1.1 \\\n        -d \"$TARGET_DOMAIN\" -q \"$BENCHMARK_QUERIES\" \\\n        -o json --quiet --save \"$BENCH_JSON\"; then\n    AVG_MS=$(python3 -c \"\nimport json\ndata = json.load(open('$BENCH_JSON'))\ntarget = next((r for r in data if r['server'] == '$DNS_SERVER'), None)\nprint(round(target['avg_response_time'], 1) if target else 'N/A')\n\" 2\u003e/dev/null || echo \"N/A\")\n    log \"Benchmark avg response time for $DNS_SERVER: ${AVG_MS}ms\"\nelse\n    log \"WARNING: benchmark failed\"\n    AVG_MS=\"N/A\"\nfi\n\n# ── DNS Compare (discrepancy detection) ─────────────────────────────────────\nCOMPARE_JSON=\"$REPORT_DIR/compare_${TIMESTAMP}.json\"\nnadzoring dns compare -t A -t MX \\\n    -s \"$DNS_SERVER\" -s 8.8.8.8 -s 1.1.1.1 \\\n    -o json --quiet --save \"$COMPARE_JSON\" \"$TARGET_DOMAIN\" || true\n\nDIFFS=$(python3 -c \"\nimport json\ndata = json.load(open('$COMPARE_JSON'))\ndiffs = data.get('differences', [])\nprint(len(diffs))\n\" 2\u003e/dev/null || echo 0)\n\nif [[ \"$DIFFS\" -gt 0 ]]; then\n    alert \"$DIFFS DNS discrepancies detected for $TARGET_DOMAIN — possible poisoning or misconfiguration\"\nfi\nlog \"DNS compare: $DIFFS discrepancies found\"\n\n# ── Reverse DNS Spot-check ───────────────────────────────────────────────────\nRESOLVED_IP=$(nadzoring network-base host-to-ip --quiet -o json \"$TARGET_DOMAIN\" 2\u003e/dev/null \\\n    | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d[0].get('ip','') if d else '')\" 2\u003e/dev/null || echo \"\")\n\nREVERSE_HOST=\"N/A\"\nif [[ -n \"$RESOLVED_IP\" ]]; then\n    REVERSE_JSON=\"$REPORT_DIR/reverse_${TIMESTAMP}.json\"\n    nadzoring dns reverse -n \"$DNS_SERVER\" -o json --quiet \\\n        --save \"$REVERSE_JSON\" \"$RESOLVED_IP\" || true\n    REVERSE_HOST=$(python3 -c \"\nimport json\ndata = json.load(open('$REVERSE_JSON'))\nprint(data[0].get('hostname','N/A') if data else 'N/A')\n\" 2\u003e/dev/null || echo \"N/A\")\n    log \"Reverse DNS for $RESOLVED_IP → $REVERSE_HOST\"\nfi\n\n# ── Append to JSONL summary for trend analysis ───────────────────────────────\npython3 - \u003c\u003cEOF \u003e\u003e \"$SUMMARY_FILE\"\nimport json, datetime\nprint(json.dumps({\n    \"timestamp\": \"$TIMESTAMP\",\n    \"domain\": \"$TARGET_DOMAIN\",\n    \"dns_server\": \"$DNS_SERVER\",\n    \"health_score\": $SCORE,\n    \"health_status\": \"$STATUS\",\n    \"avg_response_ms\": \"$AVG_MS\",\n    \"discrepancies\": $DIFFS,\n    \"resolved_ip\": \"$RESOLVED_IP\",\n    \"reverse_host\": \"$REVERSE_HOST\",\n}))\nEOF\n\nlog \"Run complete. Reports saved to $REPORT_DIR\"\n```\n\n#### Scheduling with cron (Linux/macOS)\n\n```bash\n# Edit crontab\ncrontab -e\n\n# Run every 5 minutes\n*/5 * * * * /path/to/dns_monitor.sh example.com 8.8.8.8\n\n# Run every hour with email alerts\n0 * * * * DNS_ALERT_EMAIL=ops@example.com /path/to/dns_monitor.sh example.com 8.8.8.8\n\n# Run every 15 minutes, logging cron output\n*/15 * * * * /path/to/dns_monitor.sh example.com 8.8.8.8 \u003e\u003e /var/log/nadzoring/cron.log 2\u003e\u00261\n```\n\n#### Scheduling with systemd timer (Linux, recommended)\n\nCreate `/etc/systemd/system/nadzoring-dns-monitor.service`:\n\n```ini\n[Unit]\nDescription=Nadzoring DNS health monitor\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nExecStart=/path/to/dns_monitor.sh example.com 8.8.8.8\nEnvironment=DNS_MONITOR_DIR=/var/log/nadzoring\nEnvironment=DNS_ALERT_EMAIL=ops@example.com\nStandardOutput=journal\nStandardError=journal\n```\n\nCreate `/etc/systemd/system/nadzoring-dns-monitor.timer`:\n\n```ini\n[Unit]\nDescription=Run Nadzoring DNS monitor every 5 minutes\n\n[Timer]\nOnBootSec=60\nOnUnitActiveSec=5min\nPersistent=true\n\n[Install]\nWantedBy=timers.target\n```\n\nEnable and start:\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now nadzoring-dns-monitor.timer\nsudo systemctl status nadzoring-dns-monitor.timer\njournalctl -u nadzoring-dns-monitor.service -f   # follow live logs\n```\n\n#### Python continuous monitoring loop (in-process)\n\nUse `DNSMonitor` directly for in-process monitoring with custom alerting:\n\n**Infinite loop (blocks until Ctrl-C or SIGTERM):**\n\n```python\nfrom nadzoring.dns_lookup.monitor import AlertEvent, DNSMonitor, MonitorConfig\n\n\ndef send_alert(alert: AlertEvent) -\u003e None:\n    print(f\"ALERT [{alert.alert_type}]: {alert.message}\")\n\n\nconfig = MonitorConfig(\n    domain=\"example.com\",\n    nameservers=[\"8.8.8.8\", \"1.1.1.1\"],\n    interval=60.0,\n    max_response_time_ms=500.0,\n    min_success_rate=0.95,\n    log_file=\"dns_monitor.jsonl\",\n    alert_callback=send_alert,\n)\n\nmonitor = DNSMonitor(config)\nmonitor.run()\nprint(monitor.report())\n```\n\n**Finite cycles (CI pipelines, cron scripts):**\n\n```python\nfrom nadzoring.dns_lookup.monitor import DNSMonitor, MonitorConfig\nfrom statistics import mean\n\nconfig = MonitorConfig(\n    domain=\"example.com\",\n    nameservers=[\"8.8.8.8\", \"1.1.1.1\"],\n    interval=10.0,\n    run_health_check=False,\n)\nmonitor = DNSMonitor(config)\nhistory = monitor.run_cycles(6)\n\nrts = [\n    s.avg_response_time_ms\n    for c in history\n    for s in c.samples\n    if s.avg_response_time_ms is not None\n]\nprint(f\"Mean RT: {mean(rts):.1f}ms\")\nprint(monitor.report())\n```\n\n**Analyse saved log:**\n\n```python\nfrom nadzoring.dns_lookup.monitor import load_log\nfrom statistics import mean\n\ncycles = load_log(\"dns_monitor.jsonl\")\nrts = [\n    s[\"avg_response_time_ms\"]\n    for c in cycles\n    for s in c[\"samples\"]\n    if s[\"avg_response_time_ms\"] is not None\n]\nalerts = [a for c in cycles for a in c.get(\"alerts\", [])]\nprint(f\"Cycles: {len(cycles)}  Mean RT: {mean(rts):.1f}ms  Alerts: {len(alerts)}\")\n```\n\n### Quick Website Block Check\n\n```bash\nnadzoring dns resolve -t ALL example.com\nnadzoring dns reverse 93.184.216.34\nnadzoring dns trace example.com\nnadzoring network-base ping example.com\nnadzoring dns compare example.com\nnadzoring dns poisoning example.com\nnadzoring network-base http-ping https://example.com\nnadzoring network-base traceroute example.com\nnadzoring security check-ssl example.com\nnadzoring security check-headers https://example.com\nnadzoring security check-email example.com\nnadzoring security subdomains example.com\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a pull request.\n\n**Workflow:**\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n**Areas we'd love help with:**\n\n- Additional DNS record type support\n- New health check validation rules\n- CDN network database expansion\n- Performance optimisations\n- Additional output formats\n- ARP detection heuristics\n- New network diagnostic commands\n- Extended security auditing (HSTS preload check, certificate transparency monitoring, CAA record validation)\n\n---\n\n## Documentation\n\n| Version | Link | Status |\n|---------|------|--------|\n| **main** | [Latest (development)](https://alexeev-prog.github.io/nadzoring/main) | 🟡 Development |\n| **v0.1.9** | [Release](https://alexeev-prog.github.io/nadzoring/v0.1.9) | 🟢 Stable |\n| v0.1.8 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.8) | ⚪ Legacy |\n| v0.1.7 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.7) | ⚪ Legacy |\n| v0.1.6 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.6) | ⚪ Legacy |\n| v0.1.5 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.5) | ⚪ Legacy |\n| v0.1.4 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.4) | ⚪ Legacy |\n| v0.1.3 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.3) | ⚪ Legacy |\n| v0.1.2 | [Legacy](https://alexeev-prog.github.io/nadzoring/v0.1.2) | ⚪ Legacy |\n| v0.1.1 | [First version](https://alexeev-prog.github.io/nadzoring/v0.1.1) | ⚪ Legacy |\n\nThe documentation site includes:\n- [Error Handling guide](https://alexeev-prog.github.io/nadzoring/main/error_handling.html) — complete reference of all error patterns and return values\n- [Architecture overview](https://alexeev-prog.github.io/nadzoring/main/architecture.html) — layer design, SRP/DRY/KISS principles applied\n- [DNS command reference](https://alexeev-prog.github.io/nadzoring/main/commands/dns.html) — full CLI + Python API per command\n- [Security command reference](https://alexeev-prog.github.io/nadzoring/main/commands/security.html) — SSL, headers, email, subdomains, monitoring\n- [DNS monitoring guide](https://alexeev-prog.github.io/nadzoring/main/monitoring_dns.html) — systemd, cron, trend analysis\n\n---\n\n## License \u0026 Support\n\nThis project is licensed under the **GNU GPL v3 License** — see [LICENSE](https://github.com/alexeev-prog/nadzoring/blob/main/LICENSE) for details.\n\nFor commercial support or enterprise features, contact [alexeev.dev@mail.ru](mailto:alexeev.dev@mail.ru).\n\n[📖 Explore Docs](https://alexeev-prog.github.io/nadzoring) · [🐛 Report Issue](https://github.com/alexeev-prog/nadzoring/issues)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n---\nCopyright © 2025 Alexeev Bronislav. Distributed under GNU GPL v3 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexeev-prog%2Fnadzoring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexeev-prog%2Fnadzoring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexeev-prog%2Fnadzoring/lists"}