ITPub博客

首页 > 数据库 > Oracle > ORACLE:使用tcpdump 监控客户端发过来的所有SQL语句

ORACLE:使用tcpdump 监控客户端发过来的所有SQL语句

原创 Oracle 作者:gxlineji 时间:2016-08-25 14:59:02 0 删除 编辑
思路: 
 第一步:捉取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博客 ” ,链接:https://blog.itpub.net/10995764/viewspace-2124028/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-09-11

  • 博文量
    48
  • 访问量
    76657