tiktok, facebook, start the capture, and every query whose name holds one of the keywords
(api.tiktok.com, v16.tiktokcdn.com, graph.facebook.com…) shows up within a second.
The results come two ways:
- By domain: queries grouped by registered domain (
api.tiktok.comandwww.tiktok.comundertiktok.com,p16.tiktokcdn-us.comundertiktokcdn-us.com; the public suffix list knows thatexample.co.ukis one domain). Each domain shows how many queries, names and clients it has, how many were already answered as blocked, and when it was last seen. Open a domain to see the names inside it. - Live: every query, newest first (the last 500), with the type, response code, where the answer came from and the client.
Start a capture
- Dashboard
- CLI
- AI assistant
1
Open Live Capture
Open DNS → Live Capture, or click Live capture on DNS → Query Logs, which carries
the log’s search over.
2
Pick a keyword list or enter keywords
Click one or more keyword lists under the keyword field, or type keywords,
for example
tiktok, facebook (or both). Optionally give a client address to watch one
device, and, if you can see all queries, pick the scope.3
Start
Click Start capture. Matching queries show up within a second. Stop ends it.
?q=, ?lists= (keyword list ids) and ?client= in the page’s address fill the form, so a
capture can be shared as a link.Keywords
- Separate keywords with commas or spaces; a name holding any of them matches.
tiktokmatchestiktok.com,tiktokcdn.comandtiktokv.com. - Matching is on the name as asked, in lowercase. A leading
*.or a trailing dot is ignored. - No keywords captures every query. Use it with a client address to see everything one device asks.
- Up to 50 keywords per capture, typed and from keyword lists together.
Keyword lists
Keywords you watch for often can be saved once under a name and then picked instead of typed: a Social media list holdingtiktok facebook instagram snapchat, a Games list holding
steam epicgames roblox. On DNS → Live Capture the lists show as buttons under the keyword
field. Click one or more (and type extra keywords if you like), then start the capture: it watches
for every keyword of the picked lists plus the typed ones.
- Dashboard
- CLI
- New list saves a list; with keywords typed, the button reads Save keywords as list and starts from them.
- The pencil button next to it edits or deletes a list.
- A list holds up to 50 keywords (one per line, or separated by commas or spaces) and a name of up to 64 characters, unique within its scope.
Changes are in the audit log as
capture_list.create, capture_list.update and
capture_list.delete; a capture’s capture.start entry names the lists it used. On a DNZ secondary
the lists are the primary’s, copied with its other settings, and read-only there.
Block from the results
Each domain has a Block button, and Block N selected blocks every ticked domain at once. Blocking adds a rule to the block list (DNS → Filtering → Blocking → Your rules, see Filtering). A rule covers the name and everything under it, so blockingtiktok.com blocks api.tiktok.com too. To block one name only, open its domain and click
Block only this. Domains a block rule already covers say In block list.
To keep what you block together, pick a list in Block into next to the results’ filter: Just a
rule (the default), one of your own lists (the ones you made under Blocklists), or New list…
with a name, which makes the list with the domains you block and keeps it picked for the next ones. A
domain in a list is blocked with everything under it, like a rule.
The rule’s comment records the keywords it came from, and it is in the
audit log as filter_rule.create, like any other rule. Rules take effect on the
next query: cached answers are not used for blocked names.
Which block list the rule lands in follows the capture’s scope:
Without that permission, the results show no Block buttons.
Another server
Queries are answered where clients send them: often at a secondary, while you are on the primary. On a primary, DNS → Live Capture has a Server choice: this server and each DNZ secondary. Pick one or more; the queries of the ones picked show here, with a Server column in the Live view when more than one is shown.- You need nothing on the secondary: no account, and no way to reach its API. Permissions are asked and checked on the primary (View query logs in a division, View all query logs for all of a server’s queries), and the secondary connects out to the primary, as it does for everything else. A firewall that keeps the primary from its API changes nothing.
- It is connected only during a capture. Nothing stays open between captures. Start notes the capture on the primary, in memory. The secondary hears of it in its check-in’s answer and only then opens two connections to the primary: a server-sent event stream for the filter, and a streaming upload of its hits. Both close when the capture ends.
- Usually at once, within a minute at worst. At Start the primary sends a DNS NOTIFY for the reserved name
capture.dnz.invalidto the secondary’s NOTIFY addresses, which makes it check in now. If a firewall keeps it out, the capture starts at the next check-in, and the page says Waiting for ns2… until then. A NOTIFY says nothing by itself: only the check-in’s answer decides, so a forged one costs one check-in, at most one every 5 seconds. It never counts in the NOTIFY status, so a lost one doesn’t mark the secondary Behind. - Bounded on both sides. A capture stops when the viewer leaves, the stream breaks or its time is up (its time counts from when the secondary connects). A primary that restarts knows no capture, so nothing stays running on the secondary. At most 16 captures run on a server, and at most 16 per secondary are asked for. Hits past a slow link are dropped and counted on the page (N skipped), as a slow viewer’s are.
- A division’s capture goes to the secondary as zone names and client networks, since zone ids differ between servers.
- Which servers. Only DNZ secondaries are listed; BIND, Knot and the like aren’t. One running an older DNZ shows disabled with update it, and one that hasn’t checked in for 3 minutes with not connected. A secondary shows only its own queries: it has no server choice and can’t watch its primary.
- Nothing more per query. The secondary runs the same capture code as ever: while nobody captures, a batch of queries costs one atomic load.
capture.start, with on naming the server. Blocking from the results adds the
rule on the primary, which the secondaries copy.
A reverse proxy in front of the primary must not buffer request bodies (nginx:
proxy_request_buffering off for
/api/replication/capture/), or hits wait until the capture ends. In a cluster of primaries, the secondary’s check-in must
reach the server you are connected to: a capture starts there and nowhere else. On a secondary that is a cluster itself,
the leader answers it.Scope and permissions
A client address narrows either one to a single device. API tokens with
logs.read can capture
their division. See Access for roles and permissions.
How it works
- The query log writer feeds the captures: it takes each batch of answered queries off the hot path every second (or every 500 queries). While nobody captures, a batch costs one atomic load. DNS answers never wait on a capture.
- Nothing is stored. A capture lives as long as its connection and ends when the page is closed,
Stop is pressed, or its time runs out. Starting one is in the audit log as
capture.start. - At most 16 captures run at once on a server. A viewer that falls behind gets a count of the queries it skipped instead of slowing anything down.
- Live capture works on every server, a DNZ secondary included, and a primary can show a secondary’s queries (Another server).
- In a cluster, a capture shows the queries answered by the server you are connected to, like the query log. Queries a client sends to another server show up in a capture there.
dnz_live_captureson/metricsis the number of captures running.
API
POST /api/capture answers with server-sent events. It needs logs.read in the division given by
division_id, or logs.server for the whole server.
Events:
With
on, start also has "server": "ns2", "waiting": true; connected ({"server": "ns2"}) says the secondary’s stream is
up; each hits has server; and end can also be {"reason": "ended", "message": "…"} (it stopped or broke) or
{"reason": "not_connected", "message": "…"} (it never connected, after 150 seconds). on is refused on a secondary (400) and
for a server that is older or not connected (409).
GET /api/capture/servers?division_id=2 lists what can be picked (logs.read there; without division_id, logs.server):
{"this": "ns1", "follows_primary": null, "servers": [{"id": 4, "name": "ns2", "available": true, "why": null, "message": null, "last_seen": "…"}]}.
why is older or not_connected; follows_primary names the primary on a secondary, which lists nothing.
A comment line (: ping) every 15 seconds keeps idle streams open through proxies. When too many
captures are running, the answer is 429.
Keyword lists:
A list comes back as
{"id": 3, "division_id": null, "name": "Social media", "keywords": ["tiktok", "facebook"], "created_at": "…"}.
API tokens with logs.read can read and use their division’s lists.
Next steps
Query logs
Search what clients asked in the past.
Filtering
Blocklists, rules, client groups and schedules.