214 lines
6.2 KiB
Markdown
214 lines
6.2 KiB
Markdown
# dnstt_exporter
|
|
|
|
Prometheus exporter for DNSTT client/session metrics.
|
|
|
|
`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 \
|
|
-geoip.country-database /path/to/GeoLite2-Country.mmdb \
|
|
-geoip.asn-database /path/to/GeoLite2-ASN.mmdb \
|
|
-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.
|
|
|
|
## 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.
|
|
|
|
## Metrics
|
|
|
|
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`.
|
|
|
|
- `dnstt_active_clients`
|
|
- `dnstt_peak_clients`
|
|
- `dnstt_queries_total`
|
|
- `dnstt_bytes_in_total`
|
|
- `dnstt_bytes_out_total`
|
|
- `dnstt_sessions_total`
|
|
|
|
## 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]))
|
|
```
|
|
|
|
## Development
|
|
|
|
```sh
|
|
go test ./...
|
|
go build ./cmd/dnstt_exporter
|
|
```
|