python如何实时获取tcpdump输出
作者:文渊 发布时间:2021-05-05 14:41:36
标签:python,tcpdump
一、背景
今天有个小需求,要确认客户端有没有往服务端发送udp包,但为了减轻工作量,不想每次到机器上手动执行tcpdump抓包命令。
于是就写了个脚本来释放人力。
二、代码实现
整个脚本我还加了一些其他功能:时间戳、发送端IP提取,数据包分析,数据持久化等。这里都先去掉,仅记录下简单的实时获取tcpdump输出功能。
代码如下:
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# sudo tcpdump -tt -l -nn -c 5 -i enp4s0 udp port 514 or 51414
import subprocess
cmd = ['sudo', 'tcpdump', '-tt', '-l', '-nn', '-c', '5', '-i', 'enp4s0', 'udp', 'port', '514', 'or', '51414']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
while True:
line = proc.stdout.readline()
line = line.strip()
if not line:
print('tcpdump finished...')
break
print(line)
输出如下(实时):
wenyuanblog@localhost:/home/test/script# python tcpdump_udp.py
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), capture size 262144 bytes
1499774951.124178 IP 192.168.10.210.41974 > 192.168.10.251.514: UDP, length 139
1499774953.125664 IP 192.168.10.210.54995 > 192.168.10.251.51414: UDP, length 139
1499774956.128498 IP 192.168.10.210.56748 > 192.168.10.251.514: UDP, length 139
1499774958.129918 IP 192.168.10.210.53883 > 192.168.10.251.51414: UDP, length 139
1499774961.132921 IP 192.168.10.210.58803 > 192.168.10.251.514: UDP, length 139
5 packets captured
6 packets received by filter
0 packets dropped by kernel
tcpdump finished...
以上代码相当于手动执行了 sudo tcpdump -tt -l -nn -c 5 -i enp4s0 udp port 514 or 51414
这条命令。
注意参数-l很重要(行显)。
三、代码实现(更新)
上面的代码能实现tcpdump的功能,但是有一个问题:没有做超时保护。即当程序执行时间过长时kill该进程(这里使用ctrl+c的方式)。
要实现这个功能有很多种方案,例如定时器+多线程等,这里仅演示一种方案,代码如下:
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# sudo tcpdump -tt -l -nn -c 50 -i enp4s0 udp port 514 or 51414
import subprocess
import signal
import time
import os
import re
import json
class CmdServer:
def __init__(self, cmd, timeout=120):
'''
:param cmd: 执行命令(列表形式)
:param timeout: 任务超时时间(seconds,进程运行超过该时间,kill该进程)
:param taskname: 任务名称(根据该任务名称记录命令输出信息)
'''
self.cmd = cmd
self.timeout = timeout
self.base_path = reduce(lambda x, y: os.path.dirname(x), range(1), os.path.abspath(__file__))
self.output_path = os.path.join(self.base_path, 'data.json')
self.udp_flow_list = []
self.begin_time = int(time.time())
# 执行tcpdump任务
def run(self):
if os.path.exists(self.output_path):
with open(self.output_path, 'r') as f:
self.udp_flow_list = json.load(f)
proc = subprocess.Popen(self.cmd, stdout=subprocess.PIPE)
stdout = ''
while proc.poll() == None:
current_time = int(time.time())
if current_time - self.begin_time >= self.timeout:
print('tcpdump timeout...')
proc.send_signal(signal.SIGINT)
stdout = proc.stdout.read()
if proc.poll() is not None and not stdout:
print('tcpdump finished...')
stdout = proc.stdout.read()
stdout_list = stdout.split('\n')
if stdout_list:
self._merge_data(stdout_list)
self._save_data()
# 数据合并(新增/更新)
def _merge_data(self, stdout_list):
for line in stdout_list:
line = line.strip()
if not line:
continue
timestamp = int(float(line.split('IP')[0].strip())) * 1000
# 源
src_ip_port_list = re.findall(r'IP(.+?)>', line)
if not src_ip_port_list:
continue
src_ip_port_str = src_ip_port_list[0].strip()
src_ip = '.'.join(src_ip_port_str.split('.')[0:4])
# 目的
dst_ip_port_list = re.findall(r'>(.+?):', line)
if not dst_ip_port_list:
continue
dst_ip_port_str = dst_ip_port_list[0].strip()
dst_port = dst_ip_port_str.split('.')[-1]
# 新增/更新latest_timestamp
src_item = filter(lambda x: src_ip == x['src_ip'], self.udp_flow_list)
if src_item:
src_item[0]['dst_port'] = dst_port
src_item[0]['latest_timestamp'] = timestamp
else:
self.udp_flow_list.append(dict(
src_ip=src_ip,
dst_port=dst_port,
latest_timestamp=timestamp
))
# 保存数据
def _save_data(self):
# 写入文件
with open(self.output_path, 'w') as f:
json.dump(self.udp_flow_list, f, encoding="utf-8", ensure_ascii=False)
if __name__ == '__main__':
cmd = ['sudo', 'tcpdump', '-tt', '-l', '-nn', '-c', '5', '-i', 'enp4s0', 'udp', 'port', '514', 'or', '51414']
cmd_server = CmdServer(cmd, 10)
cmd_server.run()
四、总结
比较简单,仅仅是记录下。
来源:https://www.wenyuanblog.com/blogs/python-realtime-tcpdump.html
0
投稿
猜你喜欢
- 做为一个编程爱好者,也作为一个小站长(asp之家),中国站长站(www.chinaz.com)我时不时的都会去灌一下。当然发现好的文章我也不
- 版权所有:Copyright 1997 Netscape Communications Corporation原文链接:Object Hie
- 1、闭包的概念请大家跟我理解一下,如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。闭包: 在一个外函数中定
- \\create by ahuinan 2009-6-22 \\up by ahuian 2009-6-23 \\up by ahuinan
- 本文主要介绍了pytorch cnn 识别手写的字实现自建图片数据,分享给大家,具体如下:# library# standard libra
- 其中 offset and fetch 最重要的新特性是 用来 分页,既然要分析 分页,就肯定要和之前的分页方式来比较了,特别是 Row_N
- 先看一下br怎么玩转“清除浮动”了。使用以下代码<br clear="all" />以下是代码效果演示:运行
- 运行平台:WindowsPython版本:Python3.xIDE:Sublime text3一、Scrapy简介Scrapy是一个为了爬取
- 关于段落<p></p>相信大家已经都在自己的工作中开始关注并应用了。因为那真的是非常简单的事,只要你愿意你随时都可以
- 本文实例讲述了Python二叉树定义与遍历方法。分享给大家供大家参考,具体如下:二叉树基本概述:二叉树是有限个元素的几个,如果为空则为空二叉
- 以下是作者在学习Python中django框架时的学习笔记,并把测试的代码做了详细分析,最后还附上了学习心得,值得大家学习。URL配置(UR
- 背景随着Web技术的发展和移动互联网的发展,Hybrid技术已经成为一种前端开发的主流技术方案。那什么是Hybrid App呢?Hybrid
- 随着大数据时代的到来,数据将如同煤电气油一样,成为我们最重要的能源之一,然而这种能源是可以源源不断产生、可再生的。而Python爬虫作为获取
- python中,为了方便字符串的大小写转换,为我们提供了三种方法:title()lower()upper()python title()方法
- PHP mysqli_rollback() 函数关闭自动提交,做一些查询,提交查询,然后回滚当前事务:<?php// 假定数据库用户名
- 我就废话不多说了,大家还是直接看代码吧~#aaa.py#version 3.5import os #这句是没用了,不知道为什么markdow
- Tensor.to(device)和model.to(device)的区别区别所在使用GPU训练的时候,需要将Module对象和Tensor
- 前言网易云音乐这款音乐APP本人比较喜欢,用户量也比较大,而网易云音乐之所以用户众多和它的歌曲评论功能密不可分,很多歌曲的评论非常有意思,其
- 本文实例讲述了Python反转序列的方法。分享给大家供大家参考,具体如下:序列是python中最基本的数据结构,序列中每个元素都有一个跟位置
- ExecuteReader(),ExecuteNonQuery(),ExecuteScalar(),ExecuteXmlReader()之间