zero trust architecture

Implementing Zero Trust DNS with NextDNS

Implement NextDNS as a zero trust DNS filtering layer with encrypted resolution, threat intelligence blocking, privacy protection, and organizational policy enforcement across all endpoints.

dnsdns-filteringdns-over-httpsdns-over-tlsencrypted-dnsnextdnsprivacythreat-blocking
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

NextDNS is a cloud-based DNS resolver that provides encrypted DNS resolution (DNS-over-HTTPS and DNS-over-TLS), real-time threat intelligence blocking, ad and tracker filtering, and granular DNS policy enforcement. In a zero trust architecture, DNS is a critical control point -- every network connection begins with a DNS query, making DNS filtering an effective layer for blocking malicious domains, preventing data exfiltration via DNS tunneling, enforcing acceptable use policies, and gaining visibility into all network communications. NextDNS processes queries using threat intelligence feeds containing millions of malicious domains updated in real-time, blocks cryptojacking and phishing domains, detects DNS rebinding attacks, and supports CNAME cloaking protection. For enterprise environments, Microsoft's Zero Trust DNS (ZTDNS) feature on Windows 11 extends this concept by enforcing that endpoints can only resolve domains through approved protected DNS servers.

When to Use

  • When deploying or configuring implementing zero trust dns with nextdns capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • NextDNS account (free tier: 300,000 queries/month; Pro: unlimited)
  • Network devices supporting DoH or DoT configuration
  • Administrative access to endpoint DNS settings
  • Understanding of DNS protocol and resolution chain
  • Familiarity with organizational acceptable use policies

Architecture

    Endpoint Device
         |
    DNS Query (Encrypted)
         |
    +----+----+
    |  DoH/DoT |  (DNS-over-HTTPS or DNS-over-TLS)
    |  Tunnel  |
    +----+----+
         |
    +----+----+
    | NextDNS  |
    | Resolver |
    +----+----+
         |
    +----+----+------+--------+
    |         |       |        |
  Threat   Ad/Tracker Privacy  Parental
  Intel    Blocklists Controls Controls
  Check    Check      Check    Check
    |         |       |        |
    +----+----+------+--------+
         |
    ALLOW or BLOCK
         |
    Response to Endpoint

Configuration Setup

NextDNS Profile Configuration

Dashboard: https://my.nextdns.io
 
Configuration ID: abc123 (unique per profile)
 
Endpoints:
  DNS-over-HTTPS: https://dns.nextdns.io/abc123
  DNS-over-TLS:   abc123.dns.nextdns.io
  DNS-over-QUIC:  quic://abc123.dns.nextdns.io
  IPv4:           45.90.28.x, 45.90.30.x (linked to config)
  IPv6:           2a07:a8c0::xx, 2a07:a8c1::xx

Security Settings

Security Tab Configuration:
  [x] Threat Intelligence Feeds - Block domains from curated threat feeds
  [x] AI-Driven Threat Detection - Machine learning-based detection
  [x] Google Safe Browsing - Cross-reference with Google's threat database
  [x] Cryptojacking Protection - Block crypto mining domains
  [x] DNS Rebinding Protection - Prevent DNS rebinding attacks
  [x] IDN Homograph Attacks - Block internationalized domain name attacks
  [x] Typosquatting Protection - Block common typosquatting domains
  [x] DGA Protection - Block domain generation algorithm domains
  [x] NRD (Newly Registered Domains) - Block domains < 30 days old
  [x] DDNS (Dynamic DNS) - Block dynamic DNS services
  [x] Parked Domains - Block parked/unused domains
  [x] CSAM - Block child sexual abuse material domains

Privacy Settings

Privacy Tab Configuration:
  Blocklists:
    [x] NextDNS Ads & Trackers Blocklist
    [x] OISD (Full)
    [x] EasyPrivacy
    [x] AdGuard DNS Filter
 
  Native Tracking Protection:
    [x] Block Windows telemetry
    [x] Block Apple telemetry
    [x] Block Samsung telemetry
    [x] Block Xiaomi telemetry
    [x] Block Huawei telemetry
    [x] Block Roku telemetry
    [x] Block Sonos telemetry
 
  [x] Block Disguised Third-Party Trackers (CNAME cloaking)
  [x] Allow Affiliate & Tracking Links (optional, for business)

