Smills
Smills

Reputation: 736

Intercept UDP packets passing through Linux Bridge with Python/iptables

I am trying to use iptables on a layer 2 bridge running linux to get udp packets that are coming in from an ethernet port and going out on the wlan0 interface, and redirect them to a port on localhost (say, 10000).

For example, if device1 (10.0.0.2) was sending udp packets via ethernet through the bridge (10.0.0.1) which was then passing that packet through to device2 (10.0.0.3) via the wireless interface, how would you redirect those packets to localhost (the bridge) so that a python script running on the bridge can process them?

I've tried iptables -t nat -A PREROUTING -d 10.0.0.3 -p udp --dport 10000 -j REDIRECT --to-ports 10000, but it doesn't seem to work. The packets never get redirected.

I've also tried iptables -t nat -A PREROUTING -d 10.0.0.3 -p udp --dport 10000 -j DNAT --to-destination 127.0.0.1:10000 but no luck there either.

Is there a way to do this with iptables, or with anything else? Otherwise, is there another way of intercepting the packets using Python alone? It's currently simply listening for UDP packets with:

socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket.bind(('', 10000))

Thank you.

Upvotes: 0

Views: 2316

Answers (1)

Yoel
Yoel

Reputation: 9614

The rules you've suggested should work with a minor adjustment. Though it's not documented in iptables' man page, you must specify the protocol as the first argument to match, as follows:

iptables -t nat -A PREROUTING -p udp -d 10.0.0.3 --dport 10000 -j REDIRECT --to-ports 10000
iptables -t nat -A PREROUTING -p udp -d 10.0.0.3 --dport 10000 -j DNAT --to-destination 127.0.0.1:10000

The first rule should work, however according to this answer, the second one wouldn't, requiring you to execute the following command:

sysctl -w net.ipv4.conf.all.route_localnet=1

You may replace all with your specific interface. By default this value is 0, which instructs the kernel to drop external traffic destined to 127.0.0.0/8. This is just for security purposes as such traffic is not normal.

route_localnet - BOOLEAN

Do not consider loopback addresses as martian source or destination while routing. This enables the use of 127/8 for local routing purposes.
default FALSE

Note that this option is only available for kernels above 3.5 (excluded).

Upvotes: 1

Related Questions