Claude 24f816b6a3
Consolidate 22 sibling repos into layered organism structure
Place useful parts of the surrounding repos into sica-fondt by layer, per the
body model (Ada = membrane; brain/endocrine/capabilities/knowledge non-Ada):

- brain/        LLM reasoning + providers (dapr, hermes, MoMoA)
- capabilities/ REPRAG sidecars: hermes tools/skills, dapr tools, parallel
                dispatch, A51 channels, and the OSINT cluster
- knowledge/    LORAG corpus: 754 cyber-skills, agency personas, secure-coding,
                MITRE ATT&CK data
- reference/    defensive threat-reference (C3, shhbruh doc) + AdaYaml parser

License handling: AGPL sources (worldosint, advanced_evolution, mercury,
Reticulum) and GPL DeTTECT are SPEC-only clean-room/port descriptions — no
copyleft code copied. MIT/Apache/data parts copied as working trees.

Safety: shhbruh escape/persistence material and C3 covert-C2 kept as reference
only, not wired into the running organism. See CONSOLIDATION.md.

https://claude.ai/code/session_01UehUqEXXJJCsHoA4voCU5c
2026-06-10 06:53:01 +00:00

282 lines
9.4 KiB
Python

#!/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()