Мне нужно знать количество моих клиентов DNS-сервера. Вероятно, это означает уникальные IP-адреса за день или что-то в этом роде, потому что я думаю, что нет другого способа идентифицировать клиентов другим способом. Итак, мне нужно знать, сколько клиентов обслуживает мой bind9. Как я могу добиться этого самым простым способом?
1 - ведение журнала запросов
Включить ведение журнала запросов rndc querylog
и проанализируйте ваши файлы журналов, например:
grep -Eo "client ([0-9]{1,3}[\.]){3}[0-9]{1,3}" /path/to/logfile | sort -u | uniq
client 10.0.252.1
client 10.0.231.15
client 127.0.0.1
исключая дубликаты | uniq
и | wc -l
посчитать их, но не прочь найти реальное решение, которое будет действительно точным и простым.
2 - dnstop
Захват трафика:
tcpdump -w dump.pcap -c 10000 port 53
Разбери это:
dnstop dump.pcap > report.txt
Вот выходной формат (Только топ 50 клиенты):
% cat report.txt
Sources Count % cum%
------------ --------- ------ ------
10.0.252.1 36 87.8 87.8
10.0.250.100 3 7.3 95.1
10.0.231.15 2 4.9 100.0
[...]
3 - днстап
А также есть dnstap
но я мало что знаю об этом, за исключением того, что это запланированная функция BIND 9.11: https://la51.icann.org/en/schedule/mon-tech/presentation-isc-bind-13oct14-en.pdf.
Редактировать: Команда не перечисляла все IP-адреса, я исправил это, добавив sort -u
.
Примечание: uniq не обнаруживает повторяющиеся строки, если они не являются смежными.
По сути, самый простой способ получить эту информацию - из tcpdump
. Я сам недавно делал нечто подобное, но искал другие шаблоны. Возможно, вы найдете то, что я сделал, для вас.
http://distracted-it.blogspot.co.nz/search/label/dns http://distracted-it.blogspot.co.nz/2014/07/capturing-and-analysing-dns-samples.html
В частности, как описано в разделе «Сбор и анализ образцов DNS (tcpdump соответствует SQLite3)», и помещение его в базу данных sqlite3 полезно, если вы хотите позже задать дополнительные вопросы, но не полезно для мониторинга в реальном времени. Код для этого можно найти на https://github.com/cameronkerrnz/scriptorium/blob/master/dns-query-sample
Снимок кода:
#!/bin/bash
sample_size="50000"
interface="eth0"
echo "Capturing sample of $sample_size packets from interface $interface"
tcpdump -w /tmp/query-sample.pcap -i "$interface" -nn -p -c "$sample_size" -s0 dst port domain
rm -f /tmp/query-sample.sqlite3
sqlite3 /tmp/query-sample.sqlite3 'create table queries (count int,client,querytype,queryval);'
tcpdump -r /tmp/query-sample.pcap -nn \
| sed -rne 's/^[^ ]+ IP ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+ > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+: .* ([^?]+)\? ([A-Za-z0-9._-]+) .*/\1 \3 \4/p' \
| awk '
{ queryval = $3 }
queryval ~ /\.noisy-example\.com\.$/ { queryval = "SOMETHING.noisy-example.com." }
queryval ~ /\.10\.in-addr\.arpa\.$/ { queryval = "SOMETHING.10.in-addr.arpa." }
queryval ~ /\.67\.45\.123\.in-addr\.arpa\.$/ { queryval = "SOMETHING.67.45.123.in-addr.arpa." }
queryval ~ /[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\.in-addr\.arpa\.$/ { queryval = "SOMETHING.in-addr.arpa." }
{ print $1,$2,queryval }' \
| sort | uniq -c \
| sed -re 's/[ \t]+/|/g' -e 's/^\|//' \
| sqlite3 /tmp/query-sample.sqlite3 '.import /dev/stdin queries'
echo "
In this report, Cost is a count of such queries received,
normalised by the number of clients that queried it. Thus,
something with a Cost greater than 10 (<= are omitted),
would likely benefit from DNS caching.
Some queries, namely inverse lookups and things under
noisy-domain.com (generally some abuse of DNS) are
aggregated.
"
sqlite3 /tmp/query-sample.sqlite3 <<EOF
.mode column
.header on
.width 4 7 70
select sum(count)/count(count) as Cost, querytype as RRtype, queryval as Name from queries group by RRtype,Name having Cost > 10 order by Cost desc limit 100;
.width 9 6 15
select sum(count) as NumQueries, querytype as RRtype, client as Client from queries group by Client having NumQueries > 10 order by NumQueries desc limit 100;
EOF
tcpdump -tt -r /tmp/query-sample.pcap -nn \
| grep '\.53: ' \
| cut -d. -f1 | uniq -c \
| awk '
NR == 1 {starttime = $2; next}
{total += $1; count += 1; last = $1; lasttime = $2}
END { total -= last; print "Queries / second = " total / (lasttime - starttime) }'
Для мониторинга в реальном времени вы можете использовать tcpdump, а затем обработать его с помощью такого решения, как sed и AWK, Python, Perl и т. Д. Недавно я использовал sed и AWK, чтобы помочь мне найти, кто отправляет наибольшее количество запросов. в секунду, который я затем суммирую с другим, чтобы найти наиболее частые лидеры. Вы должны иметь возможность повторно использовать по крайней мере первую часть (которую я только что заметил, мне нужно загрузить).
Наконец, вы захотите убедиться, что в своих отчетах вы не злоупотребляете собственным DNS-сервером, слишком часто вызывая dig. Вместо этого используйте getent hosts.
Пример:
$ echo -e '1.1.1.1 2\n8.8.8.8 12\n8.8.4.4 25' \
| awk '
BEGIN {threshold = 5}
$2 > threshold {
"getent hosts " $1 | getline getent_hosts_str;
split(getent_hosts_str, getent_hosts_arr, " ");
print $1, getent_hosts_arr[2], $3
}'
8.8.8.8 google-public-dns-a.google.com
8.8.4.4 google-public-dns-b.google.com
Если вы ищете постоянное решение, над которым у вас может быть панель управления, вы можете использовать tcpdump и Python для посекундной генерации сводного отчета для каждого клиента (чтобы сократить данные) через JSON и подтолкнуть его к ELK. стек. В Kibana 4 вы можете получить диаграмму уникального счетчика атрибута (например, clientip.raw)
Надеюсь, что это даст вам много полезных идей.
Ура, Кэмерон