我可以用Python嗅探发送到另一台Linux机器的UDP数据包吗?

2 投票
3 回答
2377 浏览
提问于 2025-04-16 18:50

我在一台Linux机器上,叫做server1,运行了一个Python程序,这个程序可以接收和处理原始的UDP数据包。我想要在另一台Linux机器上,叫做server2,让它也能监听到server1接收到的那些UDP数据包。

有没有什么Python的解决方案,可以让server2监听到发给另一台Linux机器的UDP数据包呢?

3 个回答

1

我之前也遇到过类似的问题,所以写了一个小的Python脚本,用来把收到的UDP数据包转发到多个主机。不过这样做有个缺点,就是你会丢失原始UDP数据包的来源IP地址。

import socket
import sys, time, string

def sendUDP(remotehost,remoteport,UDPSock,data):
    UDPSock.sendto( data, (remotehost,remoteport))

def serverLoop(listenport,remotes):
    # Set up socket
    UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    UDPSock.bind( ("0.0.0.0",listenport) )
    while 1:
        data, addr = UDPSock.recvfrom(1024)
        if not data: pass
        else:
            sys.stdout.write(".") ; sys.stdout.flush()
            # Send udp packet to remotes...
            for remote in remotes:
                if remote[0] == addr: pass
                else: sendUDP(remote[0],remote[1],UDPSock,data)
        time.sleep(0.001)

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print "%s listenport remotehost1:port1 remotehostN:portN ..." % sys.argv[0]
        sys.exit(-1)
    listenport = int(sys.argv[1])
    print "Local foward port %d" % listenport
    remotes = []
    for pair in sys.argv[2:]:
        host,port = string.split(pair,":")
        remotes.append( (host,int(port)) )
        print "Adding remote forward %s:%s" % (host,port)
    print "Starting serverloop"
    serverLoop(listenport,remotes)
4

这跟Python没有关系,而是跟你的网络结构有关。如果服务器1和服务器2是通过一个交换机连接的(很可能是这样),那么你就不能做到这一点,因为通过路由器传输的数据包只会发送到请求的IP地址。

所以首先,告诉我们你的网络结构是怎样的。服务器1和服务器2在哪里?它们是怎么互相联系的?

解决你的问题不依赖于你的操作系统,也不依赖于使用的编程语言。不过,你在问题中标记了“linux”,所以我想你对这个操作系统应该有一些了解。如果是这样的话,如果服务器1和服务器2是通过同一个路由器连接到局域网的,你可以考虑在你的路由器上安装linux(可以看看openwrt),然后直接在路由器上进行数据捕获和其他操作。

3

如果你想让多台机器一起处理相同的数据,最好的办法是使用多播(前提是你能控制发送方和基础设施)。

如果不行的话,你可以使用这个链接里的工具,通过Python来捕获数据包。不过,你还是需要设置好网络环境,把数据包传送到你想要监控的那台机器上。可以通过iptables(如果是Linux机器的话)或者在交换机上设置镜像端口等方式来实现。

补充:

如果你想在不同的机器上处理数据(你觉得一台机器处理不过来),我建议你用一台Linux机器来接收数据,然后通过iptables把数据发送到其他多台机器上。也可以在同一台机器上发送到不同的端口。这是可行的,因为使用的是UDP协议。如果你想在同一台机器上处理数据,我会建议用一个主进程来创建多个子进程,并通过连接的管道(PIPE)进行通信,绑定UDP端口,并把数据复制到每个子进程的管道中;可能还需要进行一些输入验证。

撰写回答