lost and found ( for me ? )

BIND : view queries logs with bindgraph

Here’s how to install bindgraph to monitor queries log with GUI ( RRD graph ).
root@ubuntu1204-vm1:~# tail -1 /etc/lsb-release
DISTRIB_DESCRIPTION="Ubuntu 12.04.2 LTS"
root@ubuntu1204-vm1:~# uname -ri
3.2.0-44-generic x86_64

install bind9 and bindgraph via apt-get
root@ubuntu1204-vm1:~# apt-get install bind9 bindgraph



root@ubuntu1204-vm1:~# bindgraph.pl --version
bindgraph 0.2 by {dela,md}@linux.it
root@ubuntu1204-vm1:~# named -version
BIND 9.8.1-P1

[ bindgraph ]

bindgraph configuration file.
I used default config.
root@ubuntu1204-vm1:~# less /etc/default/bindgraph
DNS_LOG=/var/log/bind9-query.log
LOG_FORMAT=bind93

[ bind ]

enable queries log
root@ubuntu1204-vm1:~# cat /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
version none;
auth-nxdomain no;    # conform to RFC1035
# listen-on-v6 { any; };
listen-on-v6 { none; };
recursion yes;
};

# enable queries log for bindgraph
logging {
       channel "log_queries" {
               file "/var/log/bind9-query.log";
               severity info;
               print-time yes;
               print-category yes;
       };

       category queries { "log_queries"; };
};

create a query log file and change file owner
root@ubuntu1204-vm1:~# touch /var/log/bind9-query.log
root@ubuntu1204-vm1:~# chown bind:bind /var/log/bind9-query.log

restart bind9
root@ubuntu1204-vm1:~# service bind9 restart

confirm if query logging is enabled.
root@ubuntu1204-vm1:~# rndc status
version: 9.8.1-P1 (version.bind/txt/ch disabled)
CPUs found: 2
worker threads: 2
number of zones: 18
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is ON
recursive clients: 0/0/1000
tcp clients: 0/100
server is up and running

[ apache ]

install apache to view DNS queries graph via web browser
root@ubuntu1204-vm1:~# apt-get install apache2

cgi for bindgraph has been installed under /usr/lib/cgi-bin/
root@ubuntu1204-vm1:~# dpkg -L bindgraph | grep -i cgi
/usr/lib/cgi-bin
/usr/lib/cgi-bin/bindgraph.cgi

I used default httpd configuration.
# cat /etc/apache2/sites-available/default
<VirtualHost *:80>
ServerAdmin webmaster@localhost

DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog ${APACHE_LOG_DIR}/access.log combined

   Alias /doc/ "/usr/share/doc/"
   <Directory "/usr/share/doc/">
       Options Indexes MultiViews FollowSymLinks
       AllowOverride None
       Order deny,allow
       Deny from all
       Allow from 127.0.0.0/255.0.0.0 ::1/128
   </Directory>

</VirtualHost>
root@ubuntu1204-vm1:~#

start bindgraph and httpd
# service bindgraph restart
# service apache2 restart

start an web browser and access to http:// your BIND server IP/cgi-bin/bindgraph.cgi
If you can’t see the graph , please type the following command and then access to your BIND.
This might help you diagnose problems.. ( this is as-is based info … )
root@ubuntu1204-vm1:~# /usr/bin/perl -w /usr/sbin/bindgraph.pl -l /var/log/bind9-query.log --format=bind93 -d --daemon_rrd=/var/lib/bindgraph --rrd_name=bindgraph

root@ubuntu1204-vm1:~# ll -d /var/lib/bindgraph/*
-rw-r--r-- 1 root root 7106208  5月 31 02:48 /var/lib/bindgraph/bindgraph.rrd

build querytcp on fedora 18 64bit

querytcp is a tool which can send TCP queries instead of UDP queries.
Please note that querytcp sends only TCP queries. ( tcpquery does not support TCP fallback as of now.)

# cat /etc/fedora-release
Fedora release 18 (Spherical Cow)

# uname -ri
3.9.2-200.fc18.x86_64 x86_64

# gcc --version
gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)

[ build querytcp ]

build querytcp from git.
# git clone https://github.com/kfujiwara/querytcp.git
# cd querytcp/
# gcc -D_LINUX -Wall -O2 -g -lm -o querytcp querytcp.c