Allowlist and Denylist

Allowlist (domains that bypass all blocking):
  - login.microsoftonline.com
  - graph.microsoft.com
  - *.company.com
 
Denylist (always blocked regardless of other settings):
  - known-malicious-domain.com
  - unauthorized-cloud-storage.com
  - personal-email-provider.com  (if policy requires)

Endpoint Deployment

Linux (systemd-resolved)

# Configure DNS-over-TLS with systemd-resolved
sudo tee /etc/systemd/resolved.conf << 'EOF'
[Resolve]
DNS=45.90.28.x#abc123.dns.nextdns.io
DNS=45.90.30.x#abc123.dns.nextdns.io
DNS=2a07:a8c0::xx#abc123.dns.nextdns.io
DNS=2a07:a8c1::xx#abc123.dns.nextdns.io
DNSOverTLS=yes
Domains=~.
EOF
 
sudo systemctl restart systemd-resolved
 
# Verify
resolvectl status
resolvectl query example.com

Linux (NextDNS CLI)

# Install NextDNS CLI
sh -c 'sh -e $(curl -sL https://nextdns.io/install)'
 
# Configure with your profile
sudo nextdns install \
  -config abc123 \
  -report-client-info \
  -auto-activate
 
# Verify
nextdns status
nextdns log

macOS

# Install via Homebrew
brew install nextdns/tap/nextdns
 
# Configure
sudo nextdns install \
  -config abc123 \
  -report-client-info
 
# Or configure via System Settings > Network > DNS
# Add DNS-over-HTTPS: https://dns.nextdns.io/abc123

Windows

# Install NextDNS CLI for Windows
# Download from: https://nextdns.io/download/windows
 
# Or configure DoH natively (Windows 11)
# Settings > Network & Internet > Ethernet/Wi-Fi > DNS
# Preferred DNS: 45.90.28.x
# DNS over HTTPS: On (Manual template)
# DoH Template: https://dns.nextdns.io/abc123
 
