I want to intercept all UDP traffic leaving tap1. And possibly reply to e.g. DNS-requests. To accomplish this I wrote some python code listening to localhost and use iptables with a rule-set like this:

Chain PREROUTING (policy ACCEPT 2 packets, 333 bytes)
 pkts bytes target     prot opt in     out     source               destination   

    0     0 DIVERT     udp  --  tap1   any     anywhere             anywhere             socket
    0     0 TPROXY     udp  --  tap1   any     anywhere             anywhere             TPROXY redirect mark 0x1/0x1

Chain DIVERT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       udp  --  any    any     anywhere             anywhere             MARK set 0x1
    0     0 ACCEPT     udp  --  any    any     anywhere             anywhere

Policy routing is done with:

ip rule add fwmark 1 lookup 100
ip route add local dev lo table 100

This setup was adapted from the kernel's Documentation/networking/tproxy.txt. This works flawlessly for a TCP socket opened with the IP_TRANSPARENT option.

Unfortunately UDP sockets don't seem to be able to handle connections. For example if I do a ncat -u localhost 1234 the socket will receive data but cannot send anything back. Wireshark will show exactly three packets for:

  1. the incoming ncat packet (to localhost:1234)
  2. the outgoing packet of my software (to :5001)
  3. an ICMP Port unreachable (of course)

For arbitrary ports to work I guess it's not feasable to set up proper (S)NATting rules.

So, what's the necessary setup to make this work for arbitrary incoming ports?

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.