pyresolvers


Namepyresolvers JSON
Version 2.4.2 PyPI version JSON
download
home_pagehttps://github.com/PigeonSec/pyresolvers
SummaryHigh-performance async DNS resolver validation and speed testing library
upload_time2025-11-11 14:19:15
maintainerNone
docs_urlNone
authorKarl
requires_python>=3.12
licenseGPL-3.0
keywords dns resolver validation speed-test async networking
VCS
bugtrack_url
requirements dnspython colorclass
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">

<img src="https://raw.githubusercontent.com/PigeonSec/pyresolvers/master/logo.png" alt="PyResolvers Logo" width="200" height="200">

# PyResolvers

**High-Performance Async DNS Resolver Validation & Speed Testing**

[![Tests](https://github.com/PigeonSec/pyresolvers/actions/workflows/test-and-publish.yml/badge.svg?branch=master)](https://github.com/PigeonSec/pyresolvers/actions/workflows/test-and-publish.yml)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/)
[![PyPI version](https://img.shields.io/pypi/v/pyresolvers.svg)](https://pypi.org/project/pyresolvers/)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

*Validate DNS resolvers, measure response times, identify the fastest servers*

</div>

---

## Overview

PyResolvers is a high-performance async Python library and CLI tool for validating DNS resolvers. It performs comprehensive validation (baseline comparison, poisoning detection, NXDOMAIN verification) and orders results by speed.

### Features

- ⚡ **High-Performance Async** - Up to 3x faster than thread-based validators
- 🚀 **Speed Testing** - Measures and orders resolvers by latency
- 🌐 **URL Support** - Download resolver lists from URLs (HTTP/HTTPS)
- 🔍 **Comprehensive Validation** - Baseline, poisoning, NXDOMAIN checks
- 🛡️ **Poisoning Detection** - 3-domain check (Amazon, PayPal, Netflix)
- 📊 **Multiple Formats** - JSON, plain text, text+speed
- 🎯 **Speed Filtering** - Filter by min/max latency thresholds
- 📝 **Smart Parsing** - Auto-extracts IPs from CSV, text, and mixed formats
- 🔊 **Verbose Mode** - See rejected/filtered servers with reasons
- 💨 **Streaming Results** - Real-time output as servers are validated

### Performance

**Benchmark (500 servers from public-dns.info):**

| Concurrency | Timeout | Time | Test Rate | Speedup |
|-------------|---------|------|-----------|---------|
| 50 (default) | 1.0s | 36.7s | 13.6/sec | baseline |
| 100 | 1.0s | 18.3s | 27.3/sec | **2.0x** ⚡ |
| 200 | 0.5s | 14.5s | 34.6/sec | **2.5x** 🚀 |

**Estimated time for 62,607 servers:**
- Default (50 threads): ~77 minutes
- Optimized (200 threads, 0.5s timeout): **~30 minutes**

---

## Installation

```bash
git clone https://github.com/PigeonSec/pyresolvers.git
cd pyresolvers
python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e .
```

**Or install from PyPI:**

```bash
pip install pyresolvers
```

**Requirements**: Python 3.12+, aiodns, pycares, colorclass

---

## Quick Start

### CLI Commands

**Basic validation:**
```bash
$ pyresolvers -t 1.1.1.1
=======================================================
pyresolvers v2.0.1 - DNS Resolver Validator
=======================================================
[10:25:04] [INFO] Testing 1 servers
[10:25:04] [INFO] Establishing baseline...
[10:25:04] [INFO] Validating with concurrency=50...
[10:25:04] [ACCEPTED] [1.1.1.1] 20.49ms
[10:25:04] [INFO] Found 1 valid servers
```

**Test multiple servers from file:**
```bash
$ pyresolvers -tL dns_servers.txt
[10:25:11] [INFO] Testing 3 servers
[10:25:11] [INFO] Establishing baseline...
[10:25:11] [INFO] Validating with concurrency=50...
[10:25:11] [ACCEPTED] [9.9.9.9] 9.00ms
[10:25:11] [ACCEPTED] [8.8.8.8] 15.79ms
[10:25:11] [ACCEPTED] [1.1.1.1] 19.69ms
[10:25:11] [INFO] Found 3 valid servers
```

**Silent mode (IPs only, perfect for piping):**
```bash
$ pyresolvers -tL dns_servers.txt --silent
9.9.9.9
8.8.8.8
1.1.1.1
```

**Verbose mode with speed filtering:**
```bash
$ pyresolvers -tL dns_servers.txt --max-speed 15 -v
[10:25:27] [INFO] Testing 3 servers
[10:25:27] [INFO] Max speed filter: 15.0ms
[10:25:28] [ACCEPTED] [9.9.9.9] 9.05ms
[10:25:28] [REJECTED] [1.1.1.1] Too slow: 20.30ms
[10:25:28] [REJECTED] [8.8.8.8] Too slow: 20.22ms
[10:25:28] [INFO] Found 1 valid servers
```

**JSON output format:**
```bash
$ pyresolvers -tL dns_servers.txt --format json
{
  "servers": [
    {"ip": "9.9.9.9", "latency_ms": 10.3},
    {"ip": "8.8.8.8", "latency_ms": 15.96},
    {"ip": "1.1.1.1", "latency_ms": 20.35}
  ],
  "count": 3,
  "filters": {"min_ms": null, "max_ms": null}
}
```

**More examples:**
```bash
# Test from URL
pyresolvers -tL https://public-dns.info/nameservers.txt

# Speed filtering and save to file
pyresolvers -tL resolvers.txt --max-speed 50 -o fast_dns.txt
pyresolvers -tL resolvers.txt --min-speed 10 --max-speed 100

# Text with speed output
pyresolvers -tL resolvers.txt --format text-with-speed -o dns_with_speed.txt

# Exclusions
pyresolvers -tL all_resolvers.txt -e 8.8.8.8
pyresolvers -tL resolvers.txt -eL blacklist.txt

# Performance tuning
pyresolvers -tL large_list.txt -threads 200 -timeout 0.5
pyresolvers -tL https://public-dns.info/nameservers.txt -threads 200 --max-speed 30 | head -10
```

### Library Usage

```python
from pyresolvers import Validator

# Basic usage - get valid servers ordered by speed
validator = Validator()
servers = ['1.1.1.1', '8.8.8.8', '9.9.9.9']
results = validator.validate_by_speed(servers)

for server, latency in results:
    print(f"{server}: {latency:.2f}ms")

# High concurrency with speed filtering
validator = Validator(concurrency=100)
fast = validator.validate_by_speed(servers, max_ms=50)

# Detailed results with error information
results = validator.validate(servers)
for r in results:
    if r.valid:
        print(f"✓ {r.server}: {r.latency_ms:.2f}ms")
    else:
        print(f"✗ {r.server}: {r.error}")

# JSON export
json_output = validator.to_json(servers, max_ms=100, pretty=True)
with open('valid_dns.json', 'w') as f:
    f.write(json_output)

# Async usage
import asyncio

async def main():
    validator = Validator(concurrency=200)
    results = await validator.validate_by_speed_async(servers)
    return results

results = asyncio.run(main())

# Streaming for huge lists (memory efficient)
async def process_huge_list():
    validator = Validator(concurrency=100)
    async for server, latency in validator.validate_streaming_async(servers):
        print(f"{server}: {latency:.2f}ms")

asyncio.run(process_huge_list())
```

### Cronjob Examples

**Daily DNS validation with API upload:**
```bash
#!/bin/bash
# /usr/local/bin/dns_monitor.sh

OUTPUT_DIR="/var/lib/dns-monitor"
mkdir -p "$OUTPUT_DIR"

# Validate and save to JSON
pyresolvers -tL https://public-dns.info/nameservers.txt \
    --max-speed 100 \
    --format json \
    -o "$OUTPUT_DIR/resolvers.json"

# Upload to API
curl -X POST "https://api.example.com/dns/update" \
    -H "Content-Type: application/json" \
    -d @"$OUTPUT_DIR/resolvers.json"
```

**Fast resolver discovery and update:**
```bash
#!/bin/bash
# /usr/local/bin/update_fast_dns.sh

# Get fastest resolvers (< 30ms) and update system config
pyresolvers -tL https://public-dns.info/nameservers.txt \
    --max-speed 30 \
    --silent \
    -threads 200 \
    -timeout 0.5 \
    -o /tmp/fast_dns.txt

# Use top 3 fastest
head -3 /tmp/fast_dns.txt > /etc/my_app/dns_servers.conf
```

**Crontab entries:**
```cron
# Daily API sync at 2 AM
0 2 * * * /usr/local/bin/dns_monitor.sh >> /var/log/dns-monitor.log 2>&1

# Update fast DNS every 6 hours
0 */6 * * * /usr/local/bin/update_fast_dns.sh >> /var/log/dns-update.log 2>&1
```

---

## Input Formats

PyResolvers supports multiple input methods for maximum flexibility.

### URL Input

Download resolver lists directly from URLs:

```bash
# Public DNS list (62,000+ resolvers)
pyresolvers -tL https://public-dns.info/nameservers.txt --max-speed 50

# Your own hosted list
pyresolvers -tL https://example.com/dns-servers.txt

# GitHub raw files
pyresolvers -tL https://raw.githubusercontent.com/user/repo/main/resolvers.txt
```

### File Input

Load from local files:

```bash
# Plain text file (one IP per line)
pyresolvers -tL resolvers.txt

# CSV format (automatically extracts IPs)
pyresolvers -tL servers.csv

# Mixed format with comments
pyresolvers -tL list.txt
```

### Supported File Formats

PyResolvers automatically extracts valid IPv4 addresses from:

**Plain Text:**
```
8.8.8.8
1.1.1.1
208.67.222.222
```

**CSV/TSV:**
```
8.8.8.8,Google,US,Fast
1.1.1.1,Cloudflare,US,Fast
208.67.222.222,OpenDNS,US,Moderate
```

**With Comments:**
```
# Google Public DNS
8.8.8.8
# Cloudflare
1.1.1.1
# OpenDNS
208.67.222.222
```

**Mixed Format:**
```
Server: 8.8.8.8 (Google)
dns1=1.1.1.1
208.67.222.222 # OpenDNS Primary
```

### Validation

All input is validated automatically:
- ✅ Extracts IPv4 addresses from any position in a line
- ✅ Validates IP format (0-255 per octet)
- ✅ Skips empty lines and comments (#)
- ✅ Handles CSV, TSV, and space-separated formats
- ✅ Removes duplicates automatically

### Exclusions

Exclude servers using the same formats:

```bash
# Exclude from URL
pyresolvers -tL all.txt -eL https://example.com/blacklist.txt

# Exclude from file
pyresolvers -tL https://public-dns.info/nameservers.txt -eL blocked.txt

# Exclude single IP
pyresolvers -tL resolvers.txt -e 8.8.8.8
```

---

## API Reference

### Validator

High-performance async DNS validator.

```python
Validator(
    trusted_resolvers: Optional[List[str]] = None,  # ["1.1.1.1", "8.8.8.8"]
    test_domains: Optional[List[str]] = None,       # ["bet365.com", "telegram.com"]
    poison_check_domains: Optional[List[str]] = None,
    baseline_domain: str = "bet365.com",
    query_prefix: str = "dnsvalidator",
    concurrency: int = 50,                          # Async concurrency
    timeout: int = 5,                               # DNS timeout (seconds)
    use_fast_timeout: bool = False,                 # Fast dead server detection (optional speedup)
    batch_size: int = 100,                          # Memory management
    verbose: bool = False
)
```

**Methods:**

- `validate(servers)` → `List[ValidationResult]` - Validate servers
- `validate_by_speed(servers, min_ms, max_ms)` → `List[Tuple[str, float]]` - Get valid servers ordered by speed
- `to_json(servers, min_ms, max_ms)` → `str` - Export as JSON
- `to_text(servers, min_ms, max_ms, show_speed)` → `str` - Export as text

**Async Methods:**

- `await validate_async(servers)` - Async validation
- `await validate_by_speed_async(servers, min_ms, max_ms)` - Async speed validation
- `async for server, latency in validate_streaming_async(servers)` - Async streaming

### ValidationResult

```python
@dataclass
class ValidationResult:
    server: str
    valid: bool
    latency_ms: float
    error: Optional[str] = None
```

---

## CLI Options

| Option | Description |
|--------|-------------|
| `-t SERVER` | Test single server |
| `-tL FILE/URL` | Test from file or URL |
| `-e SERVER` | Exclude server |
| `-eL FILE/URL` | Exclude from file/URL |
| `-r DOMAIN` | Baseline domain (default: bet365.com) |
| `-threads N` | Concurrency (default: 50) |
| `-timeout N` | Timeout seconds (default: 1) |
| `-o FILE` | Output file |
| `--format FORMAT` | text, json, text-with-speed |
| `--max-speed MS` | Max latency filter (ms) |
| `--min-speed MS` | Min latency filter (ms) |
| `--silent` | Only output IPs |
| `-v, --verbose` | Verbose output |
| `--no-color` | Disable colors |

---

## Performance Tips

### Recommended Settings

**For 60K+ servers (fastest):**
```bash
pyresolvers -tL https://public-dns.info/nameservers.txt -threads 200 -timeout 0.5 --max-speed 200 -o results.txt
```

**For balanced speed/accuracy:**
```bash
pyresolvers -tL large_list.txt -threads 100 -timeout 1 --max-speed 100
```

**For verbose debugging:**
```bash
pyresolvers -tL resolvers.txt -threads 50 -v
```

### Configuration Guide

- **Concurrency**:
  - 50-100 for stable performance
  - 200-300 for maximum speed (requires good network)
  - Higher may trigger rate limits

- **Timeout**:
  - 0.5s for fast dead server detection
  - 1s for balanced performance (default)
  - 2s+ for slow/distant servers

- **Verbose Mode**: Use `-v` to see rejected servers with reasons:
  - "Too slow: XXms" - Exceeded max-speed filter
  - "Timeout" - Server didn't respond
  - "Invalid" - Failed validation checks
  - "DNS poisoning" - Detected hijacking

### Optimization Features

1. **Async I/O** - Non-blocking DNS queries with aiodns
2. **Parallel Validation** - All checks run simultaneously
3. **Streaming Output** - Results appear in real-time
4. **Smart Poisoning** - 3 diverse domains (Amazon, PayPal, Netflix)
5. **Optimized Defaults** - 50 threads, 1s timeout, fast mode enabled
6. **Progress Indicators** - Shows validation progress every 100 servers

---

## How It Works

1. **Baseline Setup** - Query trusted resolvers (1.1.1.1, 8.8.8.8) for ground truth
2. **Parallel Validation** - For each server, run simultaneously:
   - **Poisoning Check** - Test 3 random subdomains (amazon.com, paypal.com, netflix.com)
   - **NXDOMAIN Check** - Verify correct NXDOMAIN behavior
   - **Baseline Compare** - Ensure responses match trusted resolvers
3. **Latency Measurement** - Measure DNS query speed for valid servers
4. **Real-time Output** - Stream results as validation completes
5. **Speed Filtering** - Apply min/max latency filters and output sorted results

---

## Important Notes

### Thread Count

Keep concurrency reasonable (50-100) to avoid triggering rate limits. Very high concurrency may be blocked by ISPs or DNS providers.

### Domain Selection

Use **non-geolocated** domains for baseline (bet365.com works well). Avoid google.com, facebook.com as they return different IPs by location.

---

## License

GNU General Public License v3.0 - see [LICENSE](LICENSE)

---

## Acknowledgments

Based on [dnsvalidator](https://github.com/vortexau/dnsvalidator) by:
- **James McLean** ([@vortexau](https://twitter.com/vortexau))
- **Michael Skelton** ([@codingo_](https://twitter.com/codingo_))

Enhanced with async architecture, speed testing, and performance optimizations by Karl.

---

<div align="center">

**[⬆ back to top](#pyresolvers)**

Made with ❤️ by Karl | Based on dnsvalidator by @vortexau & @codingo_

</div>

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/PigeonSec/pyresolvers",
    "name": "pyresolvers",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "dns, resolver, validation, speed-test, async, networking",
    "author": "Karl",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/18/f3/b88e57a9d633a5ea94ae9e72329201c4ed489d3ea5e1d896961a12cfb980/pyresolvers-2.4.2.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/PigeonSec/pyresolvers/master/logo.png\" alt=\"PyResolvers Logo\" width=\"200\" height=\"200\">\n\n# PyResolvers\n\n**High-Performance Async DNS Resolver Validation & Speed Testing**\n\n[![Tests](https://github.com/PigeonSec/pyresolvers/actions/workflows/test-and-publish.yml/badge.svg?branch=master)](https://github.com/PigeonSec/pyresolvers/actions/workflows/test-and-publish.yml)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/)\n[![PyPI version](https://img.shields.io/pypi/v/pyresolvers.svg)](https://pypi.org/project/pyresolvers/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\n*Validate DNS resolvers, measure response times, identify the fastest servers*\n\n</div>\n\n---\n\n## Overview\n\nPyResolvers is a high-performance async Python library and CLI tool for validating DNS resolvers. It performs comprehensive validation (baseline comparison, poisoning detection, NXDOMAIN verification) and orders results by speed.\n\n### Features\n\n- \u26a1 **High-Performance Async** - Up to 3x faster than thread-based validators\n- \ud83d\ude80 **Speed Testing** - Measures and orders resolvers by latency\n- \ud83c\udf10 **URL Support** - Download resolver lists from URLs (HTTP/HTTPS)\n- \ud83d\udd0d **Comprehensive Validation** - Baseline, poisoning, NXDOMAIN checks\n- \ud83d\udee1\ufe0f **Poisoning Detection** - 3-domain check (Amazon, PayPal, Netflix)\n- \ud83d\udcca **Multiple Formats** - JSON, plain text, text+speed\n- \ud83c\udfaf **Speed Filtering** - Filter by min/max latency thresholds\n- \ud83d\udcdd **Smart Parsing** - Auto-extracts IPs from CSV, text, and mixed formats\n- \ud83d\udd0a **Verbose Mode** - See rejected/filtered servers with reasons\n- \ud83d\udca8 **Streaming Results** - Real-time output as servers are validated\n\n### Performance\n\n**Benchmark (500 servers from public-dns.info):**\n\n| Concurrency | Timeout | Time | Test Rate | Speedup |\n|-------------|---------|------|-----------|---------|\n| 50 (default) | 1.0s | 36.7s | 13.6/sec | baseline |\n| 100 | 1.0s | 18.3s | 27.3/sec | **2.0x** \u26a1 |\n| 200 | 0.5s | 14.5s | 34.6/sec | **2.5x** \ud83d\ude80 |\n\n**Estimated time for 62,607 servers:**\n- Default (50 threads): ~77 minutes\n- Optimized (200 threads, 0.5s timeout): **~30 minutes**\n\n---\n\n## Installation\n\n```bash\ngit clone https://github.com/PigeonSec/pyresolvers.git\ncd pyresolvers\npython3 -m venv venv\nsource venv/bin/activate  # Windows: venv\\Scripts\\activate\npip install -e .\n```\n\n**Or install from PyPI:**\n\n```bash\npip install pyresolvers\n```\n\n**Requirements**: Python 3.12+, aiodns, pycares, colorclass\n\n---\n\n## Quick Start\n\n### CLI Commands\n\n**Basic validation:**\n```bash\n$ pyresolvers -t 1.1.1.1\n=======================================================\npyresolvers v2.0.1 - DNS Resolver Validator\n=======================================================\n[10:25:04] [INFO] Testing 1 servers\n[10:25:04] [INFO] Establishing baseline...\n[10:25:04] [INFO] Validating with concurrency=50...\n[10:25:04] [ACCEPTED] [1.1.1.1] 20.49ms\n[10:25:04] [INFO] Found 1 valid servers\n```\n\n**Test multiple servers from file:**\n```bash\n$ pyresolvers -tL dns_servers.txt\n[10:25:11] [INFO] Testing 3 servers\n[10:25:11] [INFO] Establishing baseline...\n[10:25:11] [INFO] Validating with concurrency=50...\n[10:25:11] [ACCEPTED] [9.9.9.9] 9.00ms\n[10:25:11] [ACCEPTED] [8.8.8.8] 15.79ms\n[10:25:11] [ACCEPTED] [1.1.1.1] 19.69ms\n[10:25:11] [INFO] Found 3 valid servers\n```\n\n**Silent mode (IPs only, perfect for piping):**\n```bash\n$ pyresolvers -tL dns_servers.txt --silent\n9.9.9.9\n8.8.8.8\n1.1.1.1\n```\n\n**Verbose mode with speed filtering:**\n```bash\n$ pyresolvers -tL dns_servers.txt --max-speed 15 -v\n[10:25:27] [INFO] Testing 3 servers\n[10:25:27] [INFO] Max speed filter: 15.0ms\n[10:25:28] [ACCEPTED] [9.9.9.9] 9.05ms\n[10:25:28] [REJECTED] [1.1.1.1] Too slow: 20.30ms\n[10:25:28] [REJECTED] [8.8.8.8] Too slow: 20.22ms\n[10:25:28] [INFO] Found 1 valid servers\n```\n\n**JSON output format:**\n```bash\n$ pyresolvers -tL dns_servers.txt --format json\n{\n  \"servers\": [\n    {\"ip\": \"9.9.9.9\", \"latency_ms\": 10.3},\n    {\"ip\": \"8.8.8.8\", \"latency_ms\": 15.96},\n    {\"ip\": \"1.1.1.1\", \"latency_ms\": 20.35}\n  ],\n  \"count\": 3,\n  \"filters\": {\"min_ms\": null, \"max_ms\": null}\n}\n```\n\n**More examples:**\n```bash\n# Test from URL\npyresolvers -tL https://public-dns.info/nameservers.txt\n\n# Speed filtering and save to file\npyresolvers -tL resolvers.txt --max-speed 50 -o fast_dns.txt\npyresolvers -tL resolvers.txt --min-speed 10 --max-speed 100\n\n# Text with speed output\npyresolvers -tL resolvers.txt --format text-with-speed -o dns_with_speed.txt\n\n# Exclusions\npyresolvers -tL all_resolvers.txt -e 8.8.8.8\npyresolvers -tL resolvers.txt -eL blacklist.txt\n\n# Performance tuning\npyresolvers -tL large_list.txt -threads 200 -timeout 0.5\npyresolvers -tL https://public-dns.info/nameservers.txt -threads 200 --max-speed 30 | head -10\n```\n\n### Library Usage\n\n```python\nfrom pyresolvers import Validator\n\n# Basic usage - get valid servers ordered by speed\nvalidator = Validator()\nservers = ['1.1.1.1', '8.8.8.8', '9.9.9.9']\nresults = validator.validate_by_speed(servers)\n\nfor server, latency in results:\n    print(f\"{server}: {latency:.2f}ms\")\n\n# High concurrency with speed filtering\nvalidator = Validator(concurrency=100)\nfast = validator.validate_by_speed(servers, max_ms=50)\n\n# Detailed results with error information\nresults = validator.validate(servers)\nfor r in results:\n    if r.valid:\n        print(f\"\u2713 {r.server}: {r.latency_ms:.2f}ms\")\n    else:\n        print(f\"\u2717 {r.server}: {r.error}\")\n\n# JSON export\njson_output = validator.to_json(servers, max_ms=100, pretty=True)\nwith open('valid_dns.json', 'w') as f:\n    f.write(json_output)\n\n# Async usage\nimport asyncio\n\nasync def main():\n    validator = Validator(concurrency=200)\n    results = await validator.validate_by_speed_async(servers)\n    return results\n\nresults = asyncio.run(main())\n\n# Streaming for huge lists (memory efficient)\nasync def process_huge_list():\n    validator = Validator(concurrency=100)\n    async for server, latency in validator.validate_streaming_async(servers):\n        print(f\"{server}: {latency:.2f}ms\")\n\nasyncio.run(process_huge_list())\n```\n\n### Cronjob Examples\n\n**Daily DNS validation with API upload:**\n```bash\n#!/bin/bash\n# /usr/local/bin/dns_monitor.sh\n\nOUTPUT_DIR=\"/var/lib/dns-monitor\"\nmkdir -p \"$OUTPUT_DIR\"\n\n# Validate and save to JSON\npyresolvers -tL https://public-dns.info/nameservers.txt \\\n    --max-speed 100 \\\n    --format json \\\n    -o \"$OUTPUT_DIR/resolvers.json\"\n\n# Upload to API\ncurl -X POST \"https://api.example.com/dns/update\" \\\n    -H \"Content-Type: application/json\" \\\n    -d @\"$OUTPUT_DIR/resolvers.json\"\n```\n\n**Fast resolver discovery and update:**\n```bash\n#!/bin/bash\n# /usr/local/bin/update_fast_dns.sh\n\n# Get fastest resolvers (< 30ms) and update system config\npyresolvers -tL https://public-dns.info/nameservers.txt \\\n    --max-speed 30 \\\n    --silent \\\n    -threads 200 \\\n    -timeout 0.5 \\\n    -o /tmp/fast_dns.txt\n\n# Use top 3 fastest\nhead -3 /tmp/fast_dns.txt > /etc/my_app/dns_servers.conf\n```\n\n**Crontab entries:**\n```cron\n# Daily API sync at 2 AM\n0 2 * * * /usr/local/bin/dns_monitor.sh >> /var/log/dns-monitor.log 2>&1\n\n# Update fast DNS every 6 hours\n0 */6 * * * /usr/local/bin/update_fast_dns.sh >> /var/log/dns-update.log 2>&1\n```\n\n---\n\n## Input Formats\n\nPyResolvers supports multiple input methods for maximum flexibility.\n\n### URL Input\n\nDownload resolver lists directly from URLs:\n\n```bash\n# Public DNS list (62,000+ resolvers)\npyresolvers -tL https://public-dns.info/nameservers.txt --max-speed 50\n\n# Your own hosted list\npyresolvers -tL https://example.com/dns-servers.txt\n\n# GitHub raw files\npyresolvers -tL https://raw.githubusercontent.com/user/repo/main/resolvers.txt\n```\n\n### File Input\n\nLoad from local files:\n\n```bash\n# Plain text file (one IP per line)\npyresolvers -tL resolvers.txt\n\n# CSV format (automatically extracts IPs)\npyresolvers -tL servers.csv\n\n# Mixed format with comments\npyresolvers -tL list.txt\n```\n\n### Supported File Formats\n\nPyResolvers automatically extracts valid IPv4 addresses from:\n\n**Plain Text:**\n```\n8.8.8.8\n1.1.1.1\n208.67.222.222\n```\n\n**CSV/TSV:**\n```\n8.8.8.8,Google,US,Fast\n1.1.1.1,Cloudflare,US,Fast\n208.67.222.222,OpenDNS,US,Moderate\n```\n\n**With Comments:**\n```\n# Google Public DNS\n8.8.8.8\n# Cloudflare\n1.1.1.1\n# OpenDNS\n208.67.222.222\n```\n\n**Mixed Format:**\n```\nServer: 8.8.8.8 (Google)\ndns1=1.1.1.1\n208.67.222.222 # OpenDNS Primary\n```\n\n### Validation\n\nAll input is validated automatically:\n- \u2705 Extracts IPv4 addresses from any position in a line\n- \u2705 Validates IP format (0-255 per octet)\n- \u2705 Skips empty lines and comments (#)\n- \u2705 Handles CSV, TSV, and space-separated formats\n- \u2705 Removes duplicates automatically\n\n### Exclusions\n\nExclude servers using the same formats:\n\n```bash\n# Exclude from URL\npyresolvers -tL all.txt -eL https://example.com/blacklist.txt\n\n# Exclude from file\npyresolvers -tL https://public-dns.info/nameservers.txt -eL blocked.txt\n\n# Exclude single IP\npyresolvers -tL resolvers.txt -e 8.8.8.8\n```\n\n---\n\n## API Reference\n\n### Validator\n\nHigh-performance async DNS validator.\n\n```python\nValidator(\n    trusted_resolvers: Optional[List[str]] = None,  # [\"1.1.1.1\", \"8.8.8.8\"]\n    test_domains: Optional[List[str]] = None,       # [\"bet365.com\", \"telegram.com\"]\n    poison_check_domains: Optional[List[str]] = None,\n    baseline_domain: str = \"bet365.com\",\n    query_prefix: str = \"dnsvalidator\",\n    concurrency: int = 50,                          # Async concurrency\n    timeout: int = 5,                               # DNS timeout (seconds)\n    use_fast_timeout: bool = False,                 # Fast dead server detection (optional speedup)\n    batch_size: int = 100,                          # Memory management\n    verbose: bool = False\n)\n```\n\n**Methods:**\n\n- `validate(servers)` \u2192 `List[ValidationResult]` - Validate servers\n- `validate_by_speed(servers, min_ms, max_ms)` \u2192 `List[Tuple[str, float]]` - Get valid servers ordered by speed\n- `to_json(servers, min_ms, max_ms)` \u2192 `str` - Export as JSON\n- `to_text(servers, min_ms, max_ms, show_speed)` \u2192 `str` - Export as text\n\n**Async Methods:**\n\n- `await validate_async(servers)` - Async validation\n- `await validate_by_speed_async(servers, min_ms, max_ms)` - Async speed validation\n- `async for server, latency in validate_streaming_async(servers)` - Async streaming\n\n### ValidationResult\n\n```python\n@dataclass\nclass ValidationResult:\n    server: str\n    valid: bool\n    latency_ms: float\n    error: Optional[str] = None\n```\n\n---\n\n## CLI Options\n\n| Option | Description |\n|--------|-------------|\n| `-t SERVER` | Test single server |\n| `-tL FILE/URL` | Test from file or URL |\n| `-e SERVER` | Exclude server |\n| `-eL FILE/URL` | Exclude from file/URL |\n| `-r DOMAIN` | Baseline domain (default: bet365.com) |\n| `-threads N` | Concurrency (default: 50) |\n| `-timeout N` | Timeout seconds (default: 1) |\n| `-o FILE` | Output file |\n| `--format FORMAT` | text, json, text-with-speed |\n| `--max-speed MS` | Max latency filter (ms) |\n| `--min-speed MS` | Min latency filter (ms) |\n| `--silent` | Only output IPs |\n| `-v, --verbose` | Verbose output |\n| `--no-color` | Disable colors |\n\n---\n\n## Performance Tips\n\n### Recommended Settings\n\n**For 60K+ servers (fastest):**\n```bash\npyresolvers -tL https://public-dns.info/nameservers.txt -threads 200 -timeout 0.5 --max-speed 200 -o results.txt\n```\n\n**For balanced speed/accuracy:**\n```bash\npyresolvers -tL large_list.txt -threads 100 -timeout 1 --max-speed 100\n```\n\n**For verbose debugging:**\n```bash\npyresolvers -tL resolvers.txt -threads 50 -v\n```\n\n### Configuration Guide\n\n- **Concurrency**:\n  - 50-100 for stable performance\n  - 200-300 for maximum speed (requires good network)\n  - Higher may trigger rate limits\n\n- **Timeout**:\n  - 0.5s for fast dead server detection\n  - 1s for balanced performance (default)\n  - 2s+ for slow/distant servers\n\n- **Verbose Mode**: Use `-v` to see rejected servers with reasons:\n  - \"Too slow: XXms\" - Exceeded max-speed filter\n  - \"Timeout\" - Server didn't respond\n  - \"Invalid\" - Failed validation checks\n  - \"DNS poisoning\" - Detected hijacking\n\n### Optimization Features\n\n1. **Async I/O** - Non-blocking DNS queries with aiodns\n2. **Parallel Validation** - All checks run simultaneously\n3. **Streaming Output** - Results appear in real-time\n4. **Smart Poisoning** - 3 diverse domains (Amazon, PayPal, Netflix)\n5. **Optimized Defaults** - 50 threads, 1s timeout, fast mode enabled\n6. **Progress Indicators** - Shows validation progress every 100 servers\n\n---\n\n## How It Works\n\n1. **Baseline Setup** - Query trusted resolvers (1.1.1.1, 8.8.8.8) for ground truth\n2. **Parallel Validation** - For each server, run simultaneously:\n   - **Poisoning Check** - Test 3 random subdomains (amazon.com, paypal.com, netflix.com)\n   - **NXDOMAIN Check** - Verify correct NXDOMAIN behavior\n   - **Baseline Compare** - Ensure responses match trusted resolvers\n3. **Latency Measurement** - Measure DNS query speed for valid servers\n4. **Real-time Output** - Stream results as validation completes\n5. **Speed Filtering** - Apply min/max latency filters and output sorted results\n\n---\n\n## Important Notes\n\n### Thread Count\n\nKeep concurrency reasonable (50-100) to avoid triggering rate limits. Very high concurrency may be blocked by ISPs or DNS providers.\n\n### Domain Selection\n\nUse **non-geolocated** domains for baseline (bet365.com works well). Avoid google.com, facebook.com as they return different IPs by location.\n\n---\n\n## License\n\nGNU General Public License v3.0 - see [LICENSE](LICENSE)\n\n---\n\n## Acknowledgments\n\nBased on [dnsvalidator](https://github.com/vortexau/dnsvalidator) by:\n- **James McLean** ([@vortexau](https://twitter.com/vortexau))\n- **Michael Skelton** ([@codingo_](https://twitter.com/codingo_))\n\nEnhanced with async architecture, speed testing, and performance optimizations by Karl.\n\n---\n\n<div align=\"center\">\n\n**[\u2b06 back to top](#pyresolvers)**\n\nMade with \u2764\ufe0f by Karl | Based on dnsvalidator by @vortexau & @codingo_\n\n</div>\n",
    "bugtrack_url": null,
    "license": "GPL-3.0",
    "summary": "High-performance async DNS resolver validation and speed testing library",
    "version": "2.4.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/PigeonSec/pyresolvers/issues",
        "Documentation": "https://github.com/PigeonSec/pyresolvers#readme",
        "Homepage": "https://github.com/PigeonSec/pyresolvers",
        "Repository": "https://github.com/PigeonSec/pyresolvers"
    },
    "split_keywords": [
        "dns",
        " resolver",
        " validation",
        " speed-test",
        " async",
        " networking"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d6be29e008e4ae67a4a17d8a408fe1b95fc25906a2660af38b5e900d2da78804",
                "md5": "715f67a890ca30ed7774a15cd3d86de3",
                "sha256": "6dd5e22c50799d8f69b392e263905313785267e43c39a737f2a60aae4182d207"
            },
            "downloads": -1,
            "filename": "pyresolvers-2.4.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "715f67a890ca30ed7774a15cd3d86de3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 17975,
            "upload_time": "2025-11-11T14:19:13",
            "upload_time_iso_8601": "2025-11-11T14:19:13.946835Z",
            "url": "https://files.pythonhosted.org/packages/d6/be/29e008e4ae67a4a17d8a408fe1b95fc25906a2660af38b5e900d2da78804/pyresolvers-2.4.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "18f3b88e57a9d633a5ea94ae9e72329201c4ed489d3ea5e1d896961a12cfb980",
                "md5": "c0c19392d4c8b450bd03a79174284e38",
                "sha256": "ef8bed52d0d084886cc0b2724e573c1d699b8da3a8432467791d36fbf0ba8af5"
            },
            "downloads": -1,
            "filename": "pyresolvers-2.4.2.tar.gz",
            "has_sig": false,
            "md5_digest": "c0c19392d4c8b450bd03a79174284e38",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 443459,
            "upload_time": "2025-11-11T14:19:15",
            "upload_time_iso_8601": "2025-11-11T14:19:15.378408Z",
            "url": "https://files.pythonhosted.org/packages/18/f3/b88e57a9d633a5ea94ae9e72329201c4ed489d3ea5e1d896961a12cfb980/pyresolvers-2.4.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-11 14:19:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "PigeonSec",
    "github_project": "pyresolvers",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "dnspython",
            "specs": [
                [
                    ">=",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "colorclass",
            "specs": [
                [
                    ">=",
                    "2.2.2"
                ]
            ]
        }
    ],
    "lcname": "pyresolvers"
}
        
Elapsed time: 2.02576s