Skip to content

Releases: Ashteeer/DNS-IPCollector

v2.0.0

Choose a tag to compare

@Ashteeer Ashteeer released this 09 Aug 18:48

Breaking change. v1.0.0 implemented the spec wrong: it wrote a text file of ip:sha256hash pairs. The list "formatted as ip:hash" is an ipset set of type hash:ip — the kernel facility. v2.0.0 is that.

The app now writes no files at all. The kernel set is the storage.

How it works

ipset -exist restore   <<<   create dns_clients hash:ip family inet hashsize 1024 maxelem 65536 timeout 10800
                             add dns_clients 192.168.1.5 timeout 10800
  • Every incoming DNS request on every transport protocol is intercepted through the official IDnsRequestController interface — UDP, TCP, DoT (Tls), DoH and DoH3 (Https), DoQ (Quic) and the PROXY protocol variants.
  • Each new query re-adds the client. Thanks to the global -exist flag, ipset does not error on a duplicate — it resets the timeout of the existing element. That is the refresh behaviour.
  • Idle clients are expired by the kernel itself. Entries live in the kernel, so restarting the DNS server does not lose them.
  • Default timeout is 3 hours. Nothing is filtered out by default — every request from every client is tracked.

Highlights

  • Batched writes. A process per DNS query is not viable, so pushes of the same client are coalesced (60 s window, far below the 3 h timeout) and a whole batch is fed to a single ipset restore process per tick.
  • IPv4 and IPv6 through separate sets (dns_clients / dns_clients6), since an ipset set has a fixed address family. ::ffff:a.b.c.d is unwrapped into plain IPv4; link local scope ids are stripped.
  • Resilient. If ipset is missing or the process lacks CAP_NET_ADMIN, the error is logged once, entries stay queued, the setup is retried, and a failed batch is requeued rather than dropped.
  • hash:net mode to aggregate clients into /24, /64, … instead of single addresses.
  • dryRun logs the exact ipset commands without executing them, so the config can be validated anywhere.
  • Never interferes. The app always returns Allow; any internal failure is caught and cannot affect DNS resolution.
  • Set names, type, timeout, create parameters, batching, network and protocol filters and log verbosity are all in dnsApp.config, and saving it hot reloads the app.

Requirements

  • Technitium DNS Server v15.3 or later (app API DnsServerCore.ApplicationCommon 10.1, .NET 10). Verified against v15.4.
  • Linux with the ipset binary installed (apt install ipset).
  • The DNS server process must be root or hold CAP_NET_ADMIN. In Docker: --cap-add NET_ADMIN; note the official image does not ship the ipset binary.

Surviving a reboot is out of scope for the app and is handled by ipset save / ipset restore (ipset-persistent, a systemd unit, etc.).

Install

  1. Download IPCollectorApp-v2.0.0.zip below.
  2. DNS server web console -> Apps -> Install, upload the zip.
  3. Open Config to adjust the settings, then Save.
  4. Verify on the host: ipset list dns_clients.

Upgrading from v1.0.0

The config format changed completely; the old storage, hashing and output sections are gone. Delete the old dnsApp.config (or let the app rewrite it) and re-apply your settings. The old ip-list.txt and ip-state.json files in the app folder can be removed.

v1.0.0

Choose a tag to compare

@Ashteeer Ashteeer released this 09 Aug 18:23

First public release of DNS IP Collector, a Technitium DNS Server app that intercepts every incoming DNS request on every transport protocol and maintains a self-refreshing list of unique clients in the ip:hash format.

Highlights

  • All protocols. Uses the official IDnsRequestController interface, which the DNS server calls for every request before processing: UDP, TCP, DoT (Tls), DoH and DoH3 (Https), DoQ (Quic), plus the PROXY protocol variants.
  • IPv4 and IPv6, including ::ffff:a.b.c.d unwrapping, link local scope id handling and optional subnet aggregation (/24, /64, ...).
  • Expiration with refresh. A new client is stored with now + retentionSeconds; every subsequent query pushes its expiry forward. A background timer purges entries that go untouched for the whole retention period.
  • Survives restarts. Expiry timestamps are persisted next to the list.
  • Never interferes. The app always returns Allow; any internal failure is caught and logged and cannot affect DNS resolution.
  • Config driven. File paths, retention, hashing (algorithm / salt / length / encoding), line templates, network and protocol filters and log verbosity all live in dnsApp.config. Saving the config hot reloads the app.

Hash

hash = ENCODE( ALGORITHM( UTF8( salt + ip ) ) )[0 .. length]

Defaults to SHA256, empty salt, lowercase hex, first 16 characters, so the value can be reproduced by any external tool.

Install

  1. Download IPCollectorApp-v1.0.0.zip below.
  2. DNS server web console -> Apps -> Install, upload the zip.
  3. Open Config to adjust the settings, then Save.

The list is written to <dns-server-config>/apps/<app name>/ip-list.txt.

Requirements

Technitium DNS Server v15.3 or later (app API DnsServerCore.ApplicationCommon 10.1, .NET 10). Verified against v15.4.

0.3

Choose a tag to compare

@Ashteeer Ashteeer released this 09 Aug 19:40

Same ipset-based collector as 2.0.0. This release switches to a plain X.Y version/tag scheme going forward (no v prefix, at most two numbers) and documents a real-world permission issue.

Fixed / documented

'ipset version' failed: ... Operation not permitted under a systemd-managed dns.service: ipset talks to the kernel over netlink and needs CAP_NET_ADMIN, which a plain service unit does not grant by default (only CAP_NET_BIND_SERVICE for port 53). The README now has the exact fix — an AmbientCapabilities systemd override, or setcap cap_net_admin+ep on the ipset binary as an alternative when ambient capabilities don't stick.

Also in this release

  • build.ps1 now packages as IPCollectorApp-X.Y.zip (previously IPCollectorApp-vX.Y.Z.zip).

No behavioral changes to the collector itself — see 2.0.0 release notes for the full feature set (kernel ipset storage, -exist timeout refresh, batching, IPv4/IPv6 split, hash:net mode, dryRun).