ORACLE:使用tcpdump 監控客戶端發過來的所有SQL語句

gxlineji發表於2016-08-25
思路: 
 第一步:捉取1521埠的接收到的資料包;
    直接捉取的命令如下: tcpdump -ttAvennSs 0 -i em1 src 10.50.xxx.xxx and dst port 1521
 第二步:使用python 解析資料包中的SQL語句,並儲存到檔案裡 
 第三步: 配置crontab 定期執行包含tcpdump 的shell,並定期使用tcp.py解析資料庫包



實現步驟與指令碼:
(1) 建立python 指令碼tcp.py,用於處理捉取到資料包,提取客戶端發過來的SQL。

點選(此處)摺疊或開啟

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. # tcpdump -ttAvennSs 0 -i em1 src 10.50.xxx.xxx and dst port 1521
  4. # 需要兩個輸入引數 :
  5. #    第一個引數 -- tcpdump 捉取到的SQL資料包檔案及路徑
  6. #    第二個引數 -- 存放SQL語句的檔名及路徑
  7. # 使用例項:python tcp.py /root/temp.data /root/sql.txt
  8. import sys

  9. def find_sql(p_str):
  10.     vstr = p_str.upper()
  11.     if vstr.find('SELECT ') > 0:
  12.         vsqltext = p_str[vstr.find('SELECT '):].strip().strip('.')
  13.     elif vstr.find('AUTH_') > 0 and vstr.find('AUTH_ALTER_SESSION') == -1 and vstr.find('AUTH_SESSKEY') == -1:
  14.         vsqltext = p_str[vstr.find('AUTH_')-20:].strip().strip('.')
  15.         #print vsqltext[0:vsqltext.find('.')].strip("'")
  16.     elif vstr.find('UPDATE ') > 0:
  17.         vsqltext = p_str[vstr.find('UPDATE '):].strip().strip('.')
  18.     elif vstr.find('DELETE ') > 0:
  19.         vsqltext = p_str[vstr.find('DELETE '):].strip().strip('.')
  20.     elif vstr.find('CREATE ') > 0:
  21.         vsqltext = p_str[vstr.find('CREATE '):].strip().strip('.')
  22.     elif vstr.find('ALTER ') > 0 and p_str.find('from Oracl1e Corporation. Copyright 2003 Oracle Corporation') == -1:
  23.         vsqltext = p_str[vstr.find('ALTER '):].strip().strip('.')
  24.     elif vstr.find('BEGIN') > 0:
  25.         vsqltext = p_str[vstr.find('BEGIN'):].strip().strip('.')
  26.     elif vstr.find('WITH ') > 0:
  27.         vsqltext = p_str[vstr.find('WITH '):].strip().strip('.')
  28.     elif vstr.find('DROP ') > 0:
  29.         vsqltext = p_str[vstr.find('DROP '):].strip().strip('.')
  30.     elif vstr.find('CALL ') > 0:
  31.         vsqltext = p_str[vstr.find('CALL '):].strip().strip('.')
  32.     else:
  33.         return '0'
  34.     return vsqltext

  35. if __name__ == '__main__':
  36.     strlist1 = []
  37.     strlist2 = []
  38.     str = ''
  39.     v_pkg_two = 0
  40.     filestr = sys.argv[1]
  41.     v_sqlfilestr = sys.argv[2]
  42.     #print sys.argv[1]
  43.     #print sys.argv[2]
  44.     if filestr == '':
  45.         print 'please input tcp data filename'
  46.         exit
  47.         if v_sqlfilestr == '':
  48.                 print 'please input filename that is use to save tcp sql!'
  49.                 exit
  50.         fow = open(v_sqlfilestr, 'a')
  51.     #開啟檔案
  52.     fo = open(filestr,'r')
  53.     for line in fo:
  54.         # 檔案行是否包含'ethertype IPv4',如果包含則為包的第一行
  55.         is_pkg_begin = line.find('ethertype IPv4')
  56.         # 判斷是否為包的第一行
  57.         if is_pkg_begin > 0:
  58.             # 列印包資訊,首次執行不列印
  59.             if len(strlist1) > 0:
  60.                 vmac_ip = strlist1[0] + ' ' + strlist1[1] +' ' + strlist2[0] + ' ' + strlist2[2][0:-1]
  61.                 vsql = find_sql(str)
  62.                 if vsql <> '0':
  63.                     fow.writelines('\n' + vmac_ip + '\n' + vsql)
  64.                     #print vsql
  65.                     #break
  66.             str = ''
  67.             # next
  68.             strlist1 = line.split(' ')
  69.             #將要讀取的檔案下一行為包的第二行
  70.             v_pkg_two = 1
  71.         #判斷是否為包的第二行
  72.         elif v_pkg_two == 1:
  73.             # 重置第二行識別符號
  74.             v_pkg_two = 0
  75.             #去掉左邊的空格
  76.             strlist2 = line.lstrip().split(' ')
  77.         else:
  78.             # 每個包可能有多行資料,需要組合起來
  79.             str = str + line
  80.     # 關閉開啟的檔案
  81.     fo.close
  82.     fow.close( )

(2)捉取1521埠接收到的資料庫,並呼叫tcp.py 提取資料包中的SQL語句。
shell指令碼名稱 tcp1521.sh ,程式碼如下:

點選(此處)摺疊或開啟

  1. #!/bin/bash
  2. # tcpdump -ttAvennSs 0 -i bond0 dst port 1521 > /dev/shm/tcpdata/tcpdata1521.data
  3. vdate=`date +%Y%m%d`
  4. vsqlfile=/home/oracle/script/tcpdumpsql/tcp_sql_${vdate}.txt
  5. vpythonscript=/home/oracle/script/tcpdumpsql/tcp.py
  6. #獲取日期
  7. vdatetime=`date +%Y%m%d%H%M%S`
  8. #捉取到的資料包的存放目錄,定期從srcfile遷移到dstfile
  9. vfilepath='/dev/shm/tcpdata/data'
  10. vfilepath1='/dev/shm/tcpdata'
  11. dstfile=${vfilepath}/tcp${vdatetime}
  12. srcfile=${vfilepath1}/tcp1521.data
  13. cd /dev/shm
  14. mkdir -p $vfilepath
  15. if [ ! -d $vfilepath ]; then
  16. echo "$vfilepath not a path"
  17. exit
  18. fi
  19. #if [ ! -f $srcfile ]; then
  20. # echo "$srcfile not exists"
  21. # exit
  22. #fi
  23. # 從srcfile遷移到dstfile
  24. mv ${srcfile} ${dstfile}
  25. # 結束tcpdump 程式(如果不結束,沒辦法遷移檔案)
  26. killall tcpdump
  27. # 開啟新的tcpdump 程式
  28. tcpdump -ttAvennSs 0 -i em1 dst port 1521 > ${srcfile} &
  29. # 查詢捉取到的資料包檔案,並遍歷使用tcp.py 解析資料包
  30. filelist=`ls $vfilepath|sort -k9`
  31. for file in $filelist
  32. do
  33. echo $vfilepath/$
  34. # 呼叫tcp.py 解析資料包,存放到$vsqlfile檔案裡
  35. /usr/bin/python $vpythonscript $vfilepath/$file $vsqlfile
  36. # 刪除已解析的資料包檔案
  37. rm -rf $vfilepath/$file
  38. done

(3) 配置crontab,定期執行tcp521.sh 
必須要定期執行,否則資料包檔案會過大,容易撐爆磁碟空間。
#tcpdump sql
00  */2  *  *  *  root  /home/oracle/script/tcpdumpsql/tcp1521.sh  >/dev/null 2>&1



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10995764/viewspace-2124028/,如需轉載,請註明出處,否則將追究法律責任。

相關文章