id: T021 name: FlashDNS PowerDNS Parity + Reverse DNS goal: Complete FlashDNS to achieve PowerDNS replacement capability with intelligent reverse DNS support status: complete priority: P1 owner: peerA (strategy) + peerB (implementation) created: 2025-12-08 depends_on: [T017] context: | PROJECT.md specifies FlashDNS requirements: - "PowerDNSを100%完全に代替可能なように" (100% PowerDNS replacement) - "逆引きDNSをやるためにとんでもない行数のBINDのファイルを書くというのがあり、バカバカしすぎるのでサブネットマスクみたいなものに対応すると良い" (Reverse DNS with subnet/CIDR support to avoid BIND config explosion) - "DNS All-Rounderという感じにしたい" (DNS all-rounder) T017 deepened FlashDNS with metadata, gRPC, DNS handler. Spec already defines PTR record type, but lacks: - Automatic reverse zone management from CIDR - Subnet-based PTR generation - Zone transfer (AXFR) for DNS synchronization - NOTIFY support for zone change propagation acceptance: - Reverse DNS zones auto-generated from CIDR input - PTR records generated per-IP or per-subnet with patterns - AXFR zone transfer (at least outbound) - NOTIFY on zone changes - cargo test passes with reverse DNS tests steps: - step: S1 action: Reverse zone model design priority: P0 status: complete owner: peerA outputs: - path: docs/por/T021-flashdns-parity/design.md note: 207L design doc with ReverseZone type, pattern substitution, CIDR→arpa conversion, storage schema notes: | Design reverse DNS zone handling: - ReverseZone type with CIDR field (e.g., "192.168.1.0/24") - Auto-generate in-addr.arpa zone name from CIDR - Support both /24 (class C) and larger subnets (/16, /8) - IPv6 ip6.arpa zones from /64, /48 prefixes Key insight: Instead of creating individual PTR records for each IP, support pattern-based PTR generation: "192.168.1.0/24" → "*.1.168.192.in-addr.arpa" Pattern: "{ip}-{subnet}.example.com" → "192-168-1-5.example.com" deliverables: - ReverseZone type in novanet-types - CIDR → arpa zone conversion utility - Design doc in docs/por/T021-flashdns-parity/design.md - step: S2 action: Reverse zone API + storage priority: P0 status: complete owner: peerB outputs: - path: flashdns/crates/flashdns-types/src/reverse_zone.rs note: ReverseZone type with cidr_to_arpa() utility (88L, 6 unit tests passing) - path: flashdns/crates/flashdns-api/proto/flashdns.proto note: ReverseZoneService with 5 RPCs (62L added) - path: flashdns/crates/flashdns-server/src/metadata.rs note: Storage methods for all 3 backends (81L added) - path: flashdns/crates/flashdns-types/Cargo.toml note: Added ipnet dependency for CIDR parsing notes: | Add ReverseZoneService to gRPC API: - CreateReverseZone(cidr, org_id, project_id, ptr_pattern) - DeleteReverseZone(zone_id) - ListReverseZones(org_id, project_id) - GetPtrRecord(ip_address) - resolve any IP in managed ranges Storage schema: - flashdns/reverse_zones/{zone_id} - flashdns/reverse_zones/by-cidr/{cidr_key} deliverables: - ReverseZoneService in proto - ReverseZoneStore implementation - Unit tests - step: S3 action: Dynamic PTR resolution priority: P0 status: complete owner: peerB outputs: - path: flashdns/crates/flashdns-server/src/dns/ptr_patterns.rs note: Pattern substitution utilities (138L, 7 unit tests passing) - path: flashdns/crates/flashdns-server/src/dns/handler.rs note: PTR query interception + longest prefix match (85L added) - path: flashdns/crates/flashdns-server/Cargo.toml note: Added ipnet dependency notes: | Extend DNS handler for reverse queries: - Intercept PTR queries for managed reverse zones - Apply pattern substitution to generate PTR response - Example: Query "5.1.168.192.in-addr.arpa" with pattern "{4}.{3}.{2}.{1}.hosts.example.com" → Response: "192.168.1.5.hosts.example.com" - Cache generated responses deliverables: - handler.rs updated for PTR pattern resolution - Unit tests for various CIDR sizes - step: S4 action: Zone transfer (AXFR) support priority: P2 status: deferred owner: peerB notes: | Implement outbound AXFR for zone synchronization: - RFC 5936 compliant AXFR responses - Support in DNS TCP handler - Optional authentication (TSIG - later phase) - Configuration for allowed transfer targets Use case: Secondary DNS servers can pull zones from FlashDNS deliverables: - AXFR handler in dns_handler.rs - Configuration for transfer ACLs - Integration test with dig axfr - step: S5 action: NOTIFY support priority: P2 status: deferred owner: peerB notes: | Send DNS NOTIFY on zone changes: - RFC 1996 compliant NOTIFY messages - Configurable notify targets per zone - Triggered on zone/record create/update/delete Use case: Instant propagation to secondary DNS deliverables: - notify.rs module - Integration with zone/record mutation hooks - Unit tests - step: S6 action: Integration test + documentation priority: P0 status: complete owner: peerB outputs: - path: flashdns/crates/flashdns-server/tests/reverse_dns_integration.rs note: E2E integration tests (165L, 4 test functions) - path: specifications/flashdns/README.md note: Reverse DNS documentation section (122L added) notes: | End-to-end test: 1. Create reverse zone for 10.0.0.0/8 with pattern 2. Query PTR for 10.1.2.3 via DNS 3. Verify correct pattern-based response 4. Test zone transfer (AXFR) retrieval 5. Verify NOTIFY sent on zone change Update spec with reverse DNS section. deliverables: - Integration tests passing - specifications/flashdns/README.md updated - Evidence log blockers: [] evidence: [] notes: | PowerDNS replacement features prioritized: - P0: Reverse DNS (PROJECT.md explicit pain point) - P1: Zone transfer + NOTIFY (operational necessity) - P2: DNSSEC (spec marks as "planned", defer) - P2: DoH/DoT (spec marks as "planned", defer) Pattern-based PTR is the key differentiator: - Traditional: 1 PTR record per IP in /24 = 256 records - FlashDNS: 1 reverse zone with pattern = 0 explicit records - Massive reduction in configuration overhead