一个不能正确工作的脚本 monitor.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php $fp = popen("tcpdump -i eth1 'tcp[tcpflags] | tcp-syn == tcp-syn' -nn", "r"); while($line = fgets($fp)) { $arr = split(" ", $line, 8); $src = $arr[2]; $dst = $arr[4]; $dotpos = strrpos($src, "."); $src_host = substr($src, 0, $dotpos); $src_port = substr($src, $dotpos + 1); $dotpos = strrpos($dst, "."); $dst_host = substr($dst, 0, $dotpos); $dst_port = substr($dst, $dotpos + 1, strlen($dst) - $dotpos - 2 ); $src = $src_host .":". $src_port; $dst = $dst_host .":". $dst_port; //echo $src ."=>" .$dst. "\n"; $fp2 = popen("ss -antp|awk '{print $4 , $5 , $6}'", "r"); while(!feof($fp2)) { $line = trim(fgets($fp2)); $arr = explode(" ", $line); if ($src == $arr[0] && $dst == $arr[1]) { echo $line ."\n"; } } } |
不能正确工作的原因:
- 可能tcpdump没有立即输出抓到的数据包,当输出时连接已经断开许久了
- 就算tcpdump能足够快地输出抓到的数据包,执行ss的时候也可能已断开连接(这个至少不至于一个抓不到)
- 就算本地主动关闭连接的情况下,连接会一段时间内处于timewait状态,但是timewait状态是不关联pid的哦
验证猜想缓存问题导致的方法:
- 启动检测脚本: php monitor.php
- nc打开百度80端口连接,然后 ctrl+z
- while :; do curl http://baidu.com ;done
- 检测脚本输出结果部分如下:
解决办法:
正确的解决办法是使用systemtap: https://sourceware.org/systemtap/SystemTap_Beginners_Guide/useful-systemtap-scripts.html#nettop