# ./querytcp --help
./querytcp: invalid option -- '-'
querytcp [-d datafile] [-s server_addr] [-p port] [-q num_queries] [-t timeout] [l limit] [-4] [-6] [-h]
 -d specifies the input data file (default: stdin)
 -s sets the server to query (default: 127.0.0.1)
 -p sets the port on which to query the server (default: 53)
 -q specifies the maximum number of queries outstanding (default: 120)
 -t specifies the timeout for query completion in seconds (default: 10)
 -l specifies how a limit for how long to run tests in seconds (no default)
 -e enable EDNS0
 -D set DO bit
 -r set RD bit



 -c print the number of packets with each rcode
 -v verbose: report the RCODE of each response on stdout
 -h print this usage

or

knot DNS source code includes querytcp.
so you can build tcpquery from knot DNS source code as well.
get knot DNS from https://www.knot-dns.cz/.
# tar xzvf knot-1.2.0.tar.gz
# cd knot-1.2.0/tests/
# gcc -D_LINUX -Wall -O2 -g -lm -o querytcp querytcp.c

# ./querytcp -h
dnsheader size: 12
querytcp [-d datafile] [-s server_addr] [-p port] [-q num_queries] [-t timeout] [l limit] [-4] [-6] [-h]
 -d specifies the input data file (default: stdin)
 -s sets the server to query (default: 127.0.0.1)
 -p sets the port on which to query the server (default: 53)
 -q specifies the maximum number of queries outstanding (default: 120)
 -t specifies the timeout for query completion in seconds (default: 10)
 -l specifies how a limit for how long to run tests in seconds (no default)
 -e enable EDNS0
 -D set DO bit
 -r set RD bit



 -c print the number of packets with each rcode
 -v verbose: report the RCODE of each response on stdout
 -h print this usage

In my environment ,I saw the following warning messges when compiling querytcp.
But it seems that querytcp  works well without problems as of now.

# gcc -Wall -O2 -g -lm -o querytcp querytcp.c
querytcp.c: In function ‘register_response’:
querytcp.c:231:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
querytcp.c:256:4: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘timediff_t’ [-Wformat]
querytcp.c: In function ‘output’:
querytcp.c:276:2: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘uint64_t’ [-Wformat]
querytcp.c:278:4: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘uint64_t’ [-Wformat]
querytcp.c:280:4: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘uint64_t’ [-Wformat]
querytcp.c:282:4: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘uint64_t’ [-Wformat]
querytcp.c:284:4: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘uint64_t’ [-Wformat]
querytcp.c:293:5: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘uint64_t’ [-Wformat]
querytcp.c: In function ‘send_query’:
querytcp.c:416:9: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
querytcp.c:421:4: warning: pointer targets in passing argument 1 of ‘fgets’ differ in signedness [-Wpointer-sign]
In file included from querytcp.c:28:0:
/usr/include/stdio.h:624:14: note: expected ‘char * __restrict__’ but argument is of type ‘u_char *’
querytcp.c:432:5: warning: pointer targets in passing argument 1 of ‘fgets’ differ in signedness [-Wpointer-sign]
In file included from querytcp.c:28:0:
/usr/include/stdio.h:624:14: note: expected ‘char * __restrict__’ but argument is of type ‘u_char *’
querytcp.c:437:3: warning: pointer targets in passing argument 1 of ‘strtok’ differ in signedness [-Wpointer-sign]
In file included from querytcp.c:30:0:
/usr/include/string.h:344:14: note: expected ‘char * __restrict__’ but argument is of type ‘u_char *’
querytcp.c:437:9: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
querytcp.c:438:5: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
querytcp.c:441:5: warning: pointer targets in passing argument 2 of ‘strcasecmp’ differ in signedness [-Wpointer-sign]
In file included from querytcp.c:30:0:
/usr/include/string.h:532:12: note: expected ‘const char *’ but argument is of type ‘u_char *’
querytcp.c:463:3: warning: pointer targets in passing argument 1 of ‘send_query_error’ differ in signedness [-Wpointer-sign]
querytcp.c:391:6: note: expected ‘char *’ but argument is of type ‘u_char *’
querytcp.c:486:5: warning: assignment from incompatible pointer type [enabled by default]
querytcp.c:495:3: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
querytcp.c: In function ‘tcp_receive’:
querytcp.c:591:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
querytcp.c:609:1: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
querytcp.c: In function ‘query’:
querytcp.c:625:9: warning: variable ‘n’ set but not used [-Wunused-but-set-variable]
#

[ usage ]

# ./querytcp -d query_list.txt -s 192.168.11.160
dnsheader size: 12
resolving: 192.168.11.160:53
elapsed time: 25.453
tcp qps: 653.638
sent: 18039
answer: 16637  92.2%
error: 1402  7.8%
zeroread: 0  0.0%
timeout: 0  0.0%
response size:        45/45.000/45/0.000 bytes



# head -1 query_list.txt
www.foo.bar a

# wc -l query_list.txt
10396 query_list.txt

here is a capture data which was collected on the DNS server.
querytcp : 192.168.11.100
DNS server : 192.168.11.160
# tshark -r zzz.pcap -R '(tcp.port==54243)'
 1   0.000000 192.168.11.100 -> 192.168.11.160 TCP 74 54243 > domain [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=30311093 TSecr=0 WS=128
 2   0.000062 192.168.11.160 -> 192.168.11.100 TCP 74 domain > 54243 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=93063 TSecr=30311093 WS=8
25   0.000461 192.168.11.100 -> 192.168.11.160 TCP 66 54243 > domain [ACK] Seq=1 Ack=1 Win=14720 Len=0 TSval=30311094 TSecr=93063
57   0.003279 192.168.11.100 -> 192.168.11.160 DNS 97 Standard query A www.foo.bar
58   0.003292 192.168.11.160 -> 192.168.11.100 TCP 66 domain > 54243 [ACK] Seq=1 Ack=32 Win=14480 Len=0 TSval=93064 TSecr=30311097
137   0.004579 192.168.11.160 -> 192.168.11.100 DNS 113 Standard query response A 127.0.1.1
142   0.004880 192.168.11.100 -> 192.168.11.160 TCP 66 54243 > domain [ACK] Seq=32 Ack=48 Win=14720 Len=0 TSval=30311098 TSecr=93064
148   0.005084 192.168.11.100 -> 192.168.11.160 TCP 66 54243 > domain [FIN, ACK] Seq=32 Ack=48 Win=14720 Len=0 TSval=30311099 TSecr=93064
174   0.005686 192.168.11.160 -> 192.168.11.100 TCP 66 domain > 54243 [FIN, ACK] Seq=48 Ack=33 Win=14480 Len=0 TSval=93064 TSecr=30311099
221   0.007259 192.168.11.100 -> 192.168.11.160 TCP 66 54243 > domain [ACK] Seq=33 Ack=49 Win=14720 Len=0 TSval=30311100 TSecr=93064

on the DNS server
# lsof -ni:53
COMMAND PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
unbound 885 unbound    3u  IPv4   7856      0t0  UDP *:domain
unbound 885 unbound    4u  IPv4   7857      0t0  TCP *:domain (LISTEN)
unbound 885 unbound   12u  IPv4  67523      0t0  TCP 192.168.11.160:domain->192.168.11.100:52975 (ESTABLISHED)
unbound 885 unbound   13u  IPv4  67524      0t0  TCP 192.168.11.160:domain->192.168.11.100:52976 (ESTABLISHED)
unbound 885 unbound   14u  IPv4  67525      0t0  TCP 192.168.11.160:domain->192.168.11.100:52977 (ESTABLISHED)
unbound 885 unbound   15u  IPv4  67526      0t0  TCP 192.168.11.160:domain->192.168.11.100:52978 (ESTABLISHED)
unbound 885 unbound   16u  IPv4  67527      0t0  TCP 192.168.11.160:domain->192.168.11.100:52979 (ESTABLISHED)
unbound 885 unbound   18u  IPv4  67492      0t0  TCP 192.168.11.160:domain->192.168.11.100:52905 (ESTABLISHED)
unbound 885 unbound   19u  IPv4  67493      0t0  TCP 192.168.11.160:domain->192.168.11.100:51684 (ESTABLISHED)
unbound 885 unbound   20u  IPv4  67494      0t0  TCP 192.168.11.160:domain->192.168.11.100:51735 (ESTABLISHED)
unbound 885 unbound   21u  IPv4  67495      0t0  TCP 192.168.11.160:domain->192.168.11.100:51641 (ESTABLISHED)

while sending TCP queries , I saw the following message on the DNS server.
localhost kernel: [  672.255114] TCP: Possible SYN flooding on port 53. Sending cookies.  Check SNMP counters.

disable SYN cookie
# cat /proc/sys/net/ipv4/tcp_syncookies
1
# echo 0 >  /proc/sys/net/ipv4/tcp_syncookies

# cat /proc/sys/net/ipv4/tcp_syncookies
0