监听机器上的所有端口

3
为了测试目的,我想建立一个服务器,监听某个接口(例如eth0)上每个端口(或至少大部分端口)的TCP连接。通过SSH访问eth1可以访问该服务器,所以没有问题。(我不关心UDP或其他协议)
我想进行一种特殊的中间件检测/分析,因此我需要能够完全建立连接。具有HTTP连接将是最好的选择,因为“客户端”可以在浏览器中作为JS实现。
我开始使用简单的jetty服务器,但必须意识到jetty需要为其侦听的每个端口生成至少一个线程。当我想要监听几千个端口时,这会导致问题。 或者是否有办法绕过这个问题?
我的下一个尝试是使用iptables:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 127.0.0.1:8080
它似乎有效。它允许连接到每个端口,并将流量路由到jetty侦听的本地端口8080。但现在我不再知道客户端使用的端口。因为jetty认为连接是通过端口8080建立的。 是否有一种方法可以从jetty确定真正的入站端口?我可以将端口作为HTTP请求的一部分发送,但如果客户端尝试联系端口1234 ..并且中间件将其重定向到端口5678 ..我无法知道使用了哪个端口。
我还尝试了像socat这样的用户空间解决方案。问题比以前更糟,因为现在jetty也将远程IP视为127.0.0.1。
或者,有另一种方法可以实现这一点吗?
哦,顺便说一下:我完全控制这台机器。因此,我可以更改内核或需要的任何内容。现在我使用Ubuntu 14.04 LTS,但如果解决方案需要其他东西,我可以采用该方案。

我觉得这个可能不适合在Stack Overflow上讨论。你考虑过使用inetd将脚本附加到端口上吗? - Sobrique
我也不确定是否应该尝试使用superuser而不是stackoverflow。但通常stackoverflow会吸引更多的专家。我还没有尝试过inetd,我会去看一下它。 - masgo
1
Wireshark是被动的。我需要能够通过完整的TCP握手等方式建立连接。 - masgo
1个回答

9

NB:这是一个Python解决方案,因为我了解Python,但是你可以在任何暴露底层C库getsockopt调用的语言中实现相同的功能。

如果您将DNAT规则替换为REDIRECT规则,您可以使用getsockoptSO_ORIGINAL_DST选项来检索REDIRECT连接的原始地址。

考虑以下代码:

#!/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代码正在运行时,我从另一台主机连接到`my_ip_address:1500`,我看到:
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连接;还有其他解决方案(可能涉及TPROXY iptables目标),也可以用于UDP连接。

哦,这很好用。现在我只需要找出如何从Java访问getsockopt。。或者如何将我的服务器适应像Python或C/C++之类的语言..但这是可行的。 - masgo
4
如果您对这个答案感到满意,请考虑点击答案左侧的勾选标记。这既是一种表达“谢谢”的方式,也是让其他人知道您的问题已经得到解答的一种方式。 - larsks

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