dnstt_exporter/README.md

215 lines
6.2 KiB
Markdown
Raw Normal View History

2026-05-05 13:25:03 +02:00
# dnstt_exporter
Prometheus exporter for DNSTT client/session metrics.
2026-05-05 13:43:02 +02:00
`dnstt_exporter` observes DNSTT DNS traffic on a local Linux host and exports
aggregate Prometheus metrics. It does not proxy, terminate, or configure DNSTT;
it passively decodes DNSTT session IDs from DNS query names.
## Usage
```sh
sudo dnstt_exporter \
-dnstt.domain tunnel.example.com \
-dnstt.port 53 \
2026-05-05 13:57:12 +02:00
-geoip.country-database /path/to/GeoLite2-Country.mmdb \
-geoip.asn-database /path/to/GeoLite2-ASN.mmdb \
2026-05-05 13:43:02 +02:00
-web.listen-address :9713
```
The exporter needs permission to open an `AF_PACKET` raw socket. Run it as root
or grant the binary `CAP_NET_RAW`.
Metrics are served at `http://127.0.0.1:9713/metrics` by default.
2026-05-05 13:57:12 +02:00
## How It Works
`dnstt_exporter` opens a Linux `AF_PACKET` raw socket and passively watches UDP
DNS traffic on the configured DNSTT port. It parses IPv4 and IPv6 packets,
matches DNS query names against the configured DNSTT domain, and decodes the
DNSTT session ID from the query-name prefix.
The exporter treats a session as active when it has seen a query for that
session within the last 30 seconds. Peak client counts are the highest active
session counts observed since the exporter started.
GeoIP labels are based on the resolver address seen by the server. For incoming
queries this is the packet source address; for outgoing responses it is the
packet destination address. This may be a recursive resolver such as an ISP DNS
server, Cloudflare, Google, or Quad9, not the original DNSTT client.
The exporter does not run `dnstt-server`, proxy traffic, terminate DNSTT, or
decrypt tunnel payloads.
2026-05-05 13:43:02 +02:00
## Metrics
2026-05-05 13:57:12 +02:00
All DNSTT metrics use a `domain` label. If `-geoip.country-database` is set,
metrics also include `country`. If `-geoip.asn-database` is set, metrics also
include `asn`. Unmapped countries use `ZZ`; unmapped ASNs use `0`.
2026-05-05 13:43:02 +02:00
- `dnstt_active_clients`
- `dnstt_peak_clients`
- `dnstt_queries_total`
- `dnstt_bytes_in_total`
- `dnstt_bytes_out_total`
- `dnstt_sessions_total`
2026-05-27 09:07:51 +02:00
## Grafana Queries
Use `$domain` as a Grafana variable for the DNSTT domain, for example
`t2.bypasscensorship.org`. Replace `$__rate_interval` with a fixed range such
as `5m` if you are not using Grafana's built-in interval variables.
- Title: Current active clients
- Description: Current number of active DNSTT sessions for the selected domain.
- Visualization: Stat or gauge.
```promql
sum(dnstt_active_clients{domain="$domain"})
```
- Title: Peak active clients
- Description: Highest active DNSTT session count observed since the exporter
started.
- Visualization: Stat.
```promql
sum(dnstt_peak_clients{domain="$domain"})
```
- Title: Active clients by country
- Description: Current active DNSTT sessions grouped by resolver country.
- Visualization: Geomap, bar chart, or table.
```promql
sum by (country) (dnstt_active_clients{domain="$domain"})
```
- Title: Top countries by active clients
- Description: Countries with the most active DNSTT sessions right now.
- Visualization: Bar chart.
```promql
topk(10, sum by (country) (dnstt_active_clients{domain="$domain"}))
```
- Title: Active clients by ASN
- Description: Current active DNSTT sessions grouped by resolver ASN.
- Visualization: Bar chart or table.
```promql
sum by (asn) (dnstt_active_clients{domain="$domain"})
```
- Title: Top ASNs by active clients
- Description: Resolver ASNs with the most active DNSTT sessions right now.
- Visualization: Bar chart.
```promql
topk(10, sum by (asn) (dnstt_active_clients{domain="$domain"}))
```
- Title: Active clients by country and ASN
- Description: Current active DNSTT sessions split by both resolver country and
resolver ASN.
- Visualization: Table.
```promql
sum by (country, asn) (dnstt_active_clients{domain="$domain"})
```
- Title: Top country/ASN pairs by active clients
- Description: Country and ASN combinations with the most active DNSTT sessions
right now.
- Visualization: Bar chart or table.
```promql
topk(20, sum by (country, asn) (dnstt_active_clients{domain="$domain"}))
```
- Title: DNS query rate
- Description: Total observed DNSTT DNS queries per second for the selected
domain.
- Visualization: Time series.
```promql
sum(rate(dnstt_queries_total{domain="$domain"}[$__rate_interval]))
```
- Title: DNS query rate by country
- Description: Observed DNSTT DNS queries per second grouped by resolver country.
- Visualization: Stacked time series or bar chart. Use stacked time series for
trends over time, and bar chart for current top countries.
```promql
sum by (country) (rate(dnstt_queries_total{domain="$domain"}[$__rate_interval]))
```
- Title: Top ASNs by DNS query rate
- Description: Resolver ASNs producing the highest DNSTT DNS query rates.
- Visualization: Bar chart.
```promql
topk(10, sum by (asn) (rate(dnstt_queries_total{domain="$domain"}[$__rate_interval])))
```
- Title: Inbound DNS traffic rate
- Description: Bytes per second received in DNSTT DNS queries.
- Visualization: Time series.
```promql
sum(rate(dnstt_bytes_in_total{domain="$domain"}[$__rate_interval]))
```
- Title: Outbound DNS traffic rate
- Description: Bytes per second sent in DNSTT DNS responses.
- Visualization: Time series.
```promql
sum(rate(dnstt_bytes_out_total{domain="$domain"}[$__rate_interval]))
```
- Title: DNS traffic rate by country
- Description: Combined inbound and outbound DNSTT DNS bytes per second grouped
by resolver country.
- Visualization: Geomap, stacked time series, or bar chart.
```promql
sum by (country) (
rate(dnstt_bytes_in_total{domain="$domain"}[$__rate_interval])
+
rate(dnstt_bytes_out_total{domain="$domain"}[$__rate_interval])
)
```
- Title: Total observed sessions
- Description: Total unique DNSTT sessions observed since the exporter started.
- Visualization: Stat.
```promql
sum(dnstt_sessions_total{domain="$domain"})
```
- Title: New session rate
- Description: New DNSTT sessions observed per second.
- Visualization: Time series.
```promql
sum(rate(dnstt_sessions_total{domain="$domain"}[$__rate_interval]))
```
- Title: New session rate by country
- Description: New DNSTT sessions per second grouped by resolver country.
- Visualization: Stacked time series, geomap, or bar chart.
```promql
sum by (country) (rate(dnstt_sessions_total{domain="$domain"}[$__rate_interval]))
```
2026-05-05 13:43:02 +02:00
## Development
```sh
go test ./...
go build ./cmd/dnstt_exporter
```