English 中文(简体)
Python port forwarding/multiplexing server
原标题:

I would like to make server that listen on UDP port 162 (SNMP trap) and then forwards this traffic to multiple clients. Also important is that the source port & address stays same (address spoofing).

I guess that best tool for this would be Twisted or Scapy or maybe vanilla sockets, only I can t find anything in the documentation for Twisted about source address spoofing/forging.

Any solution for this?

Edit:added bounty, mybe any solution with iptables?

问题回答

I am not comfortable with twisted or scapy, but it s quite straightforward to do this with vanilla python sockets. An extra advantage of that is that it will be even more portable. This code works in my limited tests:

#!/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)

The accepted answer didn t work for me and I end up using A simple TCP redirector in python :

#!/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:
	python SimpleTCPRedirector <host> <port> <remote host> <remote port> 
        print  Example:
	python 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 "
Terminating..."
            terminateAll = True
            break
        ClientThread(clientSocket, targetHost, targetPort).start()

    serverSocket.close()

A different but sort of related solution to forwarding ports, not multiplexing (not answering the specific question but hopefully matching related ones - this is what I was looking for at least):

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





相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签