Как достичь функциональности tcpflow (следите за потоком tcp) исключительно внутри Python - PullRequest
2 голосов
/ 06 января 2012

Я пишу инструмент на 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 лет и кажется в значительной степени заброшенным. Там нет пакета Pynids для моей системы Gentoo, и она поставляется с исправленной версией libnids которую я не смог бы собрать без дальнейшей настройки.

  • scapy : это программа / библиотека для работы с пакетами для python, Я не уверен, если поток TCP повторная сборка поддерживается.

  • pypcap или pylibpcap в качестве оболочки для libpcap. Опять же, libpcap для пакета захват, где мне нужна повторная сборка потока, что невозможно в соответствии с на этот вопрос .

Прежде чем я углублюсь в какую-либо из этих библиотек, я хотел бы знать, может быть, кто-то имеет рабочий фрагмент кода (это кажется довольно распространенной проблемой). Я также благодарен, если кто-то может дать совет о правильном пути.

Спасибо

Ответы [ 2 ]

1 голос
/ 20 февраля 2013

Просто как продолжение: я отказался от идеи контролировать поток на слое 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.Это создаст прокси, прослушивающий http-соединения через порт 8080 и прослушивающий другую программу python на порту 6000. Как только другая программа 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-соединение, которое вы хотите отслеживать.

1 голос
/ 06 января 2012

Джон Оберхайде возглавил усилия по поддержанию пинидов, что довольно актуально на: http://jon.oberheide.org/pynids/

Таким образом, это может позволить вам продолжить изучение flowgrep.Сам Pynids довольно элегантно обрабатывает восстановление потока. См. http://monkey.org/~jose/presentations/pysniff04.d/, чтобы найти несколько хороших примеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...