# PowerShell: Configure DoH
Set-DnsClientDohServerAddress -ServerAddress "45.90.28.x" `
  -DohTemplate "https://dns.nextdns.io/abc123" `
  -AllowFallbackToUdp $false `
  -AutoUpgrade $true

Router-Level Configuration

# Most routers support custom DNS servers
# For DoH/DoT-capable routers (pfSense, OPNsense, OpenWrt):
 
# pfSense DNS Resolver (Unbound):
# Services > DNS Resolver > Custom Options:
server:
  forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 45.90.28.x@853#abc123.dns.nextdns.io
    forward-addr: 45.90.30.x@853#abc123.dns.nextdns.io
 
# OpenWrt (using https-dns-proxy):
opkg update && opkg install https-dns-proxy
uci set https-dns-proxy.default.resolver_url='https://dns.nextdns.io/abc123'
uci commit https-dns-proxy
/etc/init.d/https-dns-proxy restart

Mobile Devices

iOS:
  Install NextDNS app from App Store
  Or: Settings > General > VPN & Device Management
  Install NextDNS configuration profile
 
Android:
  Settings > Network > Private DNS
  DNS Provider: abc123.dns.nextdns.io
 
  Or: Install NextDNS app from Play Store

Microsoft Zero Trust DNS (Windows 11)

For enterprise Windows environments, Microsoft's ZTDNS enforces that endpoints can only communicate with domains resolved through approved DNS servers.

# Enable ZTDNS (Windows 11 23H2+)
# Requires Windows Defender Firewall in enforcing mode
 
# Configure Protected DNS Servers via Group Policy:
# Computer Configuration > Administrative Templates > Network > DNS Client
# > Configure DNS over HTTPS (DoH) name resolution
# > Protected DNS servers: https://dns.nextdns.io/abc123
 
# Windows Firewall blocks all traffic to domains not resolved
# through the protected DNS server

Monitoring and Analytics

Log Analysis

NextDNS Analytics Dashboard provides:
  - Total queries over time
  - Blocked queries by category
  - Top domains (allowed and blocked)
  - Top blocked reasons (threat, ad, tracker)
  - Device-level breakdown
  - Geographic query distribution
 
Log Settings:
  Retention: 1 hour / 6 hours / 1 day / 1 week / 1 month / 3 months / 1 year / 2 years
  Storage Location: US / EU / UK / Switzerland
  Logging: [ ] Enable / [ ] Disable

API Integration

# NextDNS API for automated monitoring
# Get analytics data
curl -H "X-Api-Key: your-api-key" \
  "https://api.nextdns.io/profiles/abc123/analytics/domains?from=-24h"
 
# Get blocked domains
curl -H "X-Api-Key: your-api-key" \
  "https://api.nextdns.io/profiles/abc123/analytics/domains?from=-24h&status=blocked"
 
# Export logs for SIEM integration
curl -H "X-Api-Key: your-api-key" \
  "https://api.nextdns.io/profiles/abc123/logs?from=-1h" \
  | jq '.data[] | select(.status == "blocked")'

Zero Trust DNS Policy Framework

Policy Tiers

Tier 1 - Security (Mandatory for all):
  - Threat intelligence blocking
  - Cryptojacking protection
  - DNS rebinding protection
  - DGA detection
  - NRD blocking (< 30 days)
 
Tier 2 - Privacy (Recommended):
  - Tracker blocking
  - Native telemetry blocking
  - CNAME cloaking protection
 
Tier 3 - Compliance (Organization-specific):
  - Category-based blocking
  - Custom allowlists/denylists
  - Time-based access policies
  - Log retention per regulatory requirements

Security Best Practices

  1. Enforce encrypted DNS: Block plaintext DNS (port 53 UDP/TCP) at the firewall
  2. Use NextDNS CLI on endpoints: Ensures per-device identification and logging
  3. Enable NRD blocking: Newly registered domains are overwhelmingly malicious
  4. Block DNS-over-HTTPS bypass: Ensure browsers use system DNS, not built-in DoH
  5. Review blocklists quarterly: Remove false positives, add organizational blocks
  6. Enable CNAME cloaking protection: Prevents tracker evasion via CNAME records
  7. Set appropriate log retention: Balance privacy with forensic needs (90 days recommended)
  8. Monitor for DNS tunneling: Watch for unusual query patterns and high entropy domains
  9. Deploy at router level: Catches all devices including IoT and unmanaged endpoints
  10. Combine with endpoint DNS: Defense in depth with both router and per-device filtering

References

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.7 KB

API Reference: Zero Trust DNS with NextDNS

NextDNS REST API

Authentication

Header: X-Api-Key: <your-api-key>
Base URL: https://api.nextdns.io

Profile Endpoints

Method Endpoint Description
GET /profiles/{id} Get profile configuration
GET /profiles/{id}/security Get security feature settings
GET /profiles/{id}/denylist Get blocked domains list
GET /profiles/{id}/allowlist Get allowed domains list
GET /profiles/{id}/logs Get DNS query logs
GET /profiles/{id}/analytics/status Query volume analytics
GET /profiles/{id}/analytics/domains Top queried domains
GET /profiles/{id}/analytics/blockedReasons Block reason breakdown

Security Feature Keys

Key Feature
threatIntelligenceFeeds Real-time threat intel blocking
aiDetection AI-based threat detection
googleSafeBrowsing Google Safe Browsing integration
cryptojacking Cryptomining domain blocking
dnsRebinding DNS rebinding attack protection
idnHomographs IDN homograph attack protection
typosquatting Typosquatting domain detection
dga Domain generation algorithm blocking
nrd Newly registered domain blocking

Log Entry Fields

Field Description
domain Queried domain name
status allowed, blocked, or default
reasons Array of block reasons
clientIp Requesting client IP
timestamp Query timestamp (ISO 8601)

References

standards.md1.7 KB

Standards Reference: Zero Trust DNS with NextDNS

DNS Security Standards

RFC 8484: DNS Queries over HTTPS (DoH)

  • Encrypts DNS queries over HTTPS on port 443
  • Prevents DNS eavesdropping and manipulation
  • Browser and OS-level support

RFC 7858: DNS over Transport Layer Security (DoT)

  • Encrypts DNS queries over TLS on port 853
  • Dedicated port enables network-level policy control
  • Supported by Android 9+, systemd-resolved, Unbound

RFC 9250: DNS over Dedicated QUIC Connections (DoQ)

  • Lower latency than DoH/DoT
  • Multiplexed queries without head-of-line blocking
  • Supported by NextDNS and Adguard

NIST SP 800-81-2: Secure Domain Name System Deployment Guide

  • DNS infrastructure security requirements
  • DNSSEC validation recommendations
  • DNS monitoring and logging guidance

Zero Trust DNS Standards

Microsoft ZTDNS (Windows 11)

  • Enforces that endpoints only use approved DNS resolvers
  • Windows Firewall blocks traffic to domains not resolved through protected DNS
  • Integration with Windows Defender for endpoint protection

CISA ZTMM - Network Pillar

  • DNS encryption requirement for zero trust compliance
  • DNS monitoring for visibility and analytics
  • DNS filtering as network security control

Compliance Mapping

NIST SP 800-53

  • SC-20: Secure Name/Address Resolution Service (Authoritative Source)
  • SC-21: Secure Name/Address Resolution Service (Recursive or Caching Resolver)
  • SC-22: Architecture and Provisioning for Name/Address Resolution Service
  • SI-4: Information System Monitoring (DNS logging)

CIS Controls v8

  • Control 9.2: Use DNS Filtering Services
  • Control 9.3: Maintain and Enforce Network-Based URL Filters
  • Control 13.3: Deploy Network Intrusion Detection (DNS monitoring)
workflows.md2.4 KB

Workflows: Zero Trust DNS with NextDNS

Workflow 1: Initial NextDNS Deployment

Step 1: Create NextDNS Configuration Profile
  - Sign up at nextdns.io
  - Create configuration profile with unique ID
  - Configure security settings (all threat protection enabled)
  - Configure privacy settings (blocklists, native tracking)
  - Set log retention policy
 
Step 2: Deploy to Network Infrastructure
  - Configure router-level DNS (DoH/DoT)
  - Block plaintext DNS (port 53) at firewall for bypass prevention
  - Configure split DNS for internal domains
  - Test resolution of allowed and blocked domains
 
Step 3: Deploy to Endpoints
  - Install NextDNS CLI on managed endpoints
  - Configure mobile devices via app or Private DNS
  - Deploy MDM profile for iOS devices
  - Verify per-device identification in NextDNS dashboard
 
Step 4: Monitor and Tune
  - Review blocked domains for false positives
  - Add necessary allowlist entries
  - Monitor query patterns for anomalies
  - Adjust blocklists based on organizational needs

Workflow 2: DNS Security Policy Enforcement

Step 1: Define DNS Security Policy
  - Mandatory security protections (threat intel, DGA, NRD)
  - Privacy protections (tracker blocking, telemetry)
  - Compliance-specific blocking categories
  - Exception handling process
 
Step 2: Block Plaintext DNS Bypass
  - Firewall rule: Block outbound port 53 UDP/TCP
  - Exception: Only NextDNS CLI or approved resolvers
  - Block known DoH endpoints not managed by organization
  - Disable browser-level DoH in favor of system DNS
 
Step 3: Implement Monitoring
  - Set up API integration for log export
  - Forward DNS logs to SIEM
  - Create alerts for suspicious DNS patterns
  - Monitor for DNS tunneling indicators

Workflow 3: Incident Response with DNS Logs

Step 1: Detect Suspicious Activity
  - Alert on high-frequency queries to single domain
  - Alert on queries to known C2 domains (auto-blocked)
  - Alert on DGA-like domain patterns
  - Alert on DNS tunneling indicators (high entropy, long subdomains)
 
Step 2: Investigate
  - Query NextDNS API for device-level DNS logs
  - Correlate blocked domains with threat intelligence
  - Identify affected devices and users
  - Determine scope of potential compromise
 
Step 3: Respond
  - Add malicious domains to denylist for immediate blocking
  - Isolate affected endpoints
  - Update firewall rules as needed
  - Document findings for incident report

Scripts 2

agent.py5.9 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for configuring and auditing NextDNS zero trust DNS filtering via API."""

import requests
import json
import argparse
from datetime import datetime, timezone

NEXTDNS_API = "https://api.nextdns.io"


def get_profile(api_key, profile_id):
    """Retrieve NextDNS profile configuration."""
    headers = {"X-Api-Key": api_key}
    resp = requests.get(f"{NEXTDNS_API}/profiles/{profile_id}", headers=headers, timeout=15)
    resp.raise_for_status()
    profile = resp.json()
    print(f"[*] Profile: {profile.get('name', profile_id)}")
    print(f"  Security: {json.dumps(profile.get('security', {}), indent=2)[:200]}")
    return profile


def audit_security_settings(api_key, profile_id):
    """Audit security features enabled on a NextDNS profile."""
    headers = {"X-Api-Key": api_key}
    resp = requests.get(f"{NEXTDNS_API}/profiles/{profile_id}/security", headers=headers, timeout=15)
    resp.raise_for_status()
    security = resp.json()
    findings = []
    checks = {
        "threatIntelligenceFeeds": "Threat intelligence feeds",
        "aiDetection": "AI-driven threat detection",
        "googleSafeBrowsing": "Google Safe Browsing",
        "cryptojacking": "Cryptojacking protection",
        "dnsRebinding": "DNS rebinding protection",
        "idnHomographs": "IDN homograph protection",
        "typosquatting": "Typosquatting protection",
        "dga": "DGA domain protection",
        "nrd": "Newly registered domains blocking",
        "ddns": "Dynamic DNS blocking",
        "csam": "CSAM blocking",
    }
    for key, label in checks.items():
        enabled = security.get(key, False)
        status = "ENABLED" if enabled else "DISABLED"
        if not enabled:
            findings.append({"feature": label, "key": key, "severity": "MEDIUM"})
        print(f"  [{'+' if enabled else '!'}] {label}: {status}")
    print(f"\n[*] {len(findings)} security features disabled")
    return findings


def get_query_logs(api_key, profile_id, limit=100):
    """Retrieve recent DNS query logs for analysis."""
    headers = {"X-Api-Key": api_key}
    params = {"limit": limit}
    resp = requests.get(f"{NEXTDNS_API}/profiles/{profile_id}/logs",
                        headers=headers, params=params, timeout=15)
    resp.raise_for_status()
    logs = resp.json().get("data", [])
    blocked = [l for l in logs if l.get("status") == "blocked"]
    print(f"[*] Query logs: {len(logs)} total, {len(blocked)} blocked")
    for entry in blocked[:10]:
        print(f"  [BLOCKED] {entry.get('domain')} - reason: {entry.get('reasons', ['?'])[0]}")
    return logs


def get_analytics(api_key, profile_id, period="last30d"):
    """Retrieve DNS analytics and threat statistics."""
    headers = {"X-Api-Key": api_key}
    endpoints = {
        "queries": f"/profiles/{profile_id}/analytics/status",
        "domains": f"/profiles/{profile_id}/analytics/domains",
        "blocked_reasons": f"/profiles/{profile_id}/analytics/blockedReasons",
    }
    analytics = {}
    for name, path in endpoints.items():
        resp = requests.get(f"{NEXTDNS_API}{path}", headers=headers,
                            params={"from": f"-{period}"}, timeout=15)
        if resp.status_code == 200:
            analytics[name] = resp.json()
    if "queries" in analytics:
        data = analytics["queries"].get("data", [])
        total = sum(d.get("queries", 0) for d in data)
        blocked = sum(d.get("blockedQueries", 0) for d in data)
        print(f"[*] Analytics ({period}): {total} queries, {blocked} blocked "
              f"({blocked/total*100:.1f}%)" if total else "[*] No query data")
    return analytics


def check_denylist(api_key, profile_id):
    """Check configured denylists and custom blocked domains."""
    headers = {"X-Api-Key": api_key}
    resp = requests.get(f"{NEXTDNS_API}/profiles/{profile_id}/denylist",
                        headers=headers, timeout=15)
    resp.raise_for_status()
    denylist = resp.json()
    entries = denylist.get("data", [])
    print(f"[*] Denylist entries: {len(entries)}")
    for e in entries[:20]:
        print(f"  {e.get('id', 'unknown')}: active={e.get('active', True)}")
    return entries


def generate_report(profile, findings, logs, analytics, output_path):
    """Generate NextDNS audit report."""
    report = {
        "audit_date": datetime.now(timezone.utc).isoformat(),
        "profile": profile.get("name", "unknown"),
        "security_findings": findings,
        "blocked_queries_sample": [l for l in logs if l.get("status") == "blocked"][:20],
        "analytics_summary": analytics,
    }
    with open(output_path, "w") as f:
        json.dump(report, f, indent=2, default=str)
    print(f"\n[*] Report saved to {output_path}")


def main():
    parser = argparse.ArgumentParser(description="NextDNS Zero Trust DNS Audit Agent")
    parser.add_argument("action", choices=["audit", "logs", "analytics", "denylist", "full-audit"])
    parser.add_argument("--api-key", required=True, help="NextDNS API key")
    parser.add_argument("--profile", required=True, help="NextDNS profile ID")
    parser.add_argument("-o", "--output", default="nextdns_audit.json")
    args = parser.parse_args()

    if args.action == "audit":
        get_profile(args.api_key, args.profile)
        audit_security_settings(args.api_key, args.profile)
    elif args.action == "logs":
        get_query_logs(args.api_key, args.profile)
    elif args.action == "analytics":
        get_analytics(args.api_key, args.profile)
    elif args.action == "denylist":
        check_denylist(args.api_key, args.profile)
    elif args.action == "full-audit":
        prof = get_profile(args.api_key, args.profile)
        findings = audit_security_settings(args.api_key, args.profile)
        logs = get_query_logs(args.api_key, args.profile)
        analytics = get_analytics(args.api_key, args.profile)
        generate_report(prof, findings, logs, analytics, args.output)


if __name__ == "__main__":
    main()
process.py9.4 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
NextDNS Zero Trust DNS Configuration and Monitoring.

Manages NextDNS profiles, analyzes DNS logs for threats,
and generates compliance reports for DNS security posture.
"""

import json
import datetime
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional
import math


@dataclass
class DNSPolicy:
    name: str
    security_features: list = field(default_factory=list)
    privacy_blocklists: list = field(default_factory=list)
    native_tracking: list = field(default_factory=list)
    allowlist: list = field(default_factory=list)
    denylist: list = field(default_factory=list)
    log_retention_days: int = 90


@dataclass
class DNSQueryLog:
    timestamp: str
    domain: str
    query_type: str
    status: str  # "allowed", "blocked"
    blocked_reason: str = ""
    device: str = ""
    client_ip: str = ""


class NextDNSPolicyGenerator:
    """Generate NextDNS configuration profiles."""

    SECURITY_FEATURES = [
        "threat_intelligence_feeds",
        "ai_driven_threat_detection",
        "google_safe_browsing",
        "cryptojacking_protection",
        "dns_rebinding_protection",
        "idn_homograph_attacks",
        "typosquatting_protection",
        "dga_protection",
        "nrd_protection",
        "ddns_blocking",
        "parked_domains",
        "csam_blocking",
    ]

    PRIVACY_BLOCKLISTS = [
        "nextdns_recommended",
        "oisd_full",
        "easyprivacy",
        "adguard_dns_filter",
        "hagezi_pro",
        "steven_black_unified",
    ]

    NATIVE_TRACKING = [
        "windows", "apple", "samsung", "xiaomi",
        "huawei", "roku", "sonos", "alexa",
    ]

    def create_enterprise_policy(self, name: str) -> DNSPolicy:
        return DNSPolicy(
            name=name,
            security_features=self.SECURITY_FEATURES.copy(),
            privacy_blocklists=["nextdns_recommended", "oisd_full", "easyprivacy"],
            native_tracking=["windows", "apple"],
            log_retention_days=90,
        )

    def create_strict_policy(self, name: str) -> DNSPolicy:
        return DNSPolicy(
            name=name,
            security_features=self.SECURITY_FEATURES.copy(),
            privacy_blocklists=self.PRIVACY_BLOCKLISTS.copy(),
            native_tracking=self.NATIVE_TRACKING.copy(),
            log_retention_days=365,
        )

    def create_minimal_policy(self, name: str) -> DNSPolicy:
        return DNSPolicy(
            name=name,
            security_features=[
                "threat_intelligence_feeds",
                "cryptojacking_protection",
                "dns_rebinding_protection",
                "dga_protection",
                "nrd_protection",
            ],
            privacy_blocklists=["nextdns_recommended"],
            native_tracking=[],
            log_retention_days=30,
        )

    def export_policy(self, policy: DNSPolicy, output_path: str):
        config = {
            "name": policy.name,
            "security": {
                "features_enabled": policy.security_features,
            },
            "privacy": {
                "blocklists": policy.privacy_blocklists,
                "native_tracking_protection": policy.native_tracking,
                "block_cname_cloaking": True,
            },
            "allowlist": policy.allowlist,
            "denylist": policy.denylist,
            "logging": {
                "enabled": True,
                "retention_days": policy.log_retention_days,
                "storage_location": "US",
            },
        }
        path = Path(output_path)
        path.parent.mkdir(parents=True, exist_ok=True)
        with open(path, "w") as f:
            json.dump(config, f, indent=2)
        return config


class DNSLogAnalyzer:
    """Analyze DNS query logs for security threats."""

    def __init__(self):
        self.logs: list[DNSQueryLog] = []
        self.findings: list[dict] = []

    def add_log(self, log: DNSQueryLog):
        self.logs.append(log)

    def calculate_entropy(self, domain: str) -> float:
        """Calculate Shannon entropy of a domain name (DNS tunneling indicator)."""
        label = domain.split(".")[0]
        if not label:
            return 0.0
        freq = {}
        for c in label:
            freq[c] = freq.get(c, 0) + 1
        entropy = 0.0
        for count in freq.values():
            p = count / len(label)
            if p > 0:
                entropy -= p * math.log2(p)
        return entropy

    def detect_dns_tunneling(self, threshold: float = 4.0) -> list[dict]:
        """Detect potential DNS tunneling based on subdomain entropy and length."""
        suspects = []
        for log in self.logs:
            if log.status == "blocked":
                continue
            subdomain = log.domain.split(".")[0]
            entropy = self.calculate_entropy(log.domain)
            if entropy > threshold and len(subdomain) > 20:
                suspects.append({
                    "domain": log.domain,
                    "entropy": round(entropy, 2),
                    "subdomain_length": len(subdomain),
                    "device": log.device,
                    "timestamp": log.timestamp,
                })
        if suspects:
            self.findings.append({
                "type": "dns_tunneling_suspect",
                "severity": "HIGH",
                "count": len(suspects),
                "details": suspects[:20],
            })
        return suspects

    def detect_dga_domains(self) -> list[dict]:
        """Detect domain generation algorithm patterns."""
        suspects = []
        for log in self.logs:
            parts = log.domain.split(".")
            if len(parts) >= 2:
                sld = parts[-2]
                entropy = self.calculate_entropy(sld + "." + parts[-1])
                if entropy > 3.5 and len(sld) > 8 and not any(
                    c in sld for c in ["-", "_"]
                ):
                    digits = sum(1 for c in sld if c.isdigit())
                    if digits / len(sld) > 0.3:
                        suspects.append({
                            "domain": log.domain,
                            "entropy": round(entropy, 2),
                            "digit_ratio": round(digits / len(sld), 2),
                        })
        if suspects:
            self.findings.append({
                "type": "dga_domain_suspect",
                "severity": "HIGH",
                "count": len(suspects),
                "details": suspects[:20],
            })
        return suspects

    def get_blocked_summary(self) -> dict:
        """Summarize blocked queries by reason."""
        blocked = [l for l in self.logs if l.status == "blocked"]
        by_reason = {}
        for log in blocked:
            reason = log.blocked_reason or "unknown"
            by_reason[reason] = by_reason.get(reason, 0) + 1

        by_domain = {}
        for log in blocked:
            by_domain[log.domain] = by_domain.get(log.domain, 0) + 1

        top_blocked = sorted(by_domain.items(), key=lambda x: x[1], reverse=True)[:20]

        return {
            "total_blocked": len(blocked),
            "total_allowed": len(self.logs) - len(blocked),
            "block_rate": round(len(blocked) / len(self.logs) * 100, 2) if self.logs else 0,
            "by_reason": by_reason,
            "top_blocked_domains": dict(top_blocked),
        }

    def generate_report(self) -> dict:
        return {
            "report_date": datetime.datetime.now().isoformat(),
            "total_queries": len(self.logs),
            "blocked_summary": self.get_blocked_summary(),
            "security_findings": self.findings,
            "unique_devices": len(set(l.device for l in self.logs if l.device)),
            "unique_domains": len(set(l.domain for l in self.logs)),
        }


def main():
    """Demonstrate NextDNS policy generation and DNS log analysis."""
    # Generate policies
    gen = NextDNSPolicyGenerator()
    enterprise = gen.create_enterprise_policy("Enterprise Standard")
    enterprise.allowlist = ["login.microsoftonline.com", "graph.microsoft.com", "*.company.com"]
    enterprise.denylist = ["malware-c2.example.com", "data-exfil.example.com"]

    config = gen.export_policy(enterprise, "nextdns_enterprise_policy.json")
    print("Enterprise DNS Policy:")
    print(json.dumps(config, indent=2))

    # Analyze sample DNS logs
    analyzer = DNSLogAnalyzer()
    sample_logs = [
        DNSQueryLog("2024-01-15T10:00:00Z", "google.com", "A", "allowed", device="laptop-1"),
        DNSQueryLog("2024-01-15T10:00:01Z", "malware.example.com", "A", "blocked",
                    "threat_intelligence", "laptop-2"),
        DNSQueryLog("2024-01-15T10:00:02Z", "aHR0cHM6Ly9leGFtcGxlLmNvbQ.tunnel.evil.com",
                    "TXT", "allowed", device="server-1"),
        DNSQueryLog("2024-01-15T10:00:03Z", "x8k3m9p2q5.botnet.com", "A", "blocked",
                    "dga_protection", "laptop-3"),
        DNSQueryLog("2024-01-15T10:00:04Z", "office.com", "A", "allowed", device="laptop-1"),
        DNSQueryLog("2024-01-15T10:00:05Z", "ads.tracker.com", "A", "blocked",
                    "ad_blocker", "laptop-1"),
    ]

    for log in sample_logs:
        analyzer.add_log(log)

    analyzer.detect_dns_tunneling()
    analyzer.detect_dga_domains()

    report = analyzer.generate_report()
    print("\n" + "=" * 60)
    print("DNS Security Analysis Report")
    print("=" * 60)
    print(json.dumps(report, indent=2))


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.5 KB
Keep exploring