2012-05-31 33 views
10

我正在尋找一個工具來記錄和重播TCP流的一側進行測試。 我看到記錄整個TCP流(包括服務器和客戶端)用於測試防火牆等的工具,但我在尋找的是一個工具,它只記錄客戶端提交的流量(帶有時間信息),然後重新提交它到服務器進行測試。tcp流重放工具

回答

12

由於TCP處理重傳的方式,序號,SACK和窗口這可能是一個比你想像的更困難的任務。

通常人們使用tcpreplay進行數據包重放;然而,它doesn't support synchronizing TCP sequence numbers。既然你需要有一個雙向的TCP流,(這需要序列編號的同步),使用下列選項之一:

  1. 如果這是一個非常交互式客戶/服務器協議,你可以使用scapy去掉流中的TCP內容,解析定時和交互性。接下來使用這些信息,打開一個新的TCP套接字到您的服務器,並將這些數據反序列化到新的TCP套接字中。如果遇到TCP重傳和窗口動態變化,用scapy分析原始流可能會非常棘手。將字節寫入新的TCP套接字不需要自己處理序列號......操作系統會處理這個問題。

  2. 如果這是一個簡單的流,你可以沒有時間做(或要插入定時信息手動),你可以使用Wireshark獲取某個TCP蒸汽的原始字節,而不必擔心與scapy解析。在獲得原始字節後,將這些字節寫入新的TCP套接字(根據需要考慮交互性)。將字節寫入新的TCP套接字不需要自己處理序列號......操作系統會處理這個問題。

  3. 如果您的流是純文本(而不是html或xml)命令(如telnet會話),類似Expect的解決方案可能比上述解析更容易。在這個解決方案中,你不會直接從你的代碼打開一個TCP套接字,使用期望的spawn telnet(或其他)會話並用send/expect重放文本命令。您期望的庫/底層操作系統會處理seq編號。

  4. 如果您正在測試Web服務,我懷疑模擬真實Web客戶端點擊鏈接SeleniumSplinter會容易得多。您的http庫/底層操作系統將處理新流中的seq編號。

+0

謝謝。我認爲這並不比我想象的更難,我正在尋找一些相當簡單的東西,忽略了序列號等低層次的東西 - 只保留了時間的數據有效載荷。例如,我不在乎數據到達相同數量的數據包,相同的序列等。 –

+0

我認爲你也許誤解了我的問題。我只對流的一面感興趣。有問題的服務正在處理由物理設備生成的數據流。我不關心TCP的內部工作,我只關心我得到這個......「一堆」?的數據,然後是13秒,而不是另一堆。 Selenium是一個完美的解決方案,除了協議不是基於Web的,它只是一個連續的數據流。 –

+0

我在上面解釋了區分解析原始流和寫入新流...希望這可以清楚地表明,在重構數據的寫入操作期間,根本不需要處理TCP序列號。 –

2

看一看WirePlay code.google.com/p/wireplaygithub.com/abhisek/wireplay它承諾根據需要來重放所捕獲的TCP會話的客戶端或服務器端與所有的SYN/ACK的序列號的修改。

我不知道是否有任何二進制版本可用,您需要自己編譯它。

注意我還沒有試過這個,但我正在研究它。

2

是的,實現這樣的工具是一項艱鉅的任務。 兩年前我開始實施這種工具,現在工具已經成熟了。 嘗試一下,也許你會發現它是你正在尋找的工具。

https://github.com/wangbin579/tcpcopy

2

我想類似的東西,所以我與Scapy的工作了位,併爲我工作的解決方案上來。我的目標是重放捕獲的pcap文件的客戶端部分。我有興趣從服務器獲得響應 - 不一定與時間有關。下面是我的解決方案 - 它絕不是經過測試或完成的,但它做了我想要的事情。希望這是一個如何使用scapy重放TCP流的好例子。

from scapy.all import * 
import sys 

#NOTE - This script assumes that there is only 1 TCP stream in the PCAP file and that 
# you wish to replay the role of the client 

#acks 
ACK = 0x10 
#client closing the connection 
RSTACK = 0x14 

def replay(infile, inface): 
    recvSeqNum = 0 
    first = True 
    targetIp = None 
    #send will put the correct src ip and mac in 
    #this assumes that the client portion of the stream is being replayed 
    for p in rdpcap(infile): 
     if 'IP' in p and 'TCP' in p: 
      ip = p[IP] 
      eth = p[Ether] 
      tcp = p[TCP] 
      if targetIp == None: 
       #figure out the target ip we're interested in 
       targetIp = ip.dst 
       print(targetIp) 
      elif ip.dst != targetIp: 
       # don't replay a packet that isn't to our target ip 
       continue 
      # delete checksums so that they are recalculated 
      del ip.chksum 
      del tcp.chksum 
      if tcp.flags == ACK or tcp.flags == RSTACK: 
       tcp.ack = recvSeqNum+1 
       if first or tcp.flags == RSTACK: 
        # don't expect a response from these 
        sendp(p, iface=inface) 
        first=False 
        continue 

      rcv = srp1(p, iface=inface) 
      recvSeqNum = rcv[TCP].seq 

def printUsage(prog): 
    print("%s <pcapPath> <interface>" % prog) 

if __name__ == "__main__": 
    if 3 != len(sys.argv): 
     printUsage(sys.argv[0]) 
     exit(1) 
    replay(sys.argv[1], sys.argv[2]) 
+0

請注意,您可能需要抑制操作系統的RST響應才能使其工作。在Linux下,你可以使用'iptables -A OUTPUT -p tcp --tcp-flags RST RST -o $ INTERFACE -j DROP' – Nicholas

1

記錄完整TCP客戶端/服務器通信的數據包捕獲。然後,您可以使用tcpliveplay僅將通信的客戶端重放到真實服務器。 tcpliveplay將生成新的序列號,IP地址,MAC地址等,這樣通信就能正常流動。