如何在Python中纯粹实现tcpflow功能(跟踪TCP流)

4
我正在使用Python编写一个工具(运行平台为Linux),其中一个任务是捕获实时的TCP流,并对每一行应用函数。目前我正在使用
import subprocess
proc = subprocess.Popen(['sudo','tcpflow', '-C', '-i', interface, '-p', 'src', 'host', ip],stdout=subprocess.PIPE)

for line in iter(proc.stdout.readline,''):
    do_something(line)

这个方法非常有效(需要在/etc/sudoers中进行适当的设置),但我希望避免调用外部程序。
到目前为止,我已经研究了以下几种可能性:
  • flowgrep:一个类似我需要的Python工具,但是它内部使用pynids,这个项目已经7年没有更新了,看起来被抛弃了。我的gentoo系统上没有pynids包,并且它附带了一个经过修补的libnids版本,我无法编译它而不进行进一步调整。

  • scapy:这是一个用于Python的数据包操作程序/库,我不确定它是否支持TCP流重组。

  • pypcappylibpcap作为libpcap的封装器。同样,libpcap用于数据包捕获,而我需要的流重组根据this question是不可能的。

在深入了解这些库之前,我想知道是否有人有可用的代码片段(这似乎是一个相当常见的问题)。如果有人能给出正确的建议,我也会非常感激。
谢谢。
2个回答

2

谢谢提供链接。我完全错过了这个更新的pynids版本,我可以编译这个版本。但是第一次测试表明,由于回调函数的工作方式(我需要捕获正在进行的流),只能使用libnids来捕获新建立的TCP连接。好吧,这超出了这个问题的范围... - PiQuer
Pynids现在已经存档。有没有人知道其他实现TCP重组功能的Python库? - Radwa Ahmed

1

作为后续:我放弃了在tcp层面监控流的想法。相反,我用python编写了一个代理,让我想要监视的连接(一个http会话)通过这个代理连接。结果更加稳定,不需要root权限运行。此解决方案依赖于pymiproxy

这将进入一个独立的程序,例如helper_proxy.py

from multiprocessing.connection import Listener
import StringIO
from httplib import HTTPResponse
import threading
import time
from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy

class FakeSocket(StringIO.StringIO):
    def makefile(self, *args, **kw):
        return self

class Interceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):
    conn = None
    def do_request(self, data):
        # do whatever you need to sent data here, I'm only interested in responses
        return data
    def do_response(self, data):
        if Interceptor.conn:   # if the listener is connected, send the response to it
            response = HTTPResponse(FakeSocket(data))
            response.begin()
            Interceptor.conn.send(response.read())
        return data

def main():
    proxy = AsyncMitmProxy()
    proxy.register_interceptor(Interceptor)
    ProxyThread = threading.Thread(target=proxy.serve_forever)
    ProxyThread.daemon=True
    ProxyThread.start()
    print "Proxy started."
    address = ('localhost', 6000)     # family is deduced to be 'AF_INET'
    listener = Listener(address, authkey='some_secret_password')
    while True:
        Interceptor.conn = listener.accept()
        print "Accepted Connection from", listener.last_accepted
        try:
            Interceptor.conn.recv()
        except: time.sleep(1)
        finally:
            Interceptor.conn.close()

if __name__ == '__main__':
    main()

python helper_proxy.py开始。这将在端口8080上创建一个代理,监听http连接,并在端口6000上监听另一个python程序。一旦其他python程序已经连接到该端口,辅助代理将向其发送所有http回复。这样,辅助代理可以继续运行,保持http连接,而监听器可以重新启动进行调试。

以下是监听器的工作原理,例如listener.py

from multiprocessing.connection import Client

def main():
    address = ('localhost', 6000)
    conn = Client(address, authkey='some_secret_password')
    while True:
        print conn.recv()

if __name__ == '__main__':
    main()

这将只打印所有的回复。现在将浏览器指向运行在8080端口上的代理,并建立您想要监视的http连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接