-
-
Notifications
You must be signed in to change notification settings - Fork 552
Added MispConnectorApp
for Cyber Threat Intelligence-based blocking
#1403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…there is a concurrency issue
…s longer than interval
Thanks @zbalkan for the PR. |
Hi @ShreyasZare, I have a question for you. I followed the steps of Advanced Blocking App adnd returned the SOA but is it actually needed when the request gets blocked? I followed the handling of TXT queries as well. However, to me we can avoid that with the use of EDR. But it is up to you. |
Thanks for asking. The SOA in authority section is actually required as per the standards. The client will be useing the SOA record's TTL and MINIMUM value to do negative caching so by sending SOA, you get to control how much time the client will cache this blocked response. The TXT support is useful since many DNS clients do not support Extended DNS Errors so its useful when you need to test with tools like nslookup for example. |
Thanks for the clarification. I'll keep it as is then. |
I'll do some minor changes. I'll mark it as a draft and try to finish until next Friday. |
Found an edge case during tests. It may be related to my test environment though. I'll create a clean test environment and retest to reproduce, then finalize the PR. |
…task Signed-off-by: Zafer Balkan <zafer@zaferbalkan.com>
Signed-off-by: Zafer Balkan <zafer@zaferbalkan.com>
Finally it is complete. |
1. Problem Statement
Technitium DNS Server requires a direct, scalable method to ingest domain-based Indicators of Compromise (IOCs) from a MISP instance for network-level blocking. Any such integration must handle potentially massive datasets (>1m domains) and operate as a well-behaved background service, ensuring its resource consumption (CPU, memory) during IOC updates does not degrade the low-latency performance of the core DNS server.
2. Proposed Solution
This PR introduces a new Technitium DNS App called
MispConnectorApp
. It operates as a resilient background service that periodically fetches domain IOCs from a MISP instance and loads them into an optimized, in-memory blocklist.3. Architectural Decisions and Technical Implementation
This application was designed with the following key principles and patterns:
Configuration Model: POCO with Data Annotations
Configuration is managed via a strongly-typed Config POCO class, deserialized from dnsApp.config. Validation is handled declaratively using
System.ComponentModel.DataAnnotations
.This provides compile-time type safety and centralized validation, making the app safer and more maintainable than manual parsing. It fails fast on invalid configuration.
Data Fetching: Paginated and Resilient API Client
The FetchDomainsFromMispAsync method fetches data in configurable pages. Each page request includes a local retry policy with exponential backoff and jitter to handle transient network errors.
This ensures the entire update process is atomic (all-or-nothing) and prevents a single network blip from failing the entire multi-hour update cycle. It also ensures a low, stable resource footprint, protecting live DNS server performance.
Blocking Storage: FrozenSet
The blocklist is stored in a
FrozenSet<string>
, which is created during the update process.This is the ideal data structure for a "create-once, read-many" workload. It is immutable, inherently thread-safe for reads, and highly optimized for the fastest possible lookup performance, which is critical for the DNS query path.
Concurrency Model: Lock-Free Atomic Updates
The
_globalBlocklist
reference is updated usingInterlocked.Exchange()
. The read path in IsDomainBlocked accesses the FrozenSet directly without locks.This is the highest-performance, lock-free pattern for this scenario. It provides an instantaneous, atomic swap of the blocklist with zero blocking or contention on the read path, guaranteeing maximum query throughput.
Background Task Management: PeriodicTimer
The background update loop is managed by a System.Threading.PeriodicTimer within a long-running async Task.
This is the modern, correct, and safe way to handle periodic asynchronous work in .NET. It prevents reentrancy (overlapping updates) and integrates seamlessly with CancellationToken for graceful shutdown.
Query Processing Performance: Span on the Hot Path
The IsDomainBlocked method uses
ReadOnlySpan<char>
to perform parent domain lookups.This avoids heap allocations for intermediate substrings within the lookup loop, significantly reducing GC pressure and improving latency under heavy query load. However, we still create strings due to FrozenSet data structure. We get minor performance improvement here.
Diagnostics: EDE and TXT Reporting
The connector provides both Extended DNS Errors (EDE, RFC 8914) and optional TXT record reports for blocked domains.
These features are complementary. EDE provides a standards-compliant, machine-readable error code for modern resolvers, while TXT records offer a universally accessible, human-friendly diagnostic tool for administrators.