給阿骁兄的賀禮二: DNS 流量統計~超強版

红薯 发布于 2009/05/06 10:37
阅读 600
收藏 0

其實也稱不上超強版,不過一般人可能較不會往這邊想而以... :mrgreen: 
透過修改 bind 的 source code, 利用 rndc 從遠端直接抓出
dns 的query/response 次數,再利用 mrtg 或 rrdtool 來繪圖而以
(註:rndc 不懂的人自己去看,非本處主題)
這是我做的 bind-9.3.0 的 patch file, 有興趣的可拿去看看,如果懂程式
的話,你就會知道不同的版本如何改,如果不懂的話,你就將就用囉!

diff -cr bind-9.3.0/bin/named/query.c bind-9.3.0_abel/bin/named/query.c


*** bind-9.3.0/bin/named/query.c Wed Jun 30 22:13:05 2004
--- bind-9.3.0_abel/bin/named/query.c Wed Oct 13 00:45:07 2004
***************
*** 95,100 ****
--- 95,103 ----
  static void
  query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);
  
+ static int querycount=0;
+ static int replycount=0;

  /*
   * Increment query statistics counters.
   */
***************
*** 112,121 ****
--- 115,132 ----
  zonestats[counter]++;
  }
  }
+ int get_query_count(void) {
+ return(querycount);
+ }

+ int get_reply_count(void) {
+ return(replycount);
+ }
  
  static void
  query_send(ns_client_t *client) {
  dns_statscounter_t counter;
+ replycount++;
  if (client->;message->;rcode == dns_rcode_noerror) {
  if (ISC_LIST_EMPTY(client->;message->;sections[DNS_SECTION_ANSWER])) {
  if (client->;query.isreferral) {
***************
*** 3447,3453 ****
  query_error(client, result);
  return;
  }

  if (ns_g_server->;log_queries)
  log_query(client);
  
--- 3458,3464 ----
  query_error(client, result);
  return;
  }
! querycount++;
  if (ns_g_server->;log_queries)
  log_query(client);
  
diff -cr bind-9.3.0/bin/named/server.c bind-9.3.0_abel/bin/named/server.c
*** bind-9.3.0/bin/named/server.c Fri Jun 18 12:39:48 2004
--- bind-9.3.0_abel/bin/named/server.c Wed Oct 13 00:47:47 2004
***************
*** 3998,4003 ****
--- 3998,4005 ----
  n = snprintf((char *)isc_buffer_used(text),
       isc_buffer_availablelength(text),
       "number of zones: %u\n"
+      "number of query: %u\n"
+      "number of reply: %u\n"
       "debug level: %d\n"
       "xfers running: %u\n"
       "xfers deferred: %u\n"
***************
*** 4006,4012 ****
       "recursive clients: %d/%d\n"
       "tcp clients: %d/%d\n"
       "server is up and running",
!      zonecount, ns_g_debuglevel, xferrunning, xferdeferred,
       soaqueries, server->;log_queries ? "ON" : "OFF",
       server->;recursionquota.used, server->;recursionquota.max,
       server->;tcpquota.used, server->;tcpquota.max);
--- 4008,4014 ----
       "recursive clients: %d/%d\n"
       "tcp clients: %d/%d\n"
       "server is up and running",
!      zonecount, get_query_count(), get_reply_count(),ns_g_debuglevel, xferrunning, xferdeferred,
       soaqueries, server->;log_queries ? "ON" : "OFF",
       server->;recursionquota.used, server->;recursionquota.max,
       server->;tcpquota.used, server->;tcpquota.max);

註:Patch 動作請自己做, patch -p1 < this_patch_file,本檔僅適合 9.3.0,沒空每版都寫出來
以上的程式僅是在做 rdnc -s IP_addr status 時,可以帶出如下內容:
[root@log SIP]# rndc -s 211.72.210.251 status
number of zones: 1


number of query: 157
number of reply: 153
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is ON
recursive clients: 0/1000
tcp clients: 0/100
server is up and running

看到沒有,跟你的有什麼不同, 多了 
number of query: 157
number of reply: 153

兩欄,也就是我們加上去的,好了,你每一台機器都做了這樣的 patch 後
並做相同的 rndc.conf 的設定,就可以利用 rndc -s Server_IP status 取
得這樣的結果了,我們可以驗證看看數字到底對不對:




#rndc -s Server_IP stats
# cat /var/named/named.stats
success 137
referral 0
nxrrset 6
nxdomain 10
recursion 142
failure 4

上面數字 success+nxrrset+nxdomain+failure=157 表示 dns 收到了
157 查詢,其中有 142 次做 recursion

不計算 failure 即為成功的查詢次數, 所以為 153

故程式的結果沒有問題 !!
我再寫一個小程式來做字串處理:



#!/usr/bin/perl
open(II,"/usr/local/sbin/rndc -s $ARGV[0] status|");
while ( ;) {
  chomp;
  split(/: /,$_);
  print "$_[1]\n" if ($_[0] eq 'number of query' or $_[0] eq 'number of reply');
}
close(II);

Ex:filename 為 dns_flow.pl
./dns_flow.pl Server_IP
輸出結果為:
157


153


是不是變簡單了呢 !?
你若跑十台 DNS 服務,想來很多人會用 query log 來記 Query 量
這是最不好的方式,因為 Disk I/O 會很多
若你用 rndc stats 來做分折,是可以的,但資料滙整將是一個問題

改程式是終南捷徑(要會改就不是捷徑了)...
每部 DNS Server 再配置相同的 rndc.conf ,即可使用此一 rule
(不同也行,但就會變復雜了,相同的 rndc.conf 只要將一些 rndc
的設定copy 到別台機器即可)

利用 mrtg 來輸出結果:



#  for UNIX
WorkDir: /www/html/mrtg
#  or for NT
# WorkDir: c:\mrtgdata

### Global Defaults

#  to get bits instead of bytes and graphs growing to the right
Options[_]: growright, noinfo



#---------------------------------------------------------------

Target[DNS_Server1]: `/home/abel/dns.pl 你的DNS_Server_IP`
MaxBytes[DNS_Server1]: 2500
Title[DNS_Server1]: A.DNS.TW (IPv6)
Legend1[DNS_Server1]: DNS查詢(次數/秒)
Legend2[DNS_Server1]: DNS回應(次數/秒)
LegendI[DNS_Server1]: DNS查詢
LegendO[DNS_Server1]: DNS回應
YLegend[DNS_Server1]: Q. per second
PageTop[DNS_Server1]: 

;DNS_Server Query/Response

;

crontab 那些及 mrtg 設定細節就不再贅述

mrtg 結果:
http://211.72.210.251/dns/


這次我就不寫 rrdtool 版本了,免得大家望文生畏,我也偷懶一下 :em03:
給阿骁兄的賀禮基本上 google 都是沒有或不足的,有興趣的人可好好研究
一下 :em06:

註: 我直接提供一個修改過的9.3.0版本給大家試試 
http://211.72.210.251/bind-9.3.0.tar.gz
若不放心,請記得到 ftp://ftp.isc.org 下也抓一個 9.3.0
來做比較(diff -cr isc_dir abel_dir), 即可知我改了什麼



加载中
返回顶部
顶部