2019独角兽企业重金招聘Python工程师标准>>>
需求描述:
请通过tcpdump命令进行抓包,抓192.168.0.100的IP的3022端口的所有包;
并要求每10分钟开启一个新的抓包进程,新进程开启后,再关闭原有进程(目的是防止抓包信息量过大不容易分析);
同时对/jboss/server/default/log目录下的xxx.log日志进行监控,当日志中出现“Connection connected to :192.168.0.100:3022”后停止抓包,最后只需保留最后一个抓包文件,删除多余的方便分析。
实现思路:
1)编写collect_data脚本,使用正确的tcpdump命令按照要求抓包
/usr/sbin/tcpdump -i eth0 -n dst host 192.168.0.100 and dst port 3022 -vv -w file
说明:-w file 指把tcpdump的内容保存到一个二进制文件中,该文件使用 tcpdump -r file 来读取,每次执行这个命令都会重写file文件相当于>符号。
2)每10分钟开启一个新抓包进程目的是为了防止抓包信息持续写进一个文件中,导致文件过大不容易分析,所以shell程序必须能够进行新旧抓包命令的更替(每次更替分别将输出重定向到不同的文件日志中防止文件过大)。每10分钟进行一次,可以利用cron来定时,定时执行collect_data脚本,脚本中每次执行都完成开启新tcpdump进程,确保新tcpdump进程开启后再kill掉之前的进程的动作就可以了。而实现这一点,需要每次执行后记录本次执行的pid,下一次执行新的进程时再记录新的pid然后kill掉上次的pid,这样就满足了需求。
3)单独编写一个shell程序,用来实时的监视xxx.log日志,当日志中出现关键字后就kill掉tcpdump进程,保留本次tcpdump的输出的日志,删除上一次tcpdump进程的输出的日志,最后处理cron定时,不再执行定时否则会冲掉分析记录。
# vi collect_data 用来做tcpdump新旧进程交替的动作
#!/bin/sh #author:shenxiaoran #date:2013-3-12 prog_home=/home/shenxiaoran prog=/usr/sbin/tcpdump test -f $prog_home/flag || touch $prog_home/flag cat $prog_home/flag if [ $(cat $prog_home/flag) -eq 0 ];then $prog -i eth0 -n -nn dst host 192.168.0.100 and dst port 3022 -vv -w $prog_home/a.log & 2>/dev/null echo $! > $prog_home/tcpdump.0.run if [ $? -eq 0 ];then # ps -ef|grep tcpdump|grep -v root|awk '{print $2}'|head -1 > $prog_home/tcpdump.0.run # echo "ps : `ps -ef|grep tcpdump|grep -v root|awk '{print $2}'|head -1`" # echo "tcpdump.0.run: `cat $prog_home/tcpdump.0.run`" sleep 1 test -e $prog_home/tcpdump.1.run && cat $prog_home/tcpdump.1.run|xargs kill -9 > /dev/null fi echo 1 > $prog_home/flag exit fi if [ $(cat $prog_home/flag) -eq 1 ];then $prog -i eth0 -n -nn dst host 192.168.0.100 and dst port 3022 -vv -w $prog_home/b.log & 2>/dev/null echo $! > $prog_home/tcpdump.1.run if [ $? -eq 0 ];then # ps -ef|grep tcpdump|grep -v root|awk '{print $2}'|head -1 > $prog_home/tcpdump.1.run # echo "ps : `ps -ef|grep tcpdump|grep -v root|awk '{print $2}'|head -1`" # echo "tcpdump.1.run: `cat $prog_home/tcpdump.1.run`" sleep 1 test -e $prog_home/tcpdump.0.run && cat $prog_home/tcpdump.0.run|xargs kill -9 > /dev/null fi echo 0 > $prog_home/flag exit fi |
# vi monitor 用来实时监视xxx.log日志,一旦发现关键字出现立即执行相应动作(关键字是grep “”引号中的部分)
#!/bin/sh #author:shenxiaoran prog_home=/home/shenxiaoran log_file=/var/mqm/qmgrs/QM\!HL1/errors/xxx.log while : do tail $log_file |grep "Channel 'TO.QM.CENTER2' is starting" if [ $? -eq 0 ];then echo "Successful matches" current_tcpdump_pid=$(ps -ef|grep tcpdump|grep -v root|awk '{print $2}'|head -1) if [ -z "$current_tcpdump_pid" ];then echo "No any tcpdump process,$0 exit" break elif [ $current_tcpdump_pid -eq `cat $prog_home/tcpdump.0.run` ];then echo "kill prog" rm -f $prog_home/b.log cat $prog_home/tcpdump.0.run|xargs kill -9 > /dev/null sed -i -e 's/[0-9][0-9] [0-9][0-9] \* \* \* \/home\/shenxiaoran\/collect_data.*/#&/' /var/spool/cron/root /etc/init.d/crond reload elif [ $current_tcpdump_pid -eq `cat $prog_home/tcpdump.1.run` ];then echo "kill prog" rm -f $prog_home/a.log cat $prog_home/tcpdump.1.run|xargs kill -9 > /dev/null sed -i -e 's/[0-9][0-9] [0-9][0-9] \* \* \* \/home\/shenxiaoran\/collect_data.*/#&/' /var/spool/cron/root /etc/init.d/crond reload fi # pkill tcpdump > /dev/null break fi # sleep 60 done |
大功告成,这是本人运行过程中遇到的一个实际的需求案例,写在这里供大家参考。
注:使用tcpdump抓包然后放到windows桌面利用wireshark图形工具分析的时候,经常提示下图出现的错误,如何解决?
这个问题主要是由于tcpdump命令的参数使用不当造成的,注意使用-s 0 参数,保存文件时也不要用重定向而是使用-w file参数,保存的文件名最好直接使用xxx.pcap后缀,这样wireshark工具直接认识。
-s 0 : 抓取数据包时默认抓取长度为68字节。加上-s 0 后可以抓到完整的数据包。若存在双网卡的情况,需要明确制定包从哪个网卡进来,添加类似 -i eth1这样的参数,否则默认监听eth0网卡。
例如:tcpdump -nn -s 0 host 192.168.11.243 and port 80 -w wireshark.pcap