2015-07-20 85 views
1

爲了測試的目的,我想構建一個服務器,用於偵聽某個接口(例如,eth0)上每個端口(或至少在大多數端口上)的TCP連接。服務器通過SSH訪問eth1,所以沒有問題。 (我不在乎UDP或其他協議)收聽機器上的每個端口

我想做一種特殊的中間盒檢測/分析,因此我需要能夠完全建立連接。有一個HTTP連接將是最好的,因爲「客戶端」可以在瀏覽器中實現爲JS。

我從一個簡單的碼頭服務器開始,但必須認識到,碼頭需要至少在每個端口上產生線程,它正在偵聽。當我想聽幾千個端口時,這會導致問題。 或者有沒有辦法解決這個問題?

我的下一個嘗試是使用iptables

須藤的iptables -t NAT -A PREROUTING -i eth0的-p TCP -j DNAT --to目的地127.0.0.1:8080`

它似乎工作。它允許連接每個端口,並將流量路由到碼頭監聽的本地端口8080。但現在我不知道客戶端使用了哪個端口。因爲碼頭認爲通過端口8080建立了連接。有沒有一種方法可以確定碼頭的真正輸入端口?我可以將端口作爲HTTP請求的一部分發送,但是如果客戶端嘗試聯繫端口1234 ..並且中間框將此端口重定向到端口5678 ..我無法知道使用了哪個端口。

我也試過像socat這樣的userland解決方案。問題比以前更糟糕。因爲現在jetty也將遠程IP視爲127.0.0.1。

或者,還有其他方法可以實現嗎?

哦,順便說一句:我完全控制了機器。所以我可以改變內核或任何需要的東西。現在我使用Ubuntu 14.04 LTS,但是如果解決方案需要其他東西,我可以使用它。

+0

我認爲這可能是堆棧溢出偏離主題。您是否考慮過使用'inetd'將腳本附加到端口? – Sobrique

+0

我也不確定是否應該嘗試超級用戶而不是stackoverflow。但通常stackoverflow吸引更多exper。我還沒有試過'inetd',我會看看它。 – masgo

+0

wireshark是被動的。我需要能夠建立與完整的TCP握手等連接。 – masgo

回答

4

NB:這是一個Python解決方案,因爲我知道Python,但是你可以用任何語言完成同樣的事情,底層C庫getsockopt調用。

如果用REDIRECT規則取代你DNAT規則,然後 使用getsockoptSO_ORIGINAL_DST選項,您可以檢索REDIRECT -ed連接的 原始地址。

考慮下面的代碼:

#!/usr/bin/python 

import socket 
import struct 

SO_ORIGINAL_DST = 80 

s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind(('0.0.0.0', 2000)) 
s.listen(10) 

while True: 
    csock, caddr = s.accept() 
    orig_dst = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16) 

    orig_port = struct.unpack('>H', orig_dst[2:4]) 
    orig_addr = socket.inet_ntoa(orig_dst[4:8]) 

    print 'connection from', caddr 
    print 'connection to', (orig_addr, orig_port) 
    print 

如果我有一個iptables規則是這樣的:

# iptables -t nat -A PREROUTING -p tcp --dport 1500:1600 \ 
    -j REDIRECT --to-port 2000 

雖然上面的Python代碼運行時我連接從另一個 主機到我看到:

connection from ('192.168.1.20', 35790) 
connection to ('192.168.1.75', (1500,)) 

如果我連接到端口1550我看到:

connection from ('192.168.1.20', 42054) 
connection to ('192.168.1.75', (1550,)) 

我認爲這是你問的什麼了。請注意,據我所知,這隻適用於TCP連接;還有其他解決方案(可能涉及iptables目標),它們也可以用於UDP連接。

+0

哦,這很好。現在我只需要找出如何從java訪問getsockopt,或者如何使我的服務器適應類似python或C/C++的東西......但這是可行的。 – masgo

+0

如果您對此答案感到滿意,請考慮點擊答案左側的複選標記。這既是一種說「謝謝」的方式,也是讓人們知道你的問題已經得到解答的一種方式。 – larsks