A Prometheus exporter that captures information from the BIND queries log file. It is based on the node_exporter and cf_exporter projects.
By default, this exporter's Stats collector doesn't do anything special that you can't get with the much better bind_exporter query stats. However, enabling the Names
collector with --filter.collectors="Names"
makes DNS query hits per name available (see the warning in the Names collector documentation below). This can be useful for a few use cases:
- Using the
--names.include.file
to see if a list of DNS names you would like to decommission are still receiving queries - Using the
--names.include.file
to identify if clients on your network are reaching out to forbidden domain names - Using the
--names.exclude.file
to see if your authoritative DNS server is receiving queries for domain names you don't own
Depending on the use case, enabling --names.capture-client
and --names.reverse-lookup
may be helpful.
Note that BIND does not log queries by default, so logging must be turned on before this collector will do much. On Debian-based systems, placing the following contents in /etc/bind/named.conf.logging
will enable logging:
logging {
channel bind_log {
file "/var/log/bind/bind.log";
severity info;
print-category yes;
print-severity yes;
print-time yes;
};
channel query_log {
file "/var/log/bind/queries.log";
severity info;
print-category yes;
print-severity yes;
print-time yes;
};
category default { bind_log; };
category update { bind_log; };
category update-security { bind_log; };
category security { bind_log; };
category queries { query_log; };
category lame-servers { null; };
};
It is strongly suggested to enable rotation of the log file. On Debian-based systems, you can do this by creating the file /etc/logrotate.d/bind
with these contents:
/var/log/bind/bind.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 644 bind bind
}
/var/log/bind/queries.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 644 bind bind
postrotate
/usr/sbin/invoke-rc.d bind9 reload > /dev/null
endscript
}
Download the already existing binaries for your platform:
$ ./bind_query_exporter <flags>
Using the standard go install
(you must have Go already installed in your local machine):
$ go install github.com/DRuggeri/bind_query_exporter
$ bind_query_exporter <flags>
docker build -t bind_query_exporter .
docker run -d -p 9197:9197 -v /var/log/bind:/var/log/bind:ro bind_query_exporter"
usage: bind_query_exporter [<flags>]
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--log="/var/log/bind/queries.log"
Path of the BIND query log to watch. Defaults to '/var/log/bind/queries.log' ($BIND_QUERY_EXPORTER_LOG)
--pattern="client(?: @0x[0-9a-f]+)? ([^\\s#]+).*query: ([^\\s]+)"
The regular expression pattern with two capturing matches for the client IP and the queried name ($BIND_QUERY_EXPORTER_PATTERN)
--names.include.file="" Path to a file of DNS names that this exporter WILL export when the Names filter is enabled. One DNS name per line will be read. ($BIND_QUERY_EXPORTER_NAMES_INCLUDE_FILE)
--names.exclude.file="" Path to a file of DNS names that this exporter WILL NOT export when the Names filter is enabled. One DNS name per line will be read. ($BIND_QUERY_EXPORTER_NAMES_EXCLUDE_FILE)
--names.capture-client Enable capturing the client making the query as part of the vector. WARNING: This will can lead to lots of metrics in your Prometheus database! ($BIND_QUERY_EXPORTER_NAMES_CAPTURE_CLIENT)
--names.reverse-lookup When names.capture-client is enabled, enable a reverse DNS lookup to identify the client in the vector instead of the IP. ($BIND_QUERY_EXPORTER_NAMES_REVERSE_LOOKUP)
--filter.collectors="Stats"
Comma separated collectors to enable (Stats,Names) ($BIND_QUERY_EXPORTER_FILTER_COLLECTORS)
--metrics.namespace="bind_query"
Metrics Namespace ($BIND_QUERY_EXPORTER_METRICS_NAMESPACE)
--web.listen-address=":9197"
Address to listen on for web interface and telemetry ($BIND_QUERY_EXPORTER_WEB_LISTEN_ADDRESS)
--web.telemetry-path="/metrics"
Path under which to expose Prometheus metrics ($BIND_QUERY_EXPORTER_WEB_TELEMETRY_PATH)
--web.auth.username=WEB.AUTH.USERNAME
Username for web interface basic auth. Password is set via $BIND_QUERY_EXPORTER_WEB_AUTH_PASSWORD env variable ($BIND_QUERY_EXPORTER_WEB_AUTH_USERNAME)
--web.tls.cert_file=WEB.TLS.CERT_FILE
Path to a file that contains the TLS certificate (PEM format). If the certificate is signed by a certificate authority, the file should be the concatenation of the server's certificate, any intermediates,
and the CA's certificate ($BIND_QUERY_EXPORTER_WEB_TLS_CERTFILE)
--web.tls.key_file=WEB.TLS.KEY_FILE
Path to a file that contains the TLS private key (PEM format) ($BIND_QUERY_EXPORTER_WEB_TLS_KEYFILE)
--printMetrics Print the metrics this exporter exposes and exits. Default: false ($BIND_QUERY_EXPORTER_PRINT_METRICS)
--log.level="info" Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]
--log.format="logger:stderr"
Set the log target and format. Example: "logger:syslog?appname=bob&local=7" or "logger:stdout?json=true"
--version Show application version.
This collector counts the number of DNS queries the DNS server receives by type.
bind_query_stats_total - Total queries recieved
bind_query_stats_total_by_type - Total queries recieved by type of query
bind_query_stats_scrapes_total - Total number of scrapes for BIND query stats.
bind_query_stats_scrape_errors_total - Total number of scrapes errors for BIND query stats.
bind_query_stats_last_scrape_error - Whether the last scrape of BIND query stats resulted in an error (1 for error, 0 for success).
bind_query_stats_last_scrape_timestamp - Number of seconds since 1970 since last scrape of BIND qyery stat metrics.
This collector counts unique hits to individual DNS names by setting the metric bind_query_names_all{name="site.foo.bar.com",...} 123
. If the --names.capture-clients
flag is set, the vector will also include the address of the client (or reverse lookup with --names.reverse-lookup
).
IMPORTANT NOTE: Each DNS name detected will gets its own label in the bind_query_names_all
vector. Depending on the number of things matched, you may expose yourself to the cardinality problems mentioned here and here - especially if your nameserver is used as a recursive server or sees hits for many domains! Consider using the includeFile as a whitelist to limit what is gathered. Because of this, the Names collector is not enabled by default.
bind_query_names_all - Queries per DNS name
bind_query_names_total - Sum of all queries matched. If no include/exclude filter is present, this will match bind_query_stats_total in the stats collector. It is initialized to 0 to support increment() detection.
bind_query_names_scrapes_total - Total number of scrapes for BIND names stats.
bind_query_names_scrape_errors_total - Total number of scrapes errors for BIND names stats.
bind_query_names_last_scrape_error - Whether the last scrape of BIND names stats resulted in an error (1 for error, 0 for success).
bind_query_names_last_scrape_timestamp - Number of seconds since 1970 since last scrape of BIND names metrics.
bind_query_names_last_scrape_duration_seconds - Duration of the last scrape of BIND names stats.
Refer to the contributing guidelines.
Apache License 2.0, see LICENSE.