Python - Twisted - Simple UDP forwarder. Preserve source IP?

1.3k views Asked by At

I have this basic UDP forward script in Python 3.

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

class Forward(DatagramProtocol):
  def __init__(self, targetTuples):
    print ('in init, targetTuples are ', targetTuples)
    self._targetTuples = targetTuples

  def datagramReceived(self, data, hostAndPort):
    print ('self._targetTuples is ', self._targetTuples)
    for (targetHost, targetPort) in self._targetTuples:

        self.transport.write(data, (targetHost, targetPort))

reactor.listenUDP(5005, Forward([('10.35.203.24', 5000), ('10.35.200.251', 5005)]))  
reactor.run()

So I'm listening on port 5005 UDP, and forwarding those packets to the two IP addresses and different ports.

My question is this -

How do I preserve the original IP address that twisted gets while listening on port 5005?

Source IP (10.1.1.1) --> Twisted (10.30.1.1) --> Multiple Destinations

How can I get Multiple Destinations to see the packet source preserved from the Source IP of (10.1.1.1) ?

1

There are 1 answers

0
Jean-Paul Calderone On BEST ANSWER

When sending UDP datagrams using the BSD socket API (around which, as a first approximation, Twisted is a wrapper), the source address is set to the address the socket is bound to. You can specify the IP of the bind address for a UDP socket in Twisted by passing a value for the interface argument to reactor.listenTCP. However, you are typically restricted in what addresses you are allowed to bind to. Typically the only values allowed are addresses which are assigned to a local network interface. If you are forwarding traffic for 10.1.1.1 but you are on host 10.30.1.1 then you probably cannot set the source address of the UDP packets you send to 10.1.1.1 because that address isn't assigned to a network interface on the host doing the forwarding. If you assigned it to one, routing on your network would probably break in weird ways because then two different hosts would have the same IP address.

This doesn't mean it's not possible to do what you want - but it does mean you probably cannot do it using Twisted's basic UDP support. There are a number of other approaches you could take. For example, you can rewrite source addresses using iptables on Linux. Or you can operate on the IP level and parse and generate full UDP datagrams yourself letting you specify any source address you want (you can do this with Twisted on Linux, too, using twisted.pair.tuntap). There are probably a number of other ways. The best solution for you may depend on which platforms you're targeting and the particular reasons you want to do this kind of forwarding.