繁体   English   中英

Python端口转发/多路复用服务器

[英]Python port forwarding/multiplexing server

我想让服务器侦听 UDP 端口 162(SNMP 陷阱),然后将此流量转发给多个客户端。 同样重要的是源端口和地址保持不变(地址欺骗)。

我想最好的工具是TwistedScapy或者可能是香草套接字,只是我在 Twisted 的文档中找不到关于源地址欺骗/伪造的任何内容。

有什么解决办法吗?

编辑:增加了赏金,我的 iptables 有什么解决方案吗?

我对 Twisted 或 scapy 不满意,但是使用 vanilla python 套接字执行此操作非常简单。 这样做的另一个好处是它会更加便携。 此代码适用于我的有限测试:

#!/usr/bin/python
from socket import *
bufsize = 1024 # Modify to suit your needs
targetHost = "somehost.yourdomain.com"
listenPort = 1123

def forward(data, port):
    print "Forwarding: '%s' from port %s" % (data, port)
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(("localhost", port)) # Bind to the port data came in on
    sock.sendto(data, (targetHost, listenPort))

def listen(host, port):
    listenSocket = socket(AF_INET, SOCK_DGRAM)
    listenSocket.bind((host, port))
    while True:
        data, addr = listenSocket.recvfrom(bufsize)
        forward(data, addr[1]) # data and port

listen("localhost", listenPort)

接受的答案对我不起作用,我最终在 python 中使用了一个简单的 TCP 重定向器

#!/usr/bin/env python

import socket
import threading
import select
import sys

terminateAll = False

class ClientThread(threading.Thread):
    def __init__(self, clientSocket, targetHost, targetPort):
        threading.Thread.__init__(self)
        self.__clientSocket = clientSocket
        self.__targetHost = targetHost
        self.__targetPort = targetPort

    def run(self):
        print "Client Thread started"

        self.__clientSocket.setblocking(0)

        targetHostSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        targetHostSocket.connect((self.__targetHost, self.__targetPort))
        targetHostSocket.setblocking(0)

        clientData = ""
        targetHostData = ""
        terminate = False
        while not terminate and not terminateAll:
            inputs = [self.__clientSocket, targetHostSocket]
            outputs = []

            if len(clientData) > 0:
                outputs.append(self.__clientSocket)

            if len(targetHostData) > 0:
                outputs.append(targetHostSocket)

            try:
                inputsReady, outputsReady, errorsReady = select.select(inputs, outputs, [], 1.0)
            except Exception, e:
                print e
                break

            for inp in inputsReady:
                if inp == self.__clientSocket:
                    try:
                        data = self.__clientSocket.recv(4096)
                    except Exception, e:
                        print e

                    if data != None:
                        if len(data) > 0:
                            targetHostData += data
                        else:
                            terminate = True
                elif inp == targetHostSocket:
                    try:
                        data = targetHostSocket.recv(4096)
                    except Exception, e:
                        print e

                    if data != None:
                        if len(data) > 0:
                            clientData += data
                        else:
                            terminate = True

            for out in outputsReady:
                if out == self.__clientSocket and len(clientData) > 0:
                    bytesWritten = self.__clientSocket.send(clientData)
                    if bytesWritten > 0:
                        clientData = clientData[bytesWritten:]
                elif out == targetHostSocket and len(targetHostData) > 0:
                    bytesWritten = targetHostSocket.send(targetHostData)
                    if bytesWritten > 0:
                        targetHostData = targetHostData[bytesWritten:]

        self.__clientSocket.close()
        targetHostSocket.close()
        print "ClienThread terminating"

if __name__ == '__main__':
    if len(sys.argv) != 5:
        print 'Usage:\n\tpython SimpleTCPRedirector <host> <port> <remote host> <remote port>'
        print 'Example:\n\tpython SimpleTCPRedirector localhost 8080 www.google.com 80'
        sys.exit(0)     

    localHost = sys.argv[1]
    localPort = int(sys.argv[2])
    targetHost = sys.argv[3]
    targetPort = int(sys.argv[4])

    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serverSocket.bind((localHost, localPort))
    serverSocket.listen(5)
    print "Waiting for client..."
    while True:
        try:
            clientSocket, address = serverSocket.accept()
        except KeyboardInterrupt:
            print "\nTerminating..."
            terminateAll = True
            break
        ClientThread(clientSocket, targetHost, targetPort).start()

    serverSocket.close()

转发端口的一种不同但相关的解决方案,而不是多路复用(不回答特定问题,但希望匹配相关问题 - 这至少是我正在寻找的):

http://www.linux-support.com/cms/forward-network-connections-with-python/